diff options
1027 files changed, 102117 insertions, 35197 deletions
diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml index dec3abe52b..aede3f8d49 100644 --- a/.github/workflows/macos_builds.yml +++ b/.github/workflows/macos_builds.yml @@ -3,7 +3,8 @@ on: [push, pull_request] # Global Settings env: - GODOT_BASE_BRANCH: master + # Only used for the cache key. Increment version to force clean build. + GODOT_BASE_BRANCH: master-v2 SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes concurrency: diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index b649a36de3..cb7772e161 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -184,7 +184,7 @@ License: Expat and Bitstream Vera Fonts Copyright Files: ./thirdparty/freetype/ Comment: The FreeType Project -Copyright: 1996-2020, David Turner, Robert Wilhelm, and Werner Lemberg. +Copyright: 1996-2021, David Turner, Robert Wilhelm, and Werner Lemberg. License: FTL Files: ./thirdparty/glslang/ @@ -206,11 +206,11 @@ Copyright: 2010-2020, Google, Inc. 2019-2020, Facebook, Inc. 2012, Mozilla Foundation 2011, Codethink Limited - 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) + 2008, 2010, Nokia Corporation and/or its subsidiary(-ies) 2009, Keith Stribley 2009, Martin Hosken and SIL International 2007, Chris Wilson - 2006, Behdad Esfahbod + 2005-2006, 2020-2021, Behdad Esfahbod 2005, David Turner 2004, 2007-2010, Red Hat, Inc. 1998-2004, David Turner and Werner Lemberg @@ -362,10 +362,6 @@ Comment: Multi-channel signed distance field generator Copyright: 2016, Viktor Chlumsky License: MIT -Files: ./thirdparty/nanosvg/ -Comment: NanoSVG -Copyright: 2013-2014, Mikko Mononen -License: Zlib Files: ./thirdparty/oidn/ Comment: Intel Open Image Denoise @@ -403,6 +399,11 @@ Comment: libSquish Copyright: 2006, Simon Brown License: Expat +Files: ./thirdparty/thorvg/ +Comment: ThorVG +Copyright: 2020-2021, Samsung Electronics Co., Ltd. +License: Expat + Files: ./thirdparty/tinyexr/ Comment: TinyEXR Copyright: 2014-2021, Syoyo Fujita diff --git a/SConstruct b/SConstruct index bdf4937cd7..b8063589c6 100644 --- a/SConstruct +++ b/SConstruct @@ -10,7 +10,48 @@ import os import pickle import sys import time +from types import ModuleType from collections import OrderedDict +from importlib.util import spec_from_file_location, module_from_spec + +# Explicitly resolve the helper modules, this is done to avoid clash with +# modules of the same name that might be randomly added (e.g. someone adding +# an `editor.py` file at the root of the module creates a clash with the editor +# folder when doing `import editor.template_builder`) + + +def _helper_module(name, path): + spec = spec_from_file_location(name, path) + module = module_from_spec(spec) + spec.loader.exec_module(module) + sys.modules[name] = module + # Ensure the module's parents are in loaded to avoid loading the wrong parent + # when doing "import foo.bar" while only "foo.bar" as declared as helper module + child_module = module + parent_name = name + while True: + try: + parent_name, child_name = parent_name.rsplit(".", 1) + except ValueError: + break + try: + parent_module = sys.modules[parent_name] + except KeyError: + parent_module = ModuleType(parent_name) + sys.modules[parent_name] = parent_module + setattr(parent_module, child_name, child_module) + + +_helper_module("gles3_builders", "gles3_builders.py") +_helper_module("glsl_builders", "glsl_builders.py") +_helper_module("methods", "methods.py") +_helper_module("platform_methods", "platform_methods.py") +_helper_module("version", "version.py") +_helper_module("core.core_builders", "core/core_builders.py") +_helper_module("editor.editor_builders", "editor/editor_builders.py") +_helper_module("editor.template_builders", "editor/template_builders.py") +_helper_module("main.main_builders", "main/main_builders.py") +_helper_module("modules.modules_builders", "modules/modules_builders.py") # Local import methods @@ -576,7 +617,8 @@ if selected_platform in platform_list: if env["target"] == "release": if env["tools"]: - print("Error: The editor can only be built with `target=debug` or `target=release_debug`.") + print("ERROR: The editor can only be built with `target=debug` or `target=release_debug`.") + print(" Use `tools=no target=release` to build a release export template.") Exit(255) suffix += ".opt" env.Append(CPPDEFINES=["NDEBUG"]) diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 1891ea7e3a..ef28f43f05 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -698,10 +698,7 @@ Variant Geometry2D::line_intersects_line(const Vector2 &p_from_a, const Vector2 Vector<Vector2> Geometry2D::get_closest_points_between_segments(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2) { Vector2 r1, r2; ::Geometry2D::get_closest_points_between_segments(p1, q1, p2, q2, r1, r2); - Vector<Vector2> r; - r.resize(2); - r.set(0, r1); - r.set(1, r2); + Vector<Vector2> r = { r1, r2 }; return r; } @@ -923,10 +920,7 @@ Vector<Plane> Geometry3D::build_capsule_planes(float p_radius, float p_height, i Vector<Vector3> Geometry3D::get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2) { Vector3 r1, r2; ::Geometry3D::get_closest_points_between_segments(p1, p2, q1, q2, r1, r2); - Vector<Vector3> r; - r.resize(2); - r.set(0, r1); - r.set(1, r2); + Vector<Vector3> r = { r1, r2 }; return r; } diff --git a/core/input/input.cpp b/core/input/input.cpp index 26df16792d..fa2f00bf8d 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -916,40 +916,25 @@ void Input::joy_button(int p_device, JoyButton p_button, bool p_pressed) { // no event? } -void Input::joy_axis(int p_device, JoyAxis p_axis, const JoyAxisValue &p_value) { +void Input::joy_axis(int p_device, JoyAxis p_axis, float p_value) { _THREAD_SAFE_METHOD_; ERR_FAIL_INDEX((int)p_axis, (int)JoyAxis::MAX); Joypad &joy = joy_names[p_device]; - if (joy.last_axis[(size_t)p_axis] == p_value.value) { + if (joy.last_axis[(size_t)p_axis] == p_value) { return; } - //when changing direction quickly, insert fake event to release pending inputmap actions - float last = joy.last_axis[(size_t)p_axis]; - if (p_value.min == 0 && (last < 0.25 || last > 0.75) && (last - 0.5) * (p_value.value - 0.5) < 0) { - JoyAxisValue jx; - jx.min = p_value.min; - jx.value = p_value.value < 0.5 ? 0.6 : 0.4; - joy_axis(p_device, p_axis, jx); - } else if (ABS(last) > 0.5 && last * p_value.value <= 0) { - JoyAxisValue jx; - jx.min = p_value.min; - jx.value = last > 0 ? 0.1 : -0.1; - joy_axis(p_device, p_axis, jx); - } - - joy.last_axis[(size_t)p_axis] = p_value.value; - float val = p_value.min == 0 ? -1.0f + 2.0f * p_value.value : p_value.value; + joy.last_axis[(size_t)p_axis] = p_value; if (joy.mapping == -1) { - _axis_event(p_device, p_axis, val); + _axis_event(p_device, p_axis, p_value); return; } - JoyEvent map = _get_mapped_axis_event(map_db[joy.mapping], p_axis, val); + JoyEvent map = _get_mapped_axis_event(map_db[joy.mapping], p_axis, p_value); if (map.type == TYPE_BUTTON) { bool pressed = map.value > 0.5; @@ -989,10 +974,15 @@ void Input::joy_axis(int p_device, JoyAxis p_axis, const JoyAxisValue &p_value) } if (map.type == TYPE_AXIS) { - _axis_event(p_device, (JoyAxis)map.index, map.value); + JoyAxis axis = JoyAxis(map.index); + float value = map.value; + if (axis == JoyAxis::TRIGGER_LEFT || axis == JoyAxis::TRIGGER_RIGHT) { + // Convert to a value between 0.0f and 1.0f. + value = 0.5f + value / 2.0f; + } + _axis_event(p_device, axis, value); return; } - //printf("invalid mapping\n"); } void Input::joy_hat(int p_device, HatMask p_val) { diff --git a/core/input/input.h b/core/input/input.h index 8b1d7d6161..e5ef31ab4f 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -77,11 +77,6 @@ public: JOYPADS_MAX = 16, }; - struct JoyAxisValue { - int min; - float value; - }; - typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event); private: @@ -313,7 +308,7 @@ public: void parse_mapping(String p_mapping); void joy_button(int p_device, JoyButton p_button, bool p_pressed); - void joy_axis(int p_device, JoyAxis p_axis, const JoyAxisValue &p_value); + void joy_axis(int p_device, JoyAxis p_axis, float p_value); void joy_hat(int p_device, HatMask p_val); void add_joy_mapping(String p_mapping, bool p_update_existing = false); diff --git a/core/io/image.h b/core/io/image.h index dffc5a6a5f..29236a55e5 100644 --- a/core/io/image.h +++ b/core/io/image.h @@ -36,8 +36,6 @@ #include "core/math/rect2.h" /** - * @author Juan Linietsky <reduzio@gmail.com> - * * Image storage class. This is used to store an image in user memory, as well as * providing some basic methods for image manipulation. * Images can be loaded from a file, or registered into the Render object as textures. diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index ebe88fcf66..ce2435216b 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -699,8 +699,7 @@ Vector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) { ERR_FAIL_COND_V_MSG(!to_exists, Vector<Vector2>(), vformat("Can't get point path. Point with id: %d doesn't exist.", p_to_id)); if (a == b) { - Vector<Vector2> ret; - ret.push_back(Vector2(a->pos.x, a->pos.y)); + Vector<Vector2> ret = { Vector2(a->pos.x, a->pos.y) }; return ret; } diff --git a/core/math/a_star.h b/core/math/a_star.h index 1839ec7e04..130c202a61 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -37,9 +37,7 @@ #include "core/templates/oa_hash_map.h" /** - A* pathfinding algorithm - - @author Juan Linietsky <reduzio@gmail.com> + A* pathfinding algorithm. */ class AStar : public RefCounted { diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index b968156887..2902ca59b9 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -346,6 +346,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform */ Vector<Plane> planes; + planes.resize(6); const real_t *matrix = (const real_t *)this->matrix; @@ -360,7 +361,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[0] = p_transform.xform(new_plane); ///////--- Far Plane ---/////// new_plane = Plane(matrix[3] - matrix[2], @@ -371,7 +372,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[1] = p_transform.xform(new_plane); ///////--- Left Plane ---/////// new_plane = Plane(matrix[3] + matrix[0], @@ -382,7 +383,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[2] = p_transform.xform(new_plane); ///////--- Top Plane ---/////// new_plane = Plane(matrix[3] - matrix[1], @@ -393,7 +394,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[3] = p_transform.xform(new_plane); ///////--- Right Plane ---/////// new_plane = Plane(matrix[3] - matrix[0], @@ -404,7 +405,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[4] = p_transform.xform(new_plane); ///////--- Bottom Plane ---/////// new_plane = Plane(matrix[3] + matrix[1], @@ -415,7 +416,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[5] = p_transform.xform(new_plane); return planes; } diff --git a/core/math/disjoint_set.h b/core/math/disjoint_set.h index d16c5d3d62..8657dc068e 100644 --- a/core/math/disjoint_set.h +++ b/core/math/disjoint_set.h @@ -34,10 +34,6 @@ #include "core/templates/map.h" #include "core/templates/vector.h" -/** - @author Marios Staikopoulos <marios@staik.net> -*/ - /* This DisjointSet class uses Find with path compression and Union by rank */ template <typename T, class C = Comparator<T>, class AL = DefaultAllocator> class DisjointSet { diff --git a/core/math/geometry_3d.cpp b/core/math/geometry_3d.cpp index e1bce81b6b..98a2c27d93 100644 --- a/core/math/geometry_3d.cpp +++ b/core/math/geometry_3d.cpp @@ -644,14 +644,15 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes Vector3 right = p.normal.cross(ref).normalized(); Vector3 up = p.normal.cross(right).normalized(); - Vector<Vector3> vertices; - Vector3 center = p.center(); + // make a quad clockwise - vertices.push_back(center - up * subplane_size + right * subplane_size); - vertices.push_back(center - up * subplane_size - right * subplane_size); - vertices.push_back(center + up * subplane_size - right * subplane_size); - vertices.push_back(center + up * subplane_size + right * subplane_size); + Vector<Vector3> vertices = { + center - up * subplane_size + right * subplane_size, + center - up * subplane_size - right * subplane_size, + center + up * subplane_size - right * subplane_size, + center + up * subplane_size + right * subplane_size + }; for (int j = 0; j < p_planes.size(); j++) { if (j == i) { @@ -762,14 +763,14 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes } Vector<Plane> Geometry3D::build_box_planes(const Vector3 &p_extents) { - Vector<Plane> planes; - - planes.push_back(Plane(Vector3(1, 0, 0), p_extents.x)); - planes.push_back(Plane(Vector3(-1, 0, 0), p_extents.x)); - planes.push_back(Plane(Vector3(0, 1, 0), p_extents.y)); - planes.push_back(Plane(Vector3(0, -1, 0), p_extents.y)); - planes.push_back(Plane(Vector3(0, 0, 1), p_extents.z)); - planes.push_back(Plane(Vector3(0, 0, -1), p_extents.z)); + Vector<Plane> planes = { + Plane(Vector3(1, 0, 0), p_extents.x), + Plane(Vector3(-1, 0, 0), p_extents.x), + Plane(Vector3(0, 1, 0), p_extents.y), + Plane(Vector3(0, -1, 0), p_extents.y), + Plane(Vector3(0, 0, 1), p_extents.z), + Plane(Vector3(0, 0, -1), p_extents.z) + }; return planes; } diff --git a/core/math/rect2.h b/core/math/rect2.h index 1f14a01103..f34550bef1 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -207,11 +207,6 @@ struct Rect2 { bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; } inline Rect2 grow(real_t p_amount) const { -#ifdef MATH_CHECKS - if (unlikely(size.x < 0 || size.y < 0)) { - ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size."); - } -#endif Rect2 g = *this; g.grow_by(p_amount); return g; @@ -238,11 +233,6 @@ struct Rect2 { } inline Rect2 grow_individual(real_t p_left, real_t p_top, real_t p_right, real_t p_bottom) const { -#ifdef MATH_CHECKS - if (unlikely(size.x < 0 || size.y < 0)) { - ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size."); - } -#endif Rect2 g = *this; g.position.x -= p_left; g.position.y -= p_top; @@ -488,11 +478,6 @@ struct Rect2i { bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; } Rect2i grow(int p_amount) const { -#ifdef MATH_CHECKS - if (unlikely(size.x < 0 || size.y < 0)) { - ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); - } -#endif Rect2i g = *this; g.position.x -= p_amount; g.position.y -= p_amount; @@ -515,11 +500,6 @@ struct Rect2i { } inline Rect2i grow_individual(int p_left, int p_top, int p_right, int p_bottom) const { -#ifdef MATH_CHECKS - if (unlikely(size.x < 0 || size.y < 0)) { - ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); - } -#endif Rect2i g = *this; g.position.x -= p_left; g.position.y -= p_top; diff --git a/core/object/object.h b/core/object/object.h index 4fe2dff19b..602bd3cda1 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -52,10 +52,6 @@ #define VARIANT_ARGPTRS_PASS *argptr[0], *argptr[1], *argptr[2], *argptr[3], *argptr[4], *argptr[5], *argptr[6]], *argptr[7] #define VARIANT_ARGS_FROM_ARRAY(m_arr) m_arr[0], m_arr[1], m_arr[2], m_arr[3], m_arr[4], m_arr[5], m_arr[6], m_arr[7] -/** -@author Juan Linietsky <reduzio@gmail.com> -*/ - enum PropertyHint { PROPERTY_HINT_NONE, ///< no hint provided. PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_lesser][,noslider][,radians][,degrees][,exp][,suffix:<keyword>] range. diff --git a/core/os/pool_allocator.h b/core/os/pool_allocator.h index 25b5061f62..11a252bc54 100644 --- a/core/os/pool_allocator.h +++ b/core/os/pool_allocator.h @@ -34,13 +34,12 @@ #include "core/typedefs.h" /** - @author Juan Linietsky <reduzio@gmail.com> * Generic Pool Allocator. * This is a generic memory pool allocator, with locking, compacting and alignment. (@TODO alignment) * It used as a standard way to manage allocation in a specific region of memory, such as texture memory, * audio sample memory, or just any kind of memory overall. * (@TODO) abstraction should be greater, because in many platforms, you need to manage a nonreachable memory. -*/ + */ enum { POOL_ALLOCATOR_INVALID_ID = -1 ///< default invalid value. use INVALID_ID( id ) to test diff --git a/core/templates/hash_map.h b/core/templates/hash_map.h index 82b3546f9d..fa5677cc70 100644 --- a/core/templates/hash_map.h +++ b/core/templates/hash_map.h @@ -40,7 +40,6 @@ /** * @class HashMap - * @author Juan Linietsky <reduzio@gmail.com> * * Implementation of a standard Hashing HashMap, for quick lookups of Data associated with a Key. * The implementation provides hashers for the default types, if you need a special kind of hasher, provide @@ -48,7 +47,8 @@ * @param TKey Key, search is based on it, needs to be hasheable. It is unique in this container. * @param TData Data, data associated with the key * @param Hasher Hasher object, needs to provide a valid static hash function for TKey - * @param Comparator comparator object, needs to be able to safely compare two TKey values. It needs to ensure that x == x for any items inserted in the map. Bear in mind that nan != nan when implementing an equality check. + * @param Comparator comparator object, needs to be able to safely compare two TKey values. + * It needs to ensure that x == x for any items inserted in the map. Bear in mind that nan != nan when implementing an equality check. * @param MIN_HASH_TABLE_POWER Miminum size of the hash table, as a power of two. You rarely need to change this parameter. * @param RELATIONSHIP Relationship at which the hash table is resized. if amount of elements is RELATIONSHIP * times bigger than the hash table, table is resized to solve this condition. if RELATIONSHIP is zero, table is always MIN_HASH_TABLE_POWER. diff --git a/core/templates/vector.h b/core/templates/vector.h index 4ada3b597a..e53c502f67 100644 --- a/core/templates/vector.h +++ b/core/templates/vector.h @@ -33,7 +33,6 @@ /** * @class Vector - * @author Juan Linietsky * Vector container. Regular Vector Container. Use with care and for smaller arrays when possible. Use Vector for large arrays. */ diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index 3d8199831d..d5551e1e04 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -1113,6 +1113,12 @@ <description> Emitted when the mouse leaves the control's [code]Rect[/code] area, provided its [member mouse_filter] lets the event reach it. [b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a child [Control] node, even if the mouse cursor is still inside the parent's [code]Rect[/code] area. + If you want to check whether the mouse truly left the area, ignoring any top nodes, you can use code like this: + [codeblock] + func _on_mouse_exited(): + if not Rect2(Vector2(), rect_size).has_point(get_local_mouse_position()): + # Not hovering over area. + [/codeblock] </description> </signal> <signal name="resized"> diff --git a/doc/classes/EditorNode3DGizmo.xml b/doc/classes/EditorNode3DGizmo.xml index 60c329935a..6473108866 100644 --- a/doc/classes/EditorNode3DGizmo.xml +++ b/doc/classes/EditorNode3DGizmo.xml @@ -12,11 +12,13 @@ <method name="_commit_handle" qualifiers="virtual"> <return type="void" /> <argument index="0" name="id" type="int" /> - <argument index="1" name="restore" type="Variant" /> - <argument index="2" name="cancel" type="bool" /> + <argument index="1" name="secondary" type="bool" /> + <argument index="2" name="restore" type="Variant" /> + <argument index="3" name="cancel" type="bool" /> <description> Override this method to commit a handle being edited (handles must have been previously added by [method add_handles]). This usually means creating an [UndoRedo] action for the change, using the current handle value as "do" and the [code]restore[/code] argument as "undo". If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] value should be directly set, without any [UndoRedo] action. + The [code]secondary[/code] argument is [code]true[/code] when the committed handle is secondary (see [method add_handles] for more information). </description> </method> <method name="_commit_subgizmos" qualifiers="virtual"> @@ -32,16 +34,19 @@ <method name="_get_handle_name" qualifiers="virtual const"> <return type="String" /> <argument index="0" name="id" type="int" /> + <argument index="1" name="secondary" type="bool" /> <description> - Override this method to return the name of an edited handle (handles must have been previously added by [method add_handles]). - Handles can be named for reference to the user when editing. + Override this method to return the name of an edited handle (handles must have been previously added by [method add_handles]). Handles can be named for reference to the user when editing. + The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method add_handles] for more information). </description> </method> <method name="_get_handle_value" qualifiers="virtual const"> <return type="Variant" /> <argument index="0" name="id" type="int" /> + <argument index="1" name="secondary" type="bool" /> <description> Override this method to return the current value of a handle. This value will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_handle]. + The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method add_handles] for more information). </description> </method> <method name="_get_subgizmo_transform" qualifiers="virtual const"> @@ -54,8 +59,10 @@ <method name="_is_handle_highlighted" qualifiers="virtual const"> <return type="bool" /> <argument index="0" name="id" type="int" /> + <argument index="1" name="secondary" type="bool" /> <description> Override this method to return [code]true[/code] whenever the given handle should be highlighted in the editor. + The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method add_handles] for more information). </description> </method> <method name="_redraw" qualifiers="virtual"> @@ -67,10 +74,12 @@ <method name="_set_handle" qualifiers="virtual"> <return type="void" /> <argument index="0" name="id" type="int" /> - <argument index="1" name="camera" type="Camera3D" /> - <argument index="2" name="point" type="Vector2" /> + <argument index="1" name="secondary" type="bool" /> + <argument index="2" name="camera" type="Camera3D" /> + <argument index="3" name="point" type="Vector2" /> <description> Override this method to update the node properties when the user drags a gizmo handle (previously added with [method add_handles]). The provided [code]point[/code] is the mouse position in screen coordinates and the [code]camera[/code] can be used to convert it to raycasts. + The [code]secondary[/code] argument is [code]true[/code] when the edited handle is secondary (see [method add_handles] for more information). </description> </method> <method name="_set_subgizmo_transform" qualifiers="virtual"> @@ -120,6 +129,7 @@ <argument index="4" name="secondary" type="bool" default="false" /> <description> Adds a list of handles (points) which can be used to edit the properties of the gizmo's Node3D. The [code]ids[/code] argument can be used to specify a custom identifier for each handle, if an empty [code]Array[/code] is passed, the ids will be assigned automatically from the [code]handles[/code] argument order. + The [code]secondary[/code] argument marks the added handles as secondary, meaning they will normally have less selection priority than regular handles. When the user is holding the shift key secondary handles will switch to have higher priority than regular handles. This change in priority can be used to place multiple handles at the same point while still giving the user control on their selection. There are virtual methods which will be called upon editing of these handles. Call this method during [method _redraw]. </description> </method> diff --git a/doc/classes/EditorNode3DGizmoPlugin.xml b/doc/classes/EditorNode3DGizmoPlugin.xml index 3bcd9e7764..aa8237d69f 100644 --- a/doc/classes/EditorNode3DGizmoPlugin.xml +++ b/doc/classes/EditorNode3DGizmoPlugin.xml @@ -21,11 +21,14 @@ <return type="void" /> <argument index="0" name="gizmo" type="EditorNode3DGizmo" /> <argument index="1" name="handle_id" type="int" /> - <argument index="2" name="restore" type="Variant" /> - <argument index="3" name="cancel" type="bool" /> + <argument index="2" name="secondary" type="bool" /> + <argument index="3" name="restore" type="Variant" /> + <argument index="4" name="cancel" type="bool" /> <description> Override this method to commit a handle being edited (handles must have been previously added by [method EditorNode3DGizmo.add_handles] during [method _redraw]). This usually means creating an [UndoRedo] action for the change, using the current handle value as "do" and the [code]restore[/code] argument as "undo". - If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] value should be directly set, without any [UndoRedo] action. Called for this plugin's active gizmos. + If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] value should be directly set, without any [UndoRedo] action. + The [code]secondary[/code] argument is [code]true[/code] when the committed handle is secondary (see [method EditorNode3DGizmo.add_handles] for more information). + Called for this plugin's active gizmos. </description> </method> <method name="_commit_subgizmos" qualifiers="virtual"> @@ -56,16 +59,20 @@ <return type="String" /> <argument index="0" name="gizmo" type="EditorNode3DGizmo" /> <argument index="1" name="handle_id" type="int" /> + <argument index="2" name="secondary" type="bool" /> <description> - Override this method to provide gizmo's handle names. Called for this plugin's active gizmos. + Override this method to provide gizmo's handle names. The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method EditorNode3DGizmo.add_handles] for more information). Called for this plugin's active gizmos. </description> </method> <method name="_get_handle_value" qualifiers="virtual const"> <return type="Variant" /> <argument index="0" name="gizmo" type="EditorNode3DGizmo" /> <argument index="1" name="handle_id" type="int" /> + <argument index="2" name="secondary" type="bool" /> <description> - Override this method to return the current value of a handle. This value will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_handle]. Called for this plugin's active gizmos. + Override this method to return the current value of a handle. This value will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_handle]. + The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method EditorNode3DGizmo.add_handles] for more information). + Called for this plugin's active gizmos. </description> </method> <method name="_get_priority" qualifiers="virtual const"> @@ -94,8 +101,9 @@ <return type="bool" /> <argument index="0" name="gizmo" type="EditorNode3DGizmo" /> <argument index="1" name="handle_id" type="int" /> + <argument index="2" name="secondary" type="bool" /> <description> - Override this method to return [code]true[/code] whenever to given handle should be highlighted in the editor. Called for this plugin's active gizmos. + Override this method to return [code]true[/code] whenever to given handle should be highlighted in the editor. The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method EditorNode3DGizmo.add_handles] for more information). Called for this plugin's active gizmos. </description> </method> <method name="_is_selectable_when_hidden" qualifiers="virtual const"> @@ -115,10 +123,13 @@ <return type="void" /> <argument index="0" name="gizmo" type="EditorNode3DGizmo" /> <argument index="1" name="handle_id" type="int" /> - <argument index="2" name="camera" type="Camera3D" /> - <argument index="3" name="screen_pos" type="Vector2" /> + <argument index="2" name="secondary" type="bool" /> + <argument index="3" name="camera" type="Camera3D" /> + <argument index="4" name="screen_pos" type="Vector2" /> <description> - Override this method to update the node's properties when the user drags a gizmo handle (previously added with [method EditorNode3DGizmo.add_handles]). The provided [code]point[/code] is the mouse position in screen coordinates and the [code]camera[/code] can be used to convert it to raycasts. Called for this plugin's active gizmos. + Override this method to update the node's properties when the user drags a gizmo handle (previously added with [method EditorNode3DGizmo.add_handles]). The provided [code]point[/code] is the mouse position in screen coordinates and the [code]camera[/code] can be used to convert it to raycasts. + The [code]secondary[/code] argument is [code]true[/code] when the edited handle is secondary (see [method EditorNode3DGizmo.add_handles] for more information). + Called for this plugin's active gizmos. </description> </method> <method name="_set_subgizmo_transform" qualifiers="virtual"> diff --git a/doc/classes/FileDialog.xml b/doc/classes/FileDialog.xml index 2b0594902f..396592719d 100644 --- a/doc/classes/FileDialog.xml +++ b/doc/classes/FileDialog.xml @@ -70,7 +70,7 @@ The dialog's open or save mode, which affects the selection behavior. See [enum FileMode]. </member> <member name="filters" type="PackedStringArray" setter="set_filters" getter="get_filters" default="PackedStringArray()"> - The available file type filters. For example, this shows only [code].png[/code] and [code].gd[/code] files: [code]set_filters(PackedStringArray(["*.png ; PNG Images","*.gd ; GDScript Files"]))[/code]. + The available file type filters. For example, this shows only [code].png[/code] and [code].gd[/code] files: [code]set_filters(PackedStringArray(["*.png ; PNG Images","*.gd ; GDScript Files"]))[/code]. Multiple file types can also be specified in a single filter. [code]"*.png, *.jpg, *.jpeg ; Supported Images"[/code] will show both PNG and JPEG files when selected. </member> <member name="mode_overrides_title" type="bool" setter="set_mode_overrides_title" getter="is_mode_overriding_title" default="true"> If [code]true[/code], changing the [code]Mode[/code] property will set the window title accordingly (e.g. setting mode to [constant FILE_MODE_OPEN_FILE] will change the window title to "Open a File"). diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml index 9d16f64f3a..575697f20d 100644 --- a/doc/classes/GraphEdit.xml +++ b/doc/classes/GraphEdit.xml @@ -214,6 +214,9 @@ <member name="minimap_size" type="Vector2" setter="set_minimap_size" getter="get_minimap_size" default="Vector2(240, 160)"> The size of the minimap rectangle. The map itself is based on the size of the grid area and is scaled to fit this rectangle. </member> + <member name="panning_scheme" type="int" setter="set_panning_scheme" getter="get_panning_scheme" enum="GraphEdit.PanningScheme" default="0"> + Defines the control scheme for panning with mouse wheel. + </member> <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" /> <member name="right_disconnects" type="bool" setter="set_right_disconnects" getter="is_right_disconnects_enabled" default="false"> If [code]true[/code], enables disconnection of existing connections in the GraphEdit by dragging the right end. @@ -345,6 +348,14 @@ </description> </signal> </signals> + <constants> + <constant name="SCROLL_ZOOMS" value="0" enum="PanningScheme"> + [kbd]Mouse Wheel[/kbd] will zoom, [kbd]Ctrl + Mouse Wheel[/kbd] will move the view. + </constant> + <constant name="SCROLL_PANS" value="1" enum="PanningScheme"> + [kbd]Mouse Wheel[/kbd] will move the view, [kbd]Ctrl + Mouse Wheel[/kbd] will zoom. + </constant> + </constants> <theme_items> <theme_item name="activity" data_type="color" type="Color" default="Color(1, 1, 1, 1)"> </theme_item> diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml index b376ab5cb0..ff01ad72fd 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -383,7 +383,7 @@ </constants> <theme_items> <theme_item name="caret_color" data_type="color" type="Color" default="Color(0.94, 0.94, 0.94, 1)"> - Color of the [LineEdit]'s caret (text cursor). + Color of the [LineEdit]'s caret (text cursor). This can be set to a fully transparent color to hide the caret entirely. </theme_item> <theme_item name="clear_button_color" data_type="color" type="Color" default="Color(0.88, 0.88, 0.88, 1)"> Color used as default tint for the clear button. @@ -406,6 +406,9 @@ <theme_item name="selection_color" data_type="color" type="Color" default="Color(0.49, 0.49, 0.49, 1)"> Color of the selection rectangle. </theme_item> + <theme_item name="caret_width" data_type="constant" type="int" default="1"> + The caret's width in pixels. Greater values can be used to improve accessibility by ensuring the caret is easily visible, or to ensure consistency with a large font size. + </theme_item> <theme_item name="minimum_character_width" data_type="constant" type="int" default="4"> Minimum horizontal space for the text (not counting the clear button and content margins). This value is measured in count of 'M' characters (i.e. this amount of 'M' characters can be displayed without scrolling). </theme_item> diff --git a/doc/classes/MeshDataTool.xml b/doc/classes/MeshDataTool.xml index 35e4451918..60137ab006 100644 --- a/doc/classes/MeshDataTool.xml +++ b/doc/classes/MeshDataTool.xml @@ -114,7 +114,7 @@ <argument index="1" name="edge" type="int" /> <description> Returns specified edge associated with given face. - Edge argument must 2 or less because a face only has three edges. + Edge argument must be either 0, 1, or 2 because a face only has three edges. </description> </method> <method name="get_face_meta" qualifiers="const"> @@ -137,7 +137,7 @@ <argument index="1" name="vertex" type="int" /> <description> Returns the specified vertex of the given face. - Vertex argument must be 2 or less because faces contain three vertices. + Vertex argument must be either 0, 1, or 2 because faces contain three vertices. </description> </method> <method name="get_format" qualifiers="const"> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index a249786388..181bcccf4b 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -331,9 +331,6 @@ <member name="debug/file_logging/max_log_files" type="int" setter="" getter="" default="5"> Specifies the maximum amount of log files allowed (used for rotation). </member> - <member name="debug/gdscript/completion/autocomplete_setters_and_getters" type="bool" setter="" getter="" default="false"> - If [code]true[/code], displays getters and setters in autocompletion results in the script editor. This setting is meant to be used when porting old projects (Godot 2), as using member variables is the preferred style from Godot 3 onwards. - </member> <member name="debug/gdscript/warnings/assert_always_false" type="bool" setter="" getter="" default="true"> </member> <member name="debug/gdscript/warnings/assert_always_true" type="bool" setter="" getter="" default="true"> @@ -481,8 +478,9 @@ <member name="display/mouse_cursor/tooltip_position_offset" type="Vector2" setter="" getter="" default="Vector2(10, 10)"> Position offset for tooltips, relative to the mouse cursor's hotspot. </member> - <member name="display/window/dpi/allow_hidpi" type="bool" setter="" getter="" default="false"> - If [code]true[/code], allows HiDPI display on Windows, macOS, and the HTML5 platform. This setting has no effect on desktop Linux, as DPI-awareness fallbacks are not supported there. + <member name="display/window/dpi/allow_hidpi" type="bool" setter="" getter="" default="true"> + If [code]true[/code], allows HiDPI display on Windows, macOS, Android, iOS and HTML5. If [code]false[/code], the platform's low-DPI fallback will be used on HiDPI displays, which causes the window to be displayed in a blurry or pixelated manner (and can cause various window management bugs). Therefore, it is recommended to make your project scale to [url=$DOCS_URL/tutorials/viewports/multiple_resolutions.html]multiple resolutions[/url] instead of disabling this setting. + [b]Note:[/b] This setting has no effect on Linux as DPI-awareness fallbacks are not supported there. </member> <member name="display/window/energy_saving/keep_screen_on" type="bool" setter="" getter="" default="true"> If [code]true[/code], keeps the screen on (even in case of inactivity), so the screensaver does not take over. Works on desktop and mobile platforms. diff --git a/doc/classes/Skin.xml b/doc/classes/Skin.xml index d24963a887..572558c3f5 100644 --- a/doc/classes/Skin.xml +++ b/doc/classes/Skin.xml @@ -14,6 +14,13 @@ <description> </description> </method> + <method name="add_named_bind"> + <return type="void" /> + <argument index="0" name="name" type="String" /> + <argument index="1" name="pose" type="Transform3D" /> + <description> + </description> + </method> <method name="clear_binds"> <return type="void" /> <description> diff --git a/doc/classes/SpriteBase3D.xml b/doc/classes/SpriteBase3D.xml index 32abd1caea..48d27ee0c0 100644 --- a/doc/classes/SpriteBase3D.xml +++ b/doc/classes/SpriteBase3D.xml @@ -66,9 +66,6 @@ <member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2(0, 0)"> The texture's drawing offset. </member> - <member name="opacity" type="float" setter="set_opacity" getter="get_opacity" default="1.0"> - The objects' visibility on a scale from [code]0[/code] fully invisible to [code]1[/code] fully visible. - </member> <member name="pixel_size" type="float" setter="set_pixel_size" getter="get_pixel_size" default="0.01"> The size of one pixel's width on the sprite to scale it in 3D. </member> diff --git a/doc/classes/SpriteFrames.xml b/doc/classes/SpriteFrames.xml index 660afb5a89..2d40167d4e 100644 --- a/doc/classes/SpriteFrames.xml +++ b/doc/classes/SpriteFrames.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="SpriteFrames" inherits="Resource" version="4.0"> <brief_description> - Sprite frame library for AnimatedSprite2D. + Sprite frame library for AnimatedSprite2D and AnimatedSprite3D. </brief_description> <description> - Sprite frame library for [AnimatedSprite2D]. Contains frames and animation data for playback. + Sprite frame library for an [AnimatedSprite2D] or [AnimatedSprite3D] node. Contains frames and animation data for playback. [b]Note:[/b] You can associate a set of normal or specular maps by creating additional [SpriteFrames] resources with a [code]_normal[/code] or [code]_specular[/code] suffix. For example, having 3 [SpriteFrames] resources [code]run[/code], [code]run_normal[/code], and [code]run_specular[/code] will make it so the [code]run[/code] animation uses normal and specular maps. </description> <tutorials> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index e120f79236..3197e59248 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -1223,7 +1223,7 @@ [Color] of the text behind the caret when using a block caret. </theme_item> <theme_item name="caret_color" data_type="color" type="Color" default="Color(0.88, 0.88, 0.88, 1)"> - [Color] of the caret. + [Color] of the caret. This can be set to a fully transparent color to hide the caret entirely. </theme_item> <theme_item name="current_line_color" data_type="color" type="Color" default="Color(0.25, 0.25, 0.26, 0.8)"> Background [Color] of the line containing the caret. @@ -1252,6 +1252,9 @@ <theme_item name="word_highlighted_color" data_type="color" type="Color" default="Color(0.8, 0.9, 0.9, 0.15)"> Sets the highlight [Color] of multiple occurrences. [member highlight_all_occurrences] has to be enabled. </theme_item> + <theme_item name="caret_width" data_type="constant" type="int" default="1"> + The caret's width in pixels. Greater values can be used to improve accessibility by ensuring the caret is easily visible, or to ensure consistency with a large font size. If set to [code]0[/code] or lower, the caret width is automatically set to 1 pixel and multiplied by the display scaling factor. + </theme_item> <theme_item name="line_spacing" data_type="constant" type="int" default="4"> Sets the spacing between the lines. </theme_item> diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml index 64989eb98b..2117451281 100644 --- a/doc/classes/TextServer.xml +++ b/doc/classes/TextServer.xml @@ -1051,6 +1051,13 @@ Returns composite character's bounds as offsets from the start of the line. </description> </method> + <method name="shaped_text_get_inferred_direction" qualifiers="const"> + <return type="int" enum="TextServer.Direction" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns direction of the text, inferred by the BiDi algorithm. + </description> + </method> <method name="shaped_text_get_line_breaks" qualifiers="const"> <return type="PackedInt32Array" /> <argument index="0" name="shaped" type="RID" /> diff --git a/doc/classes/TextServerExtension.xml b/doc/classes/TextServerExtension.xml index aa6c93456b..40a1f89395 100644 --- a/doc/classes/TextServerExtension.xml +++ b/doc/classes/TextServerExtension.xml @@ -1061,6 +1061,13 @@ Returns composite character's bounds as offsets from the start of the line. </description> </method> + <method name="_shaped_text_get_inferred_direction" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns direction of the text, inferred by the BiDi algorithm. + </description> + </method> <method name="_shaped_text_get_line_breaks" qualifiers="virtual const"> <return type="PackedInt32Array" /> <argument index="0" name="shaped" type="RID" /> diff --git a/doc/classes/TouchScreenButton.xml b/doc/classes/TouchScreenButton.xml index f1becb6906..67803b92fe 100644 --- a/doc/classes/TouchScreenButton.xml +++ b/doc/classes/TouchScreenButton.xml @@ -25,16 +25,10 @@ <member name="bitmask" type="BitMap" setter="set_bitmask" getter="get_bitmask"> The button's bitmask. </member> - <member name="normal" type="Texture2D" setter="set_texture" getter="get_texture"> - The button's texture for the normal state. - </member> <member name="passby_press" type="bool" setter="set_passby_press" getter="is_passby_press_enabled" default="false"> If [code]true[/code], the [signal pressed] and [signal released] signals are emitted whenever a pressed finger goes in and out of the button, even if the pressure started outside the active area of the button. [b]Note:[/b] This is a "pass-by" (not "bypass") press mode. </member> - <member name="pressed" type="Texture2D" setter="set_texture_pressed" getter="get_texture_pressed"> - The button's texture for the pressed state. - </member> <member name="shape" type="Shape2D" setter="set_shape" getter="get_shape"> The button's shape. </member> @@ -44,6 +38,12 @@ <member name="shape_visible" type="bool" setter="set_shape_visible" getter="is_shape_visible" default="true"> If [code]true[/code], the button's shape is visible in the editor. </member> + <member name="texture_normal" type="Texture2D" setter="set_texture_normal" getter="get_texture_normal"> + The button's texture for the normal state. + </member> + <member name="texture_pressed" type="Texture2D" setter="set_texture_pressed" getter="get_texture_pressed"> + The button's texture for the pressed state. + </member> <member name="visibility_mode" type="int" setter="set_visibility_mode" getter="get_visibility_mode" enum="TouchScreenButton.VisibilityMode" default="0"> The button's visibility mode. See [enum VisibilityMode] for possible values. </member> diff --git a/doc/translations/ar.po b/doc/translations/ar.po index 4ed6776561..caaf1ad7f1 100644 --- a/doc/translations/ar.po +++ b/doc/translations/ar.po @@ -14,12 +14,13 @@ # Alaa alden Aldroubi <alaa.aldroubi@gmail.com>, 2021. # يزن ØÙ…زه <yznhamzeh@gmail.com>, 2021. # HASSAN GAMER - ØØ³Ù† جيمر <gamerhassan55@gmail.com>, 2022. +# Spirit <i8bou3@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-01-03 03:53+0000\n" -"Last-Translator: HASSAN GAMER - ØØ³Ù† جيمر <gamerhassan55@gmail.com>\n" +"PO-Revision-Date: 2022-01-10 13:18+0000\n" +"Last-Translator: Spirit <i8bou3@gmail.com>\n" "Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/" "godot-class-reference/ar/>\n" "Language: ar\n" @@ -71,9 +72,8 @@ msgid "Method Descriptions" msgstr "أوصا٠الدوال" #: doc/tools/make_rst.py -#, fuzzy msgid "Theme Property Descriptions" -msgstr "أوصا٠المÙلكية" +msgstr "أوصا٠خاصية الثمات" #: doc/tools/make_rst.py msgid "Inherits:" @@ -89,15 +89,15 @@ msgstr "" #: doc/tools/make_rst.py msgid "Default" -msgstr "" +msgstr "Ø§ÙØªØ±Ø§Ø¶ÙŠ" #: doc/tools/make_rst.py msgid "Setter" -msgstr "" +msgstr "واضع" #: doc/tools/make_rst.py msgid "value" -msgstr "" +msgstr "قيمة" #: doc/tools/make_rst.py msgid "Getter" @@ -2829,7 +2829,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3823,8 +3828,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9425,15 +9428,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15546,9 +15551,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15564,17 +15568,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15582,8 +15587,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15591,16 +15598,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15959,6 +15970,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم." + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -16445,7 +16489,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22233,111 +22285,247 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم." + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23784,9 +23972,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23843,7 +24036,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25572,6 +25767,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29583,7 +29867,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33479,7 +33763,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33493,7 +33777,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33717,7 +34002,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34706,7 +34991,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34775,9 +35060,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34868,12 +35153,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -34899,13 +35178,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35255,7 +35527,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38408,6 +38680,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40157,6 +40432,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40277,6 +40556,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44744,7 +45027,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45507,6 +45792,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -48105,9 +48402,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51453,6 +51748,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52219,6 +52520,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52925,7 +53236,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53123,7 +53434,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54257,13 +54568,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60726,7 +61037,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61831,7 +62144,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/ca.po b/doc/translations/ca.po index 96ab70929c..3ff232366a 100644 --- a/doc/translations/ca.po +++ b/doc/translations/ca.po @@ -2857,7 +2857,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3851,8 +3856,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9445,15 +9448,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15540,9 +15545,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15558,17 +15562,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15576,8 +15581,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15585,16 +15592,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15954,6 +15965,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16439,7 +16477,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22223,111 +22269,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23772,9 +23953,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23831,7 +24017,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25560,6 +25748,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29565,7 +29841,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33456,7 +33732,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33470,7 +33746,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33694,7 +33971,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34663,7 +34940,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34731,9 +35008,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34825,12 +35102,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34854,13 +35125,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35208,7 +35472,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38352,6 +38616,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40082,6 +40349,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40202,6 +40473,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44660,7 +44935,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45423,6 +45700,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -48022,9 +48311,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51367,6 +51654,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52133,6 +52426,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52834,7 +53137,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53032,7 +53335,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54166,13 +54469,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60624,7 +60927,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61728,7 +62033,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/classes.pot b/doc/translations/classes.pot index 0df1f347d0..a802e3a7ac 100644 --- a/doc/translations/classes.pot +++ b/doc/translations/classes.pot @@ -2737,7 +2737,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3731,8 +3736,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9312,15 +9315,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15387,9 +15392,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15405,17 +15409,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15423,8 +15428,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15432,16 +15439,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15801,6 +15812,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16286,7 +16324,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22044,111 +22090,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23588,9 +23769,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23647,7 +23833,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25367,6 +25555,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29356,7 +29632,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33228,7 +33504,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33242,7 +33518,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33466,7 +33743,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34423,7 +34700,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34491,9 +34768,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34585,12 +34862,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34614,13 +34885,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -34968,7 +35232,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38100,6 +38364,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -39830,6 +40097,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -39947,6 +40218,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44404,7 +44679,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45167,6 +45444,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -47760,9 +48049,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51095,6 +51382,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -51857,6 +52150,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52554,7 +52857,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -52752,7 +53055,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53886,13 +54189,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60335,7 +60638,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61438,7 +61743,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/cs.po b/doc/translations/cs.po index ac77c85061..9179bf7651 100644 --- a/doc/translations/cs.po +++ b/doc/translations/cs.po @@ -3238,7 +3238,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -4232,8 +4237,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9833,15 +9836,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15943,9 +15948,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15958,20 +15962,24 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" +"Vracà [code]true[/code] pokud si jsou [code]a[/code] a [code]b[/code] " +"pÅ™iblÞnÄ› rovny." #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15979,8 +15987,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15988,16 +15998,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -16380,6 +16394,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "Vracà [code]true[/code] pokud [code]s[/code] je nula nebo téměř nula." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "Vracà [code]true[/code] pokud [code]s[/code] je nula nebo téměř nula." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "Vracà [code]true[/code] pokud [code]s[/code] je nula nebo téměř nula." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "Vracà [code]true[/code] pokud [code]s[/code] je nula nebo téměř nula." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "Vracà [code]true[/code] pokud [code]s[/code] je nula nebo téměř nula." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "Vracà [code]true[/code] pokud [code]s[/code] je nula nebo téměř nula." + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -16866,7 +16913,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22661,111 +22716,247 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "Vrátà sinus parametru." + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -24211,9 +24402,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -24270,7 +24466,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25999,6 +26197,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "Vrátà sinus parametru." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -30015,7 +30302,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33912,7 +34199,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33926,7 +34213,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -34150,7 +34438,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -35139,7 +35427,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -35210,9 +35498,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -35303,12 +35591,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -35334,13 +35616,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35690,7 +35965,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38845,6 +39120,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40600,6 +40878,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40720,6 +41002,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -45188,7 +45474,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45951,6 +46239,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -48551,9 +48851,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51899,6 +52197,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52664,6 +52968,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -53371,7 +53685,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53569,7 +53883,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54704,13 +55018,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -61206,7 +61520,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -62310,7 +62626,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/de.po b/doc/translations/de.po index 8b52b03270..6c8d12e11f 100644 --- a/doc/translations/de.po +++ b/doc/translations/de.po @@ -3619,8 +3619,13 @@ msgid "Gamepad button 22." msgstr "Gamepad-Taste 22." #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." -msgstr "Die maximale Anzahl der Tasten des Game-Controllers." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." +msgstr "" #: doc/classes/@GlobalScope.xml msgid "DualShock circle button." @@ -4732,8 +4737,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -11291,15 +11294,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -17565,9 +17570,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -17580,20 +17584,24 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" +"Gibt [code]true[/code] zurück wenn Einstellung welche durch [code]name[/" +"code]angegeben ist, existiert, ansonsten [code]false[/code]." #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -17601,8 +17609,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -17610,16 +17620,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -18006,6 +18020,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "Entfernt die Animation mit dem key [code]name[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "Entfernt die Animation mit dem key [code]name[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "Entfernt die Animation mit dem key [code]name[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "Entfernt die Animation mit dem key [code]name[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "Liefert die Position des Punktes bei Index [code]Punkt[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "Entfernt die Animation mit dem key [code]name[/code]." + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -18495,7 +18542,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -24307,111 +24362,252 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Gets the current branch name defined in the VCS." +msgstr "Legt den aktuell sichtbaren Rahmen der Textur fest." + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "Gibt den Sinus des Parameters zurück." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Remove a remote from the local VCS." +msgstr "Entfernt das Element der Arrays dessen Position übergeben wurde." + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" +"Entfernt den Punkt bei Index [code]Punkt[/code] aus dem Überblendungsbereich." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Pops up an error message in the edior." +msgstr "Wird verwendet, um Eigenschaften im Editor zu gruppieren." + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -25868,9 +26064,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -25927,7 +26128,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -27669,6 +27872,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "Der Name des Audiobusses des Bereichs." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -31716,7 +32008,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -35625,7 +35917,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -35639,7 +35931,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -35863,7 +36156,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -36865,7 +37158,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -36940,9 +37233,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -37035,12 +37328,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -37067,13 +37354,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -37432,7 +37712,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -40594,6 +40874,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -42373,6 +42656,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -42494,6 +42781,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -47052,7 +47343,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -47821,6 +48114,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -50452,9 +50757,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" "AABB besteht aus einer Position, einer Größe und mehreren Hilfsfunktionen. " "Es wird typischerweise für schnelle Überlappungstests verwendet." @@ -53820,6 +54123,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -54589,6 +54898,17 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +#, fuzzy +msgid "Emitted when dragging is started." +msgstr "Wird ausgegeben, wenn eine Vorlage hinzugefügt wird." + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -55305,7 +55625,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -55510,7 +55830,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -56659,13 +56979,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -63240,7 +63560,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" "Tweens sind nützlich für Animationen, bei denen eine numerische Eigenschaft " "über einen Bereich von Werten interpoliert werden muss. Der Name [i]tween[/" @@ -64398,8 +64720,17 @@ msgstr "" "[code]length[/code] begrenzt wird." #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." -msgstr "Gibt das Kreuzprodukt aus diesem Vektor und [code]mit[/code] zurück." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." +msgstr "" #: doc/classes/Vector2.xml #, fuzzy diff --git a/doc/translations/el.po b/doc/translations/el.po index f983a43b79..91be47cf2d 100644 --- a/doc/translations/el.po +++ b/doc/translations/el.po @@ -2750,7 +2750,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3744,8 +3749,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9346,15 +9349,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15467,9 +15472,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15485,17 +15489,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15503,8 +15508,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15512,16 +15519,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15880,6 +15891,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "ΕπιστÏÎφει το ημίτονο της παÏαμÎÏ„Ïου." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "ΕπιστÏÎφει το ημίτονο της παÏαμÎÏ„Ïου." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "ΕπιστÏÎφει το ημίτονο της παÏαμÎÏ„Ïου." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "ΕπιστÏÎφει το ημίτονο της παÏαμÎÏ„Ïου." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "ΕπιστÏÎφει το ημίτονο της παÏαμÎÏ„Ïου." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "ΕπιστÏÎφει το ημίτονο της παÏαμÎÏ„Ïου." + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -16366,7 +16410,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22154,111 +22206,247 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "ΕπιστÏÎφει το ημίτονο της παÏαμÎÏ„Ïου." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23705,9 +23893,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23764,7 +23957,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25493,6 +25688,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "ΕπιστÏÎφει το ημίτονο της παÏαμÎÏ„Ïου." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29504,7 +29788,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33400,7 +33684,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33414,7 +33698,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33638,7 +33923,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34621,7 +34906,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34690,9 +34975,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34783,12 +35068,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -34814,13 +35093,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35170,7 +35442,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38323,6 +38595,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40060,6 +40335,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40180,6 +40459,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44647,7 +44930,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45410,6 +45695,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -48008,9 +48305,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51356,6 +51651,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52122,6 +52423,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52828,7 +53139,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53026,7 +53337,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54160,13 +54471,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60629,7 +60940,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61734,7 +62047,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/es.po b/doc/translations/es.po index 59ace9c817..bec08603ba 100644 --- a/doc/translations/es.po +++ b/doc/translations/es.po @@ -28,12 +28,13 @@ # Manuel Cantón Guillén <manuelcanton8@gmail.com>, 2021. # Rémi Verschelde <akien@godotengine.org>, 2021. # Rémi Verschelde <remi@godotengine.org>, 2021. +# Alfonso V <alfonsov96@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2021-12-16 20:56+0000\n" -"Last-Translator: Rémi Verschelde <remi@godotengine.org>\n" +"PO-Revision-Date: 2022-01-09 14:56+0000\n" +"Last-Translator: Alfonso V <alfonsov96@gmail.com>\n" "Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/" "godot-class-reference/es/>\n" "Language: es\n" @@ -41,7 +42,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.10\n" +"X-Generator: Weblate 4.10.1\n" #: doc/tools/make_rst.py msgid "Description" @@ -90,77 +91,95 @@ msgstr "Descripciones de Propiedades" #: doc/tools/make_rst.py msgid "Inherits:" -msgstr "" +msgstr "Hereda de:" #: doc/tools/make_rst.py msgid "Inherited By:" -msgstr "" +msgstr "Heredado por:" #: doc/tools/make_rst.py msgid "(overrides %s)" -msgstr "" +msgstr "(sobreescribe %s)" #: doc/tools/make_rst.py +#, fuzzy msgid "Default" -msgstr "" +msgstr "Por defecto" #: doc/tools/make_rst.py +#, fuzzy msgid "Setter" -msgstr "" +msgstr "Método Configurador o Setter" #: doc/tools/make_rst.py msgid "value" -msgstr "" +msgstr "valor" #: doc/tools/make_rst.py +#, fuzzy msgid "Getter" -msgstr "" +msgstr "Método de Acceso al Valor o Getter" #: doc/tools/make_rst.py msgid "" "This method should typically be overridden by the user to have any effect." msgstr "" +"TÃpicamente, este método deberÃa ser sobreescrito por el usuario para que " +"tenga algún efecto." #: doc/tools/make_rst.py +#, fuzzy msgid "" "This method has no side effects. It doesn't modify any of the instance's " "member variables." msgstr "" +"Este método no tiene efectos secundarios. No modifica ninguna de las " +"variables miembras de la instancia." #: doc/tools/make_rst.py msgid "" "This method accepts any number of arguments after the ones described here." msgstr "" +"Este método permite agregar cualquier número de argumentos después de los " +"descritos aquÃ." #: doc/tools/make_rst.py +#, fuzzy msgid "This method is used to construct a type." -msgstr "" +msgstr "Este método se utiliza para construir un tipo." #: doc/tools/make_rst.py msgid "" "This method doesn't need an instance to be called, so it can be called " "directly using the class name." msgstr "" +"Este método no necesita una instancia para ser llamado, por lo que puede " +"llamarse directamente utilizando el nombre de la clase." #: doc/tools/make_rst.py +#, fuzzy msgid "" "This method describes a valid operator to use with this type as left-hand " "operand." msgstr "" +"Este método describe un operador tal que el tipo de la instancia que lo " +"llama es considerado como operando izquierdo." #: modules/gdscript/doc_classes/@GDScript.xml +#, fuzzy msgid "Built-in GDScript functions." -msgstr "Funciones GDScript Incorporadas." +msgstr "Funciones GDScript predefinidas." #: modules/gdscript/doc_classes/@GDScript.xml +#, fuzzy msgid "" "List of core built-in GDScript functions. Math functions and other " "utilities. Everything else is provided by objects. (Keywords: builtin, built " "in, global functions.)" msgstr "" -"Lista de funciones primordiales e incorporadas de GDScript. Funciones " -"matemáticas y otras utilidades. Todo lo demás está proporcionado por " -"objetos. (Palabras clave: incorporado, includido, funciones globales.)" +"Lista de funciones primitivas de GDScript. Funciones matemáticas y otras " +"utilidades. Todo lo demás está proporcionado por objetos. (Palabras clave: " +"incorporado, includido, tipo primitivo, funciones globales.)" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -187,6 +206,7 @@ msgstr "" "[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml +#, fuzzy msgid "" "Returns a color according to the standardized [code]name[/code] with " "[code]alpha[/code] ranging from 0 to 1.\n" @@ -230,7 +250,7 @@ msgid "" msgstr "" "Devuelve el arco coseno de [code]s[/code] en radianes. Se usa para obtener " "el ángulo del coseno de [code]s[/code]. [code]s[/code] debe estar entre " -"[code]-1.0[/code] y [code]1.0[/code] (inclusive), en otro caso, [method " +"[code]-1.0[/code] y [code]1.0[/code] (incluyéndolos); en otro caso, [method " "acos] devolverá [constant NAN].\n" "[codeblock]\n" "# c es 0.523599 o 30 grados si se convierte con rad2deg(s)\n" @@ -250,14 +270,15 @@ msgid "" msgstr "" "Devuelve el arcoseno de [code]s[/code] en radianes. Se usa para obtener el " "ángulo del seno de [code]s[/code]. [code]s[/code] debe estar entre " -"[code]-1.0[/code] y [code]1.0[/code] (inclusive), en otro caso, [method " +"[code]-1.0[/code] y [code]1.0[/code] (incluyéndolos); en otro caso, [method " "asin] devolverá [constant NAN].\n" "[codeblock]\n" -"# s es 0.523599 o 30 grados si se convierte conrad2deg(s)\n" +"# s es 0.523599 o 30 grados si se convierte con rad2deg(s)\n" "s = asin(0.5)\n" "[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml +#, fuzzy msgid "" "Asserts that the [code]condition[/code] is [code]true[/code]. If the " "[code]condition[/code] is [code]false[/code], an error is generated. When " @@ -286,8 +307,8 @@ msgstr "" "Afirma que la condición [code]condition[/code] es [code]true[/code]. Si la " "condición [code]condition[/code] es [code]false[/code], se genera un error. " "Cuando se ejecuta desde el editor, el proyecto en ejecución también se " -"pausará hasta que lo reanude. Esto se puede utilizar como una forma más " -"restrictiva de [method push_error] para informar errores a los " +"pausará hasta que el usuario lo reanude. Esto se puede utilizar como una " +"forma más restrictiva de [method push_error] para informar errores a los " "desarrolladores de proyectos o usuarios de complementos.\n" "[b]Nota:[/b] Por razones de rendimiento, el código dentro de [method assert] " "solo se ejecuta en compilaciones de depuración o cuando se ejecuta el " @@ -310,6 +331,7 @@ msgstr "" "[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml +#, fuzzy msgid "" "Returns the arc tangent of [code]s[/code] in radians. Use it to get the " "angle from an angle's tangent in trigonometry: [code]atan(tan(angle)) == " @@ -321,7 +343,7 @@ msgid "" "[/codeblock]" msgstr "" "Devuelve el arco tangente de [code]s[/code] en radianes. Úsalo para obtener " -"el ángulo de la tangente de un ángulo en trigonometrÃa: " +"el ángulo a partir de la tangente de un ángulo en trigonometrÃa: " "[code]atan(tan(angle)) == angle[/code].\n" "El método no puede saber en qué cuadrante el ángulo se encuentra. Vea " "[method atan2] si tienes tanto [code]y[/code] como [code]x[/code]\n" @@ -330,6 +352,7 @@ msgstr "" "[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml +#, fuzzy msgid "" "Returns the arc tangent of [code]y/x[/code] in radians. Use to get the angle " "of tangent [code]y/x[/code]. To compute the value, the method takes into " @@ -339,8 +362,8 @@ msgid "" "a = atan2(0, -1) # a is 3.141593\n" "[/codeblock]" msgstr "" -"Devuelve la arcotangente de [code]y/x[/code] en radianes. Usalo para obtener " -"el angulo de la tangente [code]y/x[/code]. Para obtener el valor, el metodo " +"Devuelve la arcotangente de [code]y/x[/code] en radianes. Úsalo para obtener " +"el ángulo de la tangente [code]y/x[/code]. Para obtener el valor, el método " "tiene en cuenta el signo de ambos argumentos para determinar el cuadrante.\n" "Nota importante: La coordenada Y es la primera, por convención.\n" "[codeblock]\n" @@ -364,14 +387,15 @@ msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml +#, fuzzy msgid "" "Converts a 2D point expressed in the cartesian coordinate system (X and Y " "axis) to the polar coordinate system (a distance from the origin and an " "angle)." msgstr "" "Convierte un punto 2D expresado en el sistema de coordenadas cartesianas " -"(ejes X e Y) en el sistema de coordenadas polares (una distancia del origen " -"y un ángulo)." +"(ejes X e Y) al sistema de coordenadas polares (una distancia desde el " +"origen y un ángulo)." #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -485,7 +509,7 @@ msgstr "Convierte de decibeles a energÃa lineal (audio)." #: modules/gdscript/doc_classes/@GDScript.xml msgid "Deprecated alias for [method step_decimals]." -msgstr "Alias obsoleto del [method step_decimals]." +msgstr "Alias obsoleto para [method step_decimals]." #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -506,6 +530,7 @@ msgstr "" "[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml +#, fuzzy msgid "" "Compares two values by checking their actual contents, recursing into any " "`Array` or `Dictionary` up to its deepest level.\n" @@ -525,6 +550,23 @@ msgid "" "want a true content-aware comparison, you have to use [code]deep_equal[/" "code]." msgstr "" +"Compara dos valores evaluando sus contenidos actuales, recorriendo de forma " +"recursiva todo `Array` o `Dictionary` hasta su mayor profundidad.\n" +"Es comparable con [code]==[/code] en varios aspectos:\n" +"- Para [code]null[/code], [code]int[/code], [code]float[/code], " +"[code]String[/code], [code]Object[/code] y [code]RID[/code], tanto " +"[code]deep_equal[/code] como [code]==[/code] operan de la misma forma.\n" +"- Para [code]Dictionary[/code], [code]==[/code] considera igualdad si, y " +"solo si, ambas variables apuntan a exactamente el mismo [code]Dictionary[/" +"code], sin recursión o verificación de su contenido.\n" +"- Para [code]Array[/code], [code]==[/code] considera igualdad si, y solo si, " +"cada Ãtem en el primer [code]Array[/code] es igual a su contraparte en el " +"segundo [code]Array[/code], según el mismo [code]==[/code]. Esto implica que " +"[code]==[/code] es recursivo para evaluar elementos de tipo [code]Array[/" +"code], pero no para elementos de tipo [code]Dictionary[/code].\n" +"En sÃntesis, siempre que un [code]Dictionary[/code] está potencialmente " +"involucrado, si se quiere una comparación real de contenidos, se debe " +"utilizar [code]deep_equal[/code]." #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -540,12 +582,13 @@ msgstr "" "[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml +#, fuzzy msgid "" "Converts a dictionary (previously created with [method inst2dict]) back to " "an instance. Useful for deserializing." msgstr "" "Convierte un diccionario (que fue creado previamente con [method inst2dict]) " -"de nuevo a una instancia. Es útil para deserializar." +"de nuevo en una instancia. Es útil para deserializar." #: modules/gdscript/doc_classes/@GDScript.xml #, fuzzy @@ -588,6 +631,7 @@ msgstr "" "avanzadas, utilice [Tween] o [AnimationPlayer]." #: modules/gdscript/doc_classes/@GDScript.xml +#, fuzzy msgid "" "The natural exponential function. It raises the mathematical constant [b]e[/" "b] to the power of [code]s[/code] and returns it.\n" @@ -602,7 +646,7 @@ msgstr "" "potencia de [code]s[/code] y la devuelve.\n" "[b]e[/b] tiene un valor aproximado de 2,71828, y puede obtenerse con " "[code]exp(1)[/code].\n" -"Para los exponentes a otras bases se utiliza el método [method pow].\n" +"Para potencias con otras bases se utiliza el método [method pow].\n" "[codeblock]\n" "a = exp(2) # Aproximadamente 7.39\n" "[/codeblock]" @@ -641,12 +685,13 @@ msgid "" "[/codeblock]\n" "For the integer remainder operation, use the % operator." msgstr "" -"Devuelve el resto en punto flotante de [code]a/b[/code], manteniendo el " -"signo de [code]a[/code].\n" +"Devuelve el residuo real de [code]a/b[/code], manteniendo el signo de " +"[code]a[/code].\n" "[codeblock]\n" -"r = fmod(7, 5.5) # r es 1.5\n" +"# residuo es 1.5\n" +"var residuo = fmod(7, 5.5)\n" "[/codeblock]\n" -"Para la operación módulo de números enteros, utilice el operador %." +"Para la operación del resto de los números enteros, utilice el operador %." #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -668,11 +713,11 @@ msgid "" " 1.5 0.0 0.0\n" "[/codeblock]" msgstr "" -"Devuelve el módulo en punto flotante de [code]a/b[/code] que envuelve por " -"igual en positivo y en negativo.\n" +"Devuelve el módulo real de [code]a/b[/code] que envuelve por igual en " +"positivo y en negativo.\n" "[codeblock]\n" "for i in 7:\n" -"var x = 0.5 * i - 1.5\n" +" var x = 0.5 * i - 1.5\n" " print(\"%4.1f %4.1f %4.1f\" % [x, fmod(x, 1.5), fposmod(x, 1.5)])\n" "[/codeblock]\n" "Produce:\n" @@ -812,10 +857,11 @@ msgstr "" "func _ready():\n" " var id = get_instance_id()\n" " var inst = instance_from_id(id)\n" -" print(inst.foo) # Prints bar\n" +" print(inst.foo) # Imprime bar\n" "[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml +#, fuzzy msgid "" "Returns an interpolation or extrapolation factor considering the range " "specified in [code]from[/code] and [code]to[/code], and the interpolated " @@ -836,6 +882,23 @@ msgid "" "[/codeblock]\n" "See also [method lerp] which performs the reverse of this operation." msgstr "" +"Devuelve un factor de interpolación o extrapolación, considerando el rango " +"especificado en [code]from[/code] y [code]to[/code], y el valor interpolado " +"especificado en [code]weight[/code]. El valor devuelto estará entre " +"[code]0.0[/code] y [code]1.0[/code] si [code]weight[/code] está entre " +"[code]from[/code] y [code]to[/code] (incluyéndolos). Si [code]weight[/code] " +"está ubicado fuera de este rango, se devolverá un factor de extrapolación " +"(valor de retorno menor que [code]0.0[/code] o mayor que [code]1.0[/code]).\n" +"[codeblock]\n" +"# La razón de interpolación en la llamada a `lerp()` de más abajo es 0.75.\n" +"var middle = lerp(20, 30, 0.75)\n" +"# `middle` ahora es 27.5.\n" +"# Ahora, suponemos haber olvidado la razón original y queremos obtererla de " +"vuelta.\n" +"var ratio = inverse_lerp(20, 30, 27.5)\n" +"# `ratio` ahora es 0.75.\n" +"[/codeblock]\n" +"Ver también [method lerp], el cual ejecuta la operación inversa a esta." #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -2202,6 +2265,7 @@ msgstr "" "La constante del cÃrculo, la circunferencia de la unidad cÃrculo en radianes." #: modules/gdscript/doc_classes/@GDScript.xml +#, fuzzy msgid "" "Positive floating-point infinity. This is the result of floating-point " "division when the divisor is [code]0.0[/code]. For negative infinity, use " @@ -2214,8 +2278,18 @@ msgid "" "code] will not result in [constant INF] and will result in a run-time error " "instead." msgstr "" +"Infinito como número de punto flotante. Este es el resultado de una división " +"real cuando el divisor es [code]0.0[/code]. Para el infinito negativo, " +"utilizar [code]-INF[/code]. Dividir por [code]-0.0[/code] otorgará como " +"resultado el infinito negativo si el numerador es positivo, de manera que no " +"es lo mismo que dividir por [code]0.0[/code] (a pesar de que [code]0.0 == " +"-0.0[/code] devuelve [code]true[/code]). [b]Nota:[/b] El infinito numérico " +"solo es un concepto para números de punto flotante y no tiene un equivalente " +"para enteros. La división de un entero por [code]0[/code] no resultará en " +"[constant INF] y en su lugar arrojará un error en tiempo de ejecución." #: modules/gdscript/doc_classes/@GDScript.xml +#, fuzzy msgid "" "\"Not a Number\", an invalid floating-point value. [constant NAN] has " "special properties, including that it is not equal to itself ([code]NAN == " @@ -2227,6 +2301,15 @@ msgid "" "[code]0[/code] will not result in [constant NAN] and will result in a run-" "time error instead." msgstr "" +"\"Not a Number\" (\"No es un Número\"), un decimal de valor inválido. " +"[constant NAN] tiene propiedades especiales, incluyendo que no es igual a si " +"mismo([code]NAN==NAN[/code] devuelve [code]false[/code]). Es una salida dada " +"por algunas operaciones inválidas, como dividir un decimal [code]0.0[/code] " +"por [code]0.0[/code].\n" +"[b]Nota:[/b] \"Not a Number\" es solo un concepto con números decimales, y " +"no tiene un equivalente para enteros. Dividiendo un entero por [code]0[/" +"code] no resultará en [constante NAN] y en su lugar arrojará un error en " +"tiempo de ejecución." #: doc/classes/@GlobalScope.xml msgid "Global scope constants and variables." @@ -3641,8 +3724,13 @@ msgid "Gamepad button 22." msgstr "Botón 2 del mando de videojuegos." #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." -msgstr "Representa el máximo número de botones de joystick soportados." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." +msgstr "" #: doc/classes/@GlobalScope.xml msgid "DualShock circle button." @@ -3901,16 +3989,22 @@ msgstr "" "Touch y Windows MR)." #: doc/classes/@GlobalScope.xml +#, fuzzy msgid "" "MIDI note OFF message. See the documentation of [InputEventMIDI] for " "information of how to use MIDI inputs." msgstr "" +"Mensaje de APAGADO en una nota MIDI. Ver la documentación de " +"[InputEventMIDI] para información sobre cómo utilizar inputs MIDI." #: doc/classes/@GlobalScope.xml +#, fuzzy msgid "" "MIDI note ON message. See the documentation of [InputEventMIDI] for " "information of how to use MIDI inputs." msgstr "" +"Mensaje de ENCENDIDO en una nota MIDI. Ver la documentación de " +"[InputEventMIDI] para información sobre cómo utilizar inputs MIDI." #: doc/classes/@GlobalScope.xml msgid "" @@ -3919,35 +4013,55 @@ msgid "" msgstr "" #: doc/classes/@GlobalScope.xml +#, fuzzy msgid "" "MIDI control change message. This message is sent when a controller value " "changes. Controllers include devices such as pedals and levers." msgstr "" +"Mensaje de cambio de control MIDI. Este mensaje se envÃa cuando cambia un " +"valor en el controlador. Los controladores son aparatos como pedales y " +"palancas." #: doc/classes/@GlobalScope.xml +#, fuzzy msgid "" "MIDI program change message. This message sent when the program patch number " "changes." msgstr "" +"Mensaje de cambio de programa MIDI. Este mensaje se envÃa cuando el número " +"de versión del programa cambia." #: doc/classes/@GlobalScope.xml +#, fuzzy msgid "" "MIDI channel pressure message. This message is most often sent by pressing " "down on the key after it \"bottoms out\". This message is different from " "polyphonic after-touch as it indicates the highest pressure across all keys." msgstr "" +"Mensaje de presión en canal MIDI. Este mensaje suele enviarse al presionar " +"una tecla después de que esta alcanza su punto mÃnimo. Este mensaje es " +"diferente al de after-touch polifónico, ya que indica la presión más alta de " +"entre todas las teclas." #: doc/classes/@GlobalScope.xml +#, fuzzy msgid "" "MIDI pitch bend message. This message is sent to indicate a change in the " "pitch bender (wheel or lever, typically)." msgstr "" +"Mensaje de alteración de tono MIDI. Este mensaje se envÃa para indicar un " +"cambio en la herramienta de alteración de tono del instrumento (normalmente " +"una rueda o palanca)." #: doc/classes/@GlobalScope.xml +#, fuzzy msgid "" "MIDI system exclusive message. This has behavior exclusive to the device " "you're receiving input from. Getting this data is not implemented in Godot." msgstr "" +"Mensaje exclusivo del sistema MIDI. Este tiene comportamiento exclusivo para " +"el aparato desde el cual se está recibiendo input. La obtención de estos " +"datos no está implementada en Godot." #: doc/classes/@GlobalScope.xml msgid "" @@ -3956,16 +4070,23 @@ msgid "" msgstr "" #: doc/classes/@GlobalScope.xml +#, fuzzy msgid "" "MIDI song position pointer message. Gives the number of 16th notes since the " "start of the song. Getting this data is not implemented in Godot." msgstr "" +"Mensaje de puntero a posición en canción MIDI. Otorga el número de " +"semicorcheas (o decimosextas) desde el inicio de la canción. La obtención de " +"estos datos no está implementada en Godot." #: doc/classes/@GlobalScope.xml +#, fuzzy msgid "" "MIDI song select message. Specifies which sequence or song is to be played. " "Getting this data is not implemented in Godot." msgstr "" +"Mensaje de selección de canción MIDI. Especifica qué secuencia o canción se " +"reproducirá. La obtención de estos datos no está implementada en Godot." #: doc/classes/@GlobalScope.xml msgid "" @@ -3974,30 +4095,42 @@ msgid "" msgstr "" #: doc/classes/@GlobalScope.xml +#, fuzzy msgid "" "MIDI timing clock message. Sent 24 times per quarter note when " "synchronization is required." msgstr "" +"Mensaje de reloj sincronizador MIDI. Se envÃa 24 veces por nota negra (o " +"cuarta) cuando se requiere sincronización." #: doc/classes/@GlobalScope.xml +#, fuzzy msgid "" "MIDI start message. Start the current sequence playing. This message will be " "followed with Timing Clocks." msgstr "" +"Mensaje de inicio MIDI. Inicia la secuencia actual. El envÃo de este mensaje " +"es seguido de Timing Clocks." #: doc/classes/@GlobalScope.xml +#, fuzzy msgid "MIDI continue message. Continue at the point the sequence was stopped." msgstr "" +"Mensaje de continuación MIDI. Continúa desde el punto en el cual la pista " +"fue previamente detenida." #: doc/classes/@GlobalScope.xml msgid "MIDI stop message. Stop the current sequence." -msgstr "" +msgstr "Mensaje de detención MIDI. Detiene la secuencia actual." #: doc/classes/@GlobalScope.xml +#, fuzzy msgid "" "MIDI active sensing message. This message is intended to be sent repeatedly " "to tell the receiver that a connection is alive." msgstr "" +"Mensaje de percepción activa MIDI. La intención de este mensaje es que se " +"envÃe repetidamente para informar al recibidor que la conexión sigue en pie." #: doc/classes/@GlobalScope.xml msgid "" @@ -4757,8 +4890,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -4802,6 +4933,7 @@ msgstr "" "Devuelve [code]true[/code] si este [AABB] contiene completamente a otro." #: doc/classes/AABB.xml +#, fuzzy msgid "" "Returns a copy of this [AABB] expanded to include a given point.\n" "[b]Example:[/b]\n" @@ -4813,16 +4945,28 @@ msgid "" "var box2 = box.expand(Vector3(0, -1, 2))\n" "[/codeblock]" msgstr "" +"Devuelve una copia de este [AABB] expandido para incluir un punto dado.\n" +"[b]Ejemplo:[/b]\n" +"[codeblock]\n" +"# posición (-3, 2, 0), tamaño (1, 1, 1)\n" +"var box = AABB(Vector3(-3, 2, 0), Vector3(1, 1, 1))\n" +"# posición (-3, -1, 0), tamaño (3, 4, 2), de manera que ajustamos tanto el " +"AABB original como el Vector3(0, -1, 2)\n" +"var box2 = box.expand(Vector3(0, -1, 2))\n" +"[/codeblock]" #: doc/classes/AABB.xml msgid "Returns the volume of the [AABB]." msgstr "Devuelve el volumen del [AABB]." #: doc/classes/AABB.xml +#, fuzzy msgid "" "Returns the center of the [AABB], which is equal to [member position] + " "([member size] / 2)." msgstr "" +"Devuelve el centro del [AABB], el cual es igual a [member position] + " +"([member size] / 2)." #: doc/classes/AABB.xml msgid "Gets the position of the 8 endpoints of the [AABB] in space." @@ -4995,12 +5139,17 @@ msgstr "" "al diálogo y devuelve el botón creado." #: doc/classes/AcceptDialog.xml +#, fuzzy msgid "" "Returns the label used for built-in text.\n" "[b]Warning:[/b] This is a required internal node, removing and freeing it " "may cause a crash. If you wish to hide it or any of its children, use their " "[member CanvasItem.visible] property." msgstr "" +"Devuelve la etiqueta utilizada por un texto integrado.\n" +"[b]Aviso:[/b] Este es un Nodo Interno requerido, removerlo o liberarlo puede " +"resultar en un colapso. Si deseas ocultarlo o cualquiera de sus Hijos, usa " +"la propiedad [member CanvasItem.visible]." #: doc/classes/AcceptDialog.xml msgid "" @@ -12286,15 +12435,19 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "Representa el tamaño del enum [enum FFT_Size]." #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +#, fuzzy +msgid "Audio effect used for recording the sound from an audio bus." msgstr "Efecto de audio usado para grabar el sonido de un micrófono." #: doc/classes/AudioEffectRecord.xml +#, fuzzy msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" "Permite al usuario grabar el sonido desde un micrófono. Establece y obtiene " "el formato en el que se grabará el archivo de audio (8-bit, 16-bit o " @@ -20140,9 +20293,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -20155,20 +20307,24 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" +"Devuelve [code]true[/code] si existe el ajuste especificado por [code]name[/" +"code], [code]false[/code] en caso contrario." #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -20176,8 +20332,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -20185,16 +20343,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -20681,6 +20843,39 @@ msgstr "" "Deje el enfoque. Ningún otro control podrá recibir la entrada del teclado." #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "Elimina la animación con la clave [code]name[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "Elimina la animación con la clave [code]name[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "Elimina la animación con la clave [code]name[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "Elimina la animación con la clave [code]name[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "Devuelve el Ãndice del artÃculo con el [code]id[/code] dado." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "Devuelve el Ãndice del artÃculo con el [code]id[/code] dado." + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -21412,7 +21607,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -29288,22 +29491,25 @@ msgid "" msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" "Interfaz del Sistema de Control de Versiones (VCS) que lee y escribe en el " "VCS local en uso." #: doc/classes/EditorVCSInterface.xml +#, fuzzy msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." msgstr "" "Usado por el editor para mostrar la información extraÃda del VCS en el " "editor. La implementación de esta API está incluida en los addons de VCS, " @@ -29315,150 +29521,244 @@ msgstr "" "proporcionar una experiencia de plug-n-play." #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "Elimina un Autoload [code]name[/code] de la lista." + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." msgstr "" -"Crea un commit de versión si el addon se inicializa, si no, regresa sin " -"hacer nada. Utiliza los archivos que han sido preparados previamente, con el " -"mensaje de confirmación establecido en un valor como el proporcionado en el " -"argumento." + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." +msgstr "Crea una instancia de [code]class[/code]." #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." -msgstr "" -"Devuelve una [Array] de objetos del [Dictionary] que contiene la diferencia " -"desdel el VCS en uso, si se inicializa un addon VCS, si no, devuelve un " -"objeto [Array] vacio. El contenido de la diferencia también consiste en " -"algunas lÃneas contextuales que proporcionan contexto al cambio de lÃnea " -"observado en el archivo.\n" -"Cada objeto [Dictionary] tiene el contenido de la lÃnea diferencia bajo las " -"claves:\n" -"- [code]\"content\"[/code] para almacenar una [String] que contiene el " -"contenido de la lÃnea\n" -"- [code]\"status\"[/code] para almacenar una [String] que contiene [code]\"+" -"\"[/code] en caso de que el contenido sea una adición de lÃnea pero almacena " -"un [code]\"-\"[/code] en caso de eliminación y una cadena vacÃa en caso de " -"que el contenido de la lÃnea no sea ni una adición ni una eliminación.\n" -"- [code]\"new_line_number\"[/code] para almacenar un número entero que " -"contenga el nuevo número de lÃnea del contenido de la lÃnea.\n" -"- [code]\"line_count\"[/code] para almacenar un entero que contenga el " -"número de lÃneas del contenido de la lÃnea.\n" -"- [code]\"old_line_number\"[/code] para almacenar un entero que contiene el " -"número de lÃnea antiguo del contenido de la lÃnea.\n" -"- [code]\"offset\"[/code] para almacenar el offset del cambio de lÃnea desde " -"el primer contenido de lÃnea contextual." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" #: doc/classes/EditorVCSInterface.xml #, fuzzy +msgid "Discards the changes made in file present at [code]file_path[/code]." +msgstr "Guarda la escena como un archivo en [code]path[/code]." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" -msgstr "" -"Devuelve un [Dictionary] que contiene la ruta del cambio de archivo " -"detectado mapeado a un número entero, lo que significa qué tipo de cambio ha " -"experimentado el archivo correspondiente.\n" -"Los siguientes valores enteros se están utilizando para significar que el " -"archivo detectado es:\n" -"- [code]0[/code]: Nuevo en el directorio de trabajo del VCS\n" -"- [code]1[/code]: Modificado\n" -"- [code]2[/code]: Renombrado\n" -"- [code]3[/code]: Borrado\n" -"- [code]4[/code]: Cambiado de tipo" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." +msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." -msgstr "Devuelve el nombre del proyecto del directorio de trabajo del VCS." +#, fuzzy +msgid "Gets the current branch name defined in the VCS." +msgstr "Devuelve la ruta actual que se está viendo en el [FileSystemDock]." #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" -"Devuelve el nombre del VCS si el VCS ha sido inicializado, si no, devuelve " -"una cadena vacÃa." #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" -"Inicializa el addon VCS si no lo ha hecho ya. Usa el valor del argumento " -"como la ruta al directorio de trabajo del proyecto. Crea el commit inicial " -"si es necesario. Devuelve [code]true[/code] si no se produce ningún fallo, " -"si no, devuelve [code]false[/code]." #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" -"Devuelve [code]true[/code] si el addon está listo para responder a las " -"llamadas de la función, si no, devuelve [code]false[/code]." #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" +"Devuelve un [Array] que contiene los Ids de los dispositivos de todos los " +"joypads conectados actualmente." + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "Devuelve el nombre del nodo en [code]idx[/code]." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Remove a branch from the local VCS." +msgstr "Elimina un nodo de la selección." + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Remove a remote from the local VCS." +msgstr "Elimina un nodo de la selección." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." msgstr "" -"Devuelve [code]true[/code] si el addon VCS ha sido inicializado, si no, " -"devuelve [code]false[/code]." #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." msgstr "" -"Apaga el complemento del VCS para permitir que el código de limpieza se " -"ejecute cuando sea necesario. Devuelve [code]true[/code] si no se produce " -"ningún fallo, si no devuelve [code]false[/code]." + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "Añade la cámara [code]feed[/code] al servidor de la cámara." #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." msgstr "" -"Establece el archivo que debe ser confirmado cuando se llama al [method " -"EditorVCSInterface.commit]. El argumento deberÃa contener la ruta absoluta." #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Pops up an error message in the edior." +msgstr "Se utiliza para agrupar las propiedades en el editor." + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "A new file has been added." +msgstr "Emitido cuando se ha añadido una nueva interfaz." + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "A file is encountered from the staged area." +msgstr "Estado: Desconectado del servidor." + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" -"Devuelve al estado sin añadir el archivo que se preparó previamente para ser " -"confirmado, de modo que ya no se confirma cuando se llama al [method " -"EditorVCSInterface.commit]. El argumento debe contener la ruta absoluta." #: doc/classes/EncodedObjectAsID.xml msgid "Holds a reference to an [Object]'s instance ID." @@ -31401,13 +31701,15 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" -"Añade [code]filter[/code] como filtro personalizado; [code]filter[/code] " -"debe tener la forma [code]\"filename.extension ; Description\"[/code]. Por " -"ejemplo, [code]\"*.png ; Imágenes PNG\"[/code]." #: doc/classes/FileDialog.xml msgid "Clear all the added filters in the dialog." @@ -31464,7 +31766,9 @@ msgstr "La ruta de archivo actualmente seleccionada del diálogo de archivo." msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" "Los filtros de tipo de archivo disponibles. Por ejemplo, esto muestra sólo " "los archivos [code].png[/code] y [code].gd[/code]: " @@ -33790,6 +34094,104 @@ msgstr "El [Gradient] que se usará para rellenar la textura." msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "El número de muestras de color que se obtendrán del [Gradient]." +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "Gradient-filled 2D texture." +msgstr "Textura llena de gradientes." + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" +"GradientTexture utiliza un [Gradient] para rellenar los datos de la textura. " +"El gradiente se rellenará de izquierda a derecha usando los colores " +"obtenidos del gradiente. Esto significa que la textura no representa " +"necesariamente una copia exacta del gradiente, sino una interpolación de " +"muestras obtenidas del gradiente a pasos fijos (ver [member width])." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "El [Gradient] que se usará para rellenar la textura." + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "El número de muestras de color que se obtendrán del [Gradient]." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "El número de muestras de color que se obtendrán del [Gradient]." + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -39188,7 +39590,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -44326,9 +44728,10 @@ msgid "Returns the number of faces in this [Mesh]." msgstr "Devuelve el número de caras en esta [Mesh]." #: doc/classes/MeshDataTool.xml +#, fuzzy msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" "Devuelve un borde especÃfico asociado a una cara determinada.\n" "El argumento de borde debe ser 2 o menos porque una cara sólo tiene tres " @@ -44343,9 +44746,11 @@ msgid "Calculates and returns the face normal of the given face." msgstr "Calcula y devuelve la cara normal de la cara dada." #: doc/classes/MeshDataTool.xml +#, fuzzy msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" "Devuelve el vértice especificado de la cara dada.\n" "El argumento del vértice debe ser 2 o menos porque las caras contienen tres " @@ -44615,9 +45020,10 @@ msgid "The [Mesh] that will be drawn by the [MeshInstance2D]." msgstr "La [Mesh] que será dibujada por la [MeshInstance2D]." #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml +#, fuzzy msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -45892,7 +46298,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -45968,9 +46374,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -46067,12 +46473,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -46099,13 +46499,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -46492,7 +46885,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -50973,6 +51366,7 @@ msgstr "" "usados." #: doc/classes/OS.xml +#, fuzzy msgid "" "Execute the file at the given path with the arguments passed as an array of " "strings. Platform path resolution will take place. The resolved file must " @@ -50991,6 +51385,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -53347,6 +53744,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -53482,6 +53883,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -59463,12 +59868,15 @@ msgstr "" "el archivo de configuración)." #: doc/classes/ProjectSettings.xml +#, fuzzy msgid "" "Sets the value of a setting.\n" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" "Establece el valor de un ajuste.\n" "[b]Ejemplo:[/b]\n" @@ -60493,6 +60901,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -63716,9 +64136,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" "[Rect2] consta de una posición, un tamaño y varias funciones de utilidad. Se " "utiliza tÃpicamente para pruebas de superposición rápida.\n" @@ -68144,6 +68562,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -69095,6 +69519,17 @@ msgstr "" "Si [code]true[/code], el deslizador mostrará las marcas de los valores " "mÃnimo y máximo." +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +#, fuzzy +msgid "Emitted when dragging is started." +msgstr "Emitido cuando se inicia el scrolling." + #: doc/classes/SliderJoint.xml #, fuzzy msgid "Slider between two PhysicsBodies in 3D." @@ -70023,9 +70458,10 @@ msgstr "" "con las texturas de base." #: doc/classes/SpatialMaterial.xml +#, fuzzy msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -70290,7 +70726,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -71751,13 +72187,13 @@ msgstr "Representa el tamaño del enum [enum DrawFlags]." #: doc/classes/SpriteFrames.xml #, fuzzy -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "Biblioteca de fotogramas de Sprite para AnimatedSprite2D." #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -80018,7 +80454,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" "Los Tweens son útiles para las animaciones que requieren que una propiedad " "numérica sea interpolada en un rango de valores. El nombre [i]tween[/i] " @@ -81602,8 +82040,17 @@ msgstr "" "[code]length[/code]." #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." -msgstr "Devuelve el producto cruzado de este vector y [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." +msgstr "" #: doc/classes/Vector2.xml #, fuzzy diff --git a/doc/translations/fa.po b/doc/translations/fa.po index 214910a78f..4e18b8c1e3 100644 --- a/doc/translations/fa.po +++ b/doc/translations/fa.po @@ -13,12 +13,13 @@ # MSKF <walkingdeadstudio@outlook.com>, 2020. # ItzMiad44909858f5774b6d <maidggg@gmail.com>, 2020. # ahmad maftoon <ahmadmaftoon.1387@gmail.com>, 2021. +# Seyed Fazel Alavi <fazel8195@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2021-05-14 20:34+0000\n" -"Last-Translator: ahmad maftoon <ahmadmaftoon.1387@gmail.com>\n" +"PO-Revision-Date: 2022-01-09 14:57+0000\n" +"Last-Translator: Seyed Fazel Alavi <fazel8195@gmail.com>\n" "Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/" "godot-class-reference/fa/>\n" "Language: fa\n" @@ -26,7 +27,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.7-dev\n" +"X-Generator: Weblate 4.10.1\n" #: doc/tools/make_rst.py msgid "Description" @@ -34,7 +35,7 @@ msgstr "تعریÙ" #: doc/tools/make_rst.py msgid "Tutorials" -msgstr "آموزش‌ها" +msgstr "آموزش ها" #: doc/tools/make_rst.py msgid "Properties" @@ -42,7 +43,7 @@ msgstr "خصوصیات" #: doc/tools/make_rst.py msgid "Methods" -msgstr "توابع" +msgstr "روش ها" #: doc/tools/make_rst.py msgid "Theme Properties" @@ -50,7 +51,7 @@ msgstr "خصوصیات زمینه" #: doc/tools/make_rst.py msgid "Signals" -msgstr "سیگنال‌ها" +msgstr "سیگنال ها" #: doc/tools/make_rst.py msgid "Enumerations" @@ -3175,7 +3176,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -4169,8 +4175,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9769,15 +9773,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15884,9 +15890,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15902,17 +15907,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15920,8 +15926,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15929,16 +15937,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -16298,6 +16310,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16783,7 +16822,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22567,111 +22614,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -24117,9 +24299,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -24176,7 +24363,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25905,6 +26094,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29913,7 +30190,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33807,7 +34084,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33821,7 +34098,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -34045,7 +34323,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -35022,7 +35300,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -35090,9 +35368,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -35184,12 +35462,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -35213,13 +35485,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35567,7 +35832,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38717,6 +38982,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40461,6 +40729,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40581,6 +40853,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -45041,7 +45317,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45804,6 +46082,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -48406,9 +48696,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51754,6 +52042,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52520,6 +52814,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -53226,7 +53530,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53424,7 +53728,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54558,13 +54862,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -61019,7 +61323,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -62124,7 +62430,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/fi.po b/doc/translations/fi.po index 3719071c3f..717b65f172 100644 --- a/doc/translations/fi.po +++ b/doc/translations/fi.po @@ -2763,7 +2763,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3757,8 +3762,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9358,15 +9361,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15466,9 +15471,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15484,17 +15488,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15502,8 +15507,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15511,16 +15518,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15879,6 +15890,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "Laskee kahden vektorin ristitulon." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "Laskee kahden vektorin ristitulon." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "Laskee kahden vektorin ristitulon." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "Laskee kahden vektorin ristitulon." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "Laskee kahden vektorin ristitulon." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "Laskee kahden vektorin ristitulon." + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -16365,7 +16409,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22153,111 +22205,247 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "Palauttaa parametrin sinin." + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23703,9 +23891,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23762,7 +23955,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25492,6 +25687,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "Palauttaa parametrin sinin." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29508,7 +29792,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33404,7 +33688,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33418,7 +33702,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33642,7 +33927,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34624,7 +34909,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34693,9 +34978,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34786,12 +35071,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -34817,13 +35096,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35173,7 +35445,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38324,6 +38596,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40059,6 +40334,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40179,6 +40458,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44645,7 +44928,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45408,6 +45693,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -48004,9 +48301,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51348,6 +51643,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52114,6 +52415,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52820,7 +53131,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53018,7 +53329,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54153,13 +54464,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60621,7 +60932,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61725,9 +62038,17 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -#, fuzzy -msgid "Returns the cross product of this vector and [code]with[/code]." -msgstr "Laskee kahden vektorin ristitulon." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." +msgstr "" #: doc/classes/Vector2.xml msgid "" diff --git a/doc/translations/fil.po b/doc/translations/fil.po index fbcff01819..71953d6a2e 100644 --- a/doc/translations/fil.po +++ b/doc/translations/fil.po @@ -2744,7 +2744,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3738,8 +3743,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9338,15 +9341,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15453,9 +15458,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15471,17 +15475,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15489,8 +15494,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15498,16 +15505,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15867,6 +15878,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16352,7 +16390,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22136,111 +22182,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23686,9 +23867,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23745,7 +23931,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25474,6 +25662,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29482,7 +29758,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33376,7 +33652,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33390,7 +33666,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33614,7 +33891,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34585,7 +34862,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34653,9 +34930,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34747,12 +35024,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34776,13 +35047,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35130,7 +35394,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38280,6 +38544,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40012,6 +40279,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40132,6 +40403,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44592,7 +44867,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45355,6 +45632,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -47953,9 +48242,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51301,6 +51588,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52067,6 +52360,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52773,7 +53076,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -52971,7 +53274,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54105,13 +54408,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60566,7 +60869,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61671,7 +61976,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/fr.po b/doc/translations/fr.po index b2e5eda16a..c651d2489c 100644 --- a/doc/translations/fr.po +++ b/doc/translations/fr.po @@ -3654,8 +3654,13 @@ msgid "Gamepad button 22." msgstr "Bouton 22 de la manette." #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." -msgstr "Le nombre maximum de boutons supportés pour un contrôleur de jeu." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." +msgstr "" #: doc/classes/@GlobalScope.xml msgid "DualShock circle button." @@ -4767,8 +4772,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -10983,15 +10986,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -17420,9 +17425,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -17435,20 +17439,24 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" +"Retourne [code]true[/code] si le paramètre spécifié par [code]name[/code] " +"existe, [code]false[/code] autrement." #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -17456,8 +17464,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -17465,16 +17475,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -17868,6 +17882,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "Supprime l’animation avec la touche [code]name[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "Supprime l’animation avec la touche [code]name[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "Supprime l’animation avec la touche [code]name[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "Supprime l’animation avec la touche [code]name[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "Retourne la position du point à l'index [code]point[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "Supprime l’animation avec la touche [code]name[/code]." + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -18356,7 +18403,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -24253,122 +24308,258 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" +"Supprime un [code]name[/code] de chargement automatique à partir de la liste." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." +msgstr "Crée une instance de [code]class[/code]." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml #, fuzzy +msgid "Gets the current branch name defined in the VCS." +msgstr "Définit le trame présentement visible de l'animation." + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" -msgstr "" -"Retourne un [Dictionary] contenant le chemin d’accès de la modification de " -"fichier détectée mappée à un entier signifiant quel type de modification le " -"fichier correspondant a connu.\n" -"Les valeurs d’entiers suivantes sont utilisées pour signifier que le fichier " -"détecté est :\n" -"- [code]0[/code] : Nouveau dans le répertoire de travail VCS\n" -"- [code]1[/code] : Modifié\n" -"- [code]2[/code] : Rebaptisé\n" -"- [code]3[/code] : Supprimé\n" -"- [code]4[/code] : Type changé" +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." +msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "" +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "Retourne une représentation [String] de l'évènement." + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "Retourne le nom du nÅ“ud à [code]idx[/code]." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Remove a branch from the local VCS." +msgstr "Supprime un nÅ“ud de la sélection." + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Remove a remote from the local VCS." +msgstr "Supprime un nÅ“ud de la sélection." + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "Ajoute un [Shape2D] au propriétaire de la forme." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Pops up an error message in the edior." +msgstr "Utilisé pour rassembler des propriétés ensemble dans l'éditeur." + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "A new file has been added." +msgstr "Émis lorsqu'une nouvelle interface a été ajoutée." + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "A file is encountered from the staged area." +msgstr "Statut : Déconnecté du serveur." + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -25852,9 +26043,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -25911,7 +26107,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -27687,6 +27885,96 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "Gradient-filled 2D texture." +msgstr "Texture remplie de gradients." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "Texture remplie de gradients." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -31774,7 +32062,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -35767,7 +36055,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -35781,7 +36069,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -36007,7 +36296,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -37014,7 +37303,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -37087,9 +37376,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -37185,12 +37474,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -37216,13 +37499,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -37582,7 +37858,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -40785,6 +41061,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -42568,6 +42847,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -42690,6 +42973,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -47289,7 +47576,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -48055,6 +48344,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -50678,9 +50979,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" "Une AABB est constituée en une position, une taille, et plusieurs fonctions " "utilitaires. Principalement utilisée pour des tests de chevauchement rapides." @@ -54060,6 +54359,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -54837,6 +55142,17 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +#, fuzzy +msgid "Emitted when dragging is started." +msgstr "Émis lorsque le défilement est commencé." + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -55552,7 +55868,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -55751,7 +56067,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -56926,13 +57242,13 @@ msgstr "" #: doc/classes/SpriteFrames.xml #, fuzzy -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "Bibliothèque de cadres Sprite pour AnimatedSprite2D." #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -63675,7 +63991,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -64793,8 +65111,17 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." -msgstr "Calcule le produit vectoriel de deux vecteurs et [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." +msgstr "" #: doc/classes/Vector2.xml msgid "" diff --git a/doc/translations/gl.po b/doc/translations/gl.po index 438057cdb3..244164c299 100644 --- a/doc/translations/gl.po +++ b/doc/translations/gl.po @@ -2745,7 +2745,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3739,8 +3744,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9320,15 +9323,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15395,9 +15400,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15413,17 +15417,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15431,8 +15436,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15440,16 +15447,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15809,6 +15820,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16294,7 +16332,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22052,111 +22098,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23596,9 +23777,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23655,7 +23841,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25375,6 +25563,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29364,7 +29640,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33236,7 +33512,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33250,7 +33526,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33474,7 +33751,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34431,7 +34708,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34499,9 +34776,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34593,12 +34870,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34622,13 +34893,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -34976,7 +35240,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38108,6 +38372,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -39838,6 +40105,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -39955,6 +40226,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44412,7 +44687,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45175,6 +45452,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -47768,9 +48057,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51103,6 +51390,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -51865,6 +52158,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52562,7 +52865,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -52760,7 +53063,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53894,13 +54197,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60343,7 +60646,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61446,7 +61751,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/hi.po b/doc/translations/hi.po index 0979c6c95d..9902e6e4d8 100644 --- a/doc/translations/hi.po +++ b/doc/translations/hi.po @@ -2743,7 +2743,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3737,8 +3742,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9318,15 +9321,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15393,9 +15398,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15411,17 +15415,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15429,8 +15434,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15438,16 +15445,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15807,6 +15818,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16292,7 +16330,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22050,111 +22096,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23594,9 +23775,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23653,7 +23839,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25373,6 +25561,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29362,7 +29638,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33234,7 +33510,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33248,7 +33524,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33472,7 +33749,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34429,7 +34706,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34497,9 +34774,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34591,12 +34868,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34620,13 +34891,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -34974,7 +35238,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38106,6 +38370,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -39836,6 +40103,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -39953,6 +40224,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44410,7 +44685,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45173,6 +45450,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -47766,9 +48055,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51101,6 +51388,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -51863,6 +52156,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52560,7 +52863,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -52758,7 +53061,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53892,13 +54195,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60341,7 +60644,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61444,7 +61749,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/hu.po b/doc/translations/hu.po index 0a786cfcd4..c8ed5c9e02 100644 --- a/doc/translations/hu.po +++ b/doc/translations/hu.po @@ -2761,7 +2761,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3755,8 +3760,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9336,15 +9339,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15411,9 +15416,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15429,17 +15433,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15447,8 +15452,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15456,16 +15463,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15825,6 +15836,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16310,7 +16348,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22068,111 +22114,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23612,9 +23793,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23671,7 +23857,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25391,6 +25579,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29380,7 +29656,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33252,7 +33528,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33266,7 +33542,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33490,7 +33767,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34447,7 +34724,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34515,9 +34792,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34609,12 +34886,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34638,13 +34909,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -34992,7 +35256,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38124,6 +38388,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -39854,6 +40121,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -39971,6 +40242,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44428,7 +44703,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45191,6 +45468,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -47784,9 +48073,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51119,6 +51406,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -51881,6 +52174,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52578,7 +52881,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -52776,7 +53079,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53910,13 +54213,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60359,7 +60662,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61462,7 +61767,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/id.po b/doc/translations/id.po index 4279718983..a65891f84e 100644 --- a/doc/translations/id.po +++ b/doc/translations/id.po @@ -2949,7 +2949,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3943,8 +3948,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9543,15 +9546,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15659,9 +15664,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15677,17 +15681,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15695,8 +15700,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15704,16 +15711,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -16073,6 +16084,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16558,7 +16596,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22342,111 +22388,247 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "Mengembalikan nilai sinus hiperbolik invers dari parameter." + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23893,9 +24075,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23952,7 +24139,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25681,6 +25870,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "Mengembalikan nilai hiperbolik tangen dari parameter." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29689,7 +29967,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33583,7 +33861,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33597,7 +33875,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33821,7 +34100,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34804,7 +35083,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34872,9 +35151,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34966,12 +35245,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34995,13 +35268,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35349,7 +35615,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38500,6 +38766,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40245,6 +40514,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40365,6 +40638,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44828,7 +45105,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45591,6 +45870,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -48189,9 +48480,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51537,6 +51826,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52303,6 +52598,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -53009,7 +53314,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53207,7 +53512,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54341,13 +54646,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60804,7 +61109,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61909,7 +62216,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/is.po b/doc/translations/is.po index 871771e31d..1d1edf8a53 100644 --- a/doc/translations/is.po +++ b/doc/translations/is.po @@ -2744,7 +2744,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3738,8 +3743,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9319,15 +9322,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15394,9 +15399,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15412,17 +15416,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15430,8 +15435,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15439,16 +15446,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15808,6 +15819,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16293,7 +16331,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22051,111 +22097,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23595,9 +23776,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23654,7 +23840,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25374,6 +25562,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29363,7 +29639,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33235,7 +33511,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33249,7 +33525,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33473,7 +33750,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34430,7 +34707,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34498,9 +34775,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34592,12 +34869,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34621,13 +34892,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -34975,7 +35239,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38107,6 +38371,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -39837,6 +40104,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -39954,6 +40225,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44411,7 +44686,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45174,6 +45451,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -47767,9 +48056,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51102,6 +51389,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -51864,6 +52157,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52561,7 +52864,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -52759,7 +53062,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53893,13 +54196,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60342,7 +60645,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61445,7 +61750,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/it.po b/doc/translations/it.po index e32a94b9cd..0ded58b016 100644 --- a/doc/translations/it.po +++ b/doc/translations/it.po @@ -3659,7 +3659,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -4670,8 +4675,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -10300,15 +10303,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -16492,9 +16497,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -16507,20 +16511,24 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" +"Ritorna [code]true[/code] se l'impostazione specificata da [code]name[/code] " +"esiste, [code]false[/code] altrimenti." #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -16528,8 +16536,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -16537,16 +16547,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -16929,6 +16943,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "Calcola il prodotto vettoriale di questo vettore e [code]with[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "Calcola il prodotto vettoriale di questo vettore e [code]with[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "Calcola il prodotto vettoriale di questo vettore e [code]with[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "Calcola il prodotto vettoriale di questo vettore e [code]with[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "Calcola il prodotto vettoriale di questo vettore e [code]with[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "Calcola il prodotto vettoriale di questo vettore e [code]with[/code]." + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -17415,7 +17462,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -23210,111 +23265,247 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "Restituisce il seno del parametro." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -24762,9 +24953,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -24821,7 +25017,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -26558,6 +26756,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "Restituisce il seno del parametro." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -30586,7 +30873,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -34488,7 +34775,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -34502,7 +34789,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -34727,7 +35015,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -35719,7 +36007,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -35791,9 +36079,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -35884,12 +36172,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -35915,13 +36197,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -36275,7 +36550,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -39437,6 +39712,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -41203,6 +41481,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -41323,6 +41605,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -45793,7 +46079,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -46556,6 +46844,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -49160,9 +49460,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -52512,6 +52810,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -53280,6 +53584,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -53987,7 +54301,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54186,7 +54500,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -55324,13 +55638,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -61832,7 +62146,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -62955,8 +63271,17 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." -msgstr "Calcola il prodotto vettoriale di questo vettore e [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." +msgstr "" #: doc/classes/Vector2.xml msgid "" diff --git a/doc/translations/ja.po b/doc/translations/ja.po index bf6d51175e..4c8cf54ae5 100644 --- a/doc/translations/ja.po +++ b/doc/translations/ja.po @@ -3559,8 +3559,13 @@ msgid "Gamepad button 22." msgstr "ゲームパッド ボタン2。" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." -msgstr "サãƒãƒ¼ãƒˆã•れるジョイスティック ãƒœã‚¿ãƒ³ã®æœ€å¤§æ•°ã‚’表ã™ã€‚" +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." +msgstr "" #: doc/classes/@GlobalScope.xml msgid "DualShock circle button." @@ -4666,8 +4671,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -11677,15 +11680,19 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "enum [enum FFT_Size] ã®ã‚µã‚¤ã‚ºã‚’表ã—ã¾ã™ã€‚" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +#, fuzzy +msgid "Audio effect used for recording the sound from an audio bus." msgstr "音をマイクã§éŒ²éŸ³ã™ã‚‹éš›ã«ä½¿ç”¨ã™ã‚‹ã‚ªãƒ¼ãƒ‡ã‚£ã‚ªã‚¨ãƒ•ェクト。" #: doc/classes/AudioEffectRecord.xml +#, fuzzy msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" "ユーザーãŒéŸ³ã‚’マイクã§éŒ²éŸ³ã§ãるよã†ã«ã—ã¾ã™ã€‚録音ã•れるオーディオファイルã®" "フォーマットをè¨å®šã—ã€å–å¾—ã§ãã¾ã™ (8 bitã€16 bitã€åœ§ç¸®)。録音ä¸ã§ã‚ã‚‹ã‹ã©ã†" @@ -18189,9 +18196,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -18204,20 +18210,24 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" +"[code]name[/code] ã¨ã„ã†åå‰ã§æŒ‡å®šã—ãŸè¨å®šãŒå˜åœ¨ã™ã‚‹å ´åˆã¯ [code]true[/" +"code]ã€ãã†ã§ãªã„å ´åˆã¯ [code]false[/code] ã‚’è¿”ã—ã¾ã™ã€‚" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -18225,8 +18235,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -18234,16 +18246,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -18626,6 +18642,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "ã‚ーå [code]name[/code] ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’削除ã—ã¾ã™ã€‚" + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "ã‚ーå [code]name[/code] ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’削除ã—ã¾ã™ã€‚" + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "ã‚ーå [code]name[/code] ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’削除ã—ã¾ã™ã€‚" + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "ã‚ーå [code]name[/code] ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’削除ã—ã¾ã™ã€‚" + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "インデックス [code]index[/code] ã®ãƒã‚¹ã‚’削除ã—ã¾ã™ã€‚" + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "ã‚ーå [code]name[/code] ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’削除ã—ã¾ã™ã€‚" + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -19115,7 +19164,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -24975,111 +25032,251 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Gets the current branch name defined in the VCS." +msgstr "テクスãƒãƒ£ã®ç¾åœ¨è¡¨ç¤ºã•れã¦ã„るフレームをè¨å®šã—ã¾ã™ã€‚" + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "ã“ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã®ãƒ–レンドシェイプã®åå‰ã‚’è¿”ã—ã¾ã™ã€‚" + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Remove a remote from the local VCS." +msgstr "インデックスã«ã‚ˆã‚Šé…列ã‹ã‚‰è¦ç´ を削除ã—ã¾ã™ã€‚" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "ディテールテクスãƒãƒ£ã¨å…±ã« [code]UV[/code] を使用ã—ã¾ã™ã€‚" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Pops up an error message in the edior." +msgstr "エディタ内ã§ãƒ—ãƒãƒ‘ティをグループ化ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã—ã¾ã™ã€‚" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -26538,9 +26735,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -26597,7 +26799,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -28347,6 +28551,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "円柱ã®ãƒ¬ãƒ³ãƒ€ãƒªãƒ³ã‚°ã«ä½¿ã†ãƒžãƒ†ãƒªã‚¢ãƒ«ã€‚" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -32393,7 +32686,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -36332,7 +36625,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -36346,7 +36639,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -36568,13 +36862,20 @@ msgid "The [Mesh] that will be drawn by the [MeshInstance2D]." msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml +#, fuzzy msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." msgstr "" +"ディテールオーãƒãƒ¼ãƒ¬ã‚¤ã®ãƒ”クセルã”ã¨ã®æ³•線を指定ã™ã‚‹ãƒ†ã‚¯ã‚¹ãƒãƒ£ã§ã™ã€‚\n" +"[b]注:[/b] Godotã¯ã€æ³•線マップãŒX+ã€Y-ã€ãŠã‚ˆã³Z+ã®åº§æ¨™ã‚’使用ã™ã‚‹ã“ã¨ã‚’期待ã—" +"ã¦ã„ã¾ã™ã€‚一般的ãªã‚¨ãƒ³ã‚¸ãƒ³ã«ã¦æœŸå¾…ã•ã‚Œã‚‹æ³•ç·šãƒžãƒƒãƒ—åº§æ¨™ã®æ¯”較ã¯ã€[url=http://" +"wiki.polycount.com/wiki/" +"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]ã“ã®ãƒšãƒ¼ã‚¸[/url] ã‚’å‚" +"ç…§ã—ã¦ãã ã•ã„。" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" @@ -37569,7 +37870,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -37644,9 +37945,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -37739,12 +38040,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -37771,13 +38066,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -38136,7 +38424,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -41301,6 +41589,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -43080,6 +43371,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -43200,6 +43495,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -47693,7 +47992,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -48470,6 +48771,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -51085,9 +51398,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" "AABBã¯ä½ç½®ã€å¤§ãã•ã€ãŠã‚ˆã³ã„ãã¤ã‹ã®ãƒ¦ãƒ¼ãƒ†ã‚£ãƒªãƒ†ã‚£é–¢æ•°ã‹ã‚‰ãªã‚Šã¾ã™ã€‚主ã«é«˜é€Ÿ" "ãªã‚ªãƒ¼ãƒãƒ¼ãƒ©ãƒƒãƒ—検出ã«ä½¿ç”¨ã•れã¾ã™ã€‚" @@ -54451,6 +54762,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -55219,6 +55536,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -55985,9 +56312,10 @@ msgstr "" "ãŸã‚ã«ä½¿ç”¨ã•れるテクスãƒãƒ£ã§ã™ã€‚" #: doc/classes/SpatialMaterial.xml +#, fuzzy msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -56246,7 +56574,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -57548,13 +57876,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -64115,7 +64443,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -65225,8 +65555,17 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." -msgstr "ã“ã®ãƒ™ã‚¯ãƒˆãƒ«ã¨ [code]with[/code] ã®ã‚¯ãƒã‚¹ç©ã‚’è¿”ã—ã¾ã™ã€‚" +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." +msgstr "" #: doc/classes/Vector2.xml msgid "" diff --git a/doc/translations/ko.po b/doc/translations/ko.po index 7e7d886ea0..5e79cdef11 100644 --- a/doc/translations/ko.po +++ b/doc/translations/ko.po @@ -2871,7 +2871,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3865,8 +3870,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9468,15 +9471,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15618,9 +15623,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15636,17 +15640,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15654,8 +15659,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15663,16 +15670,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -16031,6 +16042,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -16517,7 +16561,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22366,111 +22418,247 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23917,9 +24105,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23976,7 +24169,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25705,6 +25900,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29722,7 +30006,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33619,7 +33903,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33633,7 +33917,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33857,7 +34142,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34846,7 +35131,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34915,9 +35200,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -35008,12 +35293,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -35039,13 +35318,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35395,7 +35667,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38674,6 +38946,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40423,6 +40698,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40543,6 +40822,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -45010,7 +45293,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45773,6 +46058,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -48371,9 +48668,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51719,6 +52014,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52485,6 +52786,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -53191,7 +53502,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53389,7 +53700,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54523,13 +54834,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60992,7 +61303,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -62097,7 +62410,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/lv.po b/doc/translations/lv.po index 7fd77a6adc..b560b54e69 100644 --- a/doc/translations/lv.po +++ b/doc/translations/lv.po @@ -2759,7 +2759,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3753,8 +3758,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9353,15 +9356,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15468,9 +15473,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15486,17 +15490,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15504,8 +15509,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15513,16 +15520,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15882,6 +15893,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16367,7 +16405,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22151,111 +22197,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23701,9 +23882,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23760,7 +23946,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25489,6 +25677,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29497,7 +29773,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33391,7 +33667,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33405,7 +33681,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33629,7 +33906,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34600,7 +34877,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34668,9 +34945,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34762,12 +35039,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34791,13 +35062,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35145,7 +35409,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38295,6 +38559,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40027,6 +40294,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40147,6 +40418,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44607,7 +44882,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45370,6 +45647,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -47968,9 +48257,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51316,6 +51603,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52082,6 +52375,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52788,7 +53091,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -52986,7 +53289,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54120,13 +54423,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60581,7 +60884,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61686,7 +61991,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/mr.po b/doc/translations/mr.po index da3c6ecbe3..69aaa02fc5 100644 --- a/doc/translations/mr.po +++ b/doc/translations/mr.po @@ -2742,7 +2742,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3736,8 +3741,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9317,15 +9320,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15392,9 +15397,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15410,17 +15414,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15428,8 +15433,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15437,16 +15444,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15806,6 +15817,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16291,7 +16329,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22049,111 +22095,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23593,9 +23774,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23652,7 +23838,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25372,6 +25560,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29361,7 +29637,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33233,7 +33509,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33247,7 +33523,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33471,7 +33748,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34428,7 +34705,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34496,9 +34773,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34590,12 +34867,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34619,13 +34890,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -34973,7 +35237,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38105,6 +38369,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -39835,6 +40102,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -39952,6 +40223,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44409,7 +44684,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45172,6 +45449,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -47765,9 +48054,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51100,6 +51387,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -51862,6 +52155,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52559,7 +52862,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -52757,7 +53060,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53891,13 +54194,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60340,7 +60643,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61443,7 +61748,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/nb.po b/doc/translations/nb.po index 2b78a146f1..395ddd5a2f 100644 --- a/doc/translations/nb.po +++ b/doc/translations/nb.po @@ -5,20 +5,21 @@ # # slasken06 <ask.skivdal@gmail.com>, 2021. # Daniel Skogly <daniel@klungo.no>, 2021. +# Imre Kristoffer Eilertsen <imreeil42@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2021-11-03 13:15+0000\n" -"Last-Translator: Daniel Skogly <daniel@klungo.no>\n" +"PO-Revision-Date: 2022-01-10 13:19+0000\n" +"Last-Translator: Imre Kristoffer Eilertsen <imreeil42@gmail.com>\n" "Language-Team: Norwegian BokmÃ¥l <https://hosted.weblate.org/projects/godot-" "engine/godot-class-reference/nb_NO/>\n" -"Language: nb_NO\n" +"Language: nb\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.9-dev\n" +"X-Generator: Weblate 4.10.1\n" #: doc/tools/make_rst.py msgid "Description" @@ -26,7 +27,7 @@ msgstr "Beskrivelse" #: doc/tools/make_rst.py msgid "Tutorials" -msgstr "" +msgstr "Opplæring" #: doc/tools/make_rst.py msgid "Properties" @@ -78,19 +79,19 @@ msgstr "" #: doc/tools/make_rst.py msgid "Default" -msgstr "" +msgstr "Standard" #: doc/tools/make_rst.py msgid "Setter" -msgstr "" +msgstr "Setter" #: doc/tools/make_rst.py msgid "value" -msgstr "" +msgstr "verdi" #: doc/tools/make_rst.py msgid "Getter" -msgstr "" +msgstr "Henter" #: doc/tools/make_rst.py msgid "" @@ -2752,7 +2753,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3746,8 +3752,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9327,15 +9331,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15402,9 +15408,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15420,17 +15425,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15438,8 +15444,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15447,16 +15455,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15816,6 +15828,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16301,7 +16340,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22059,111 +22106,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23603,9 +23785,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23662,7 +23849,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25382,6 +25571,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29371,7 +29648,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33243,7 +33520,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33257,7 +33534,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33481,7 +33759,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34438,7 +34716,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34506,9 +34784,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34600,12 +34878,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34629,13 +34901,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -34983,7 +35248,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38115,6 +38380,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -39845,6 +40113,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -39962,6 +40234,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44419,7 +44695,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45182,6 +45460,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -47775,9 +48065,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51110,6 +51398,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -51872,6 +52166,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52569,7 +52873,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -52767,7 +53071,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53901,13 +54205,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60350,7 +60654,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61140,11 +61446,11 @@ msgstr "" #: modules/upnp/doc_classes/UPNP.xml msgid "Invalid parameter." -msgstr "" +msgstr "Ugyldig parameter." #: modules/upnp/doc_classes/UPNP.xml modules/upnp/doc_classes/UPNPDevice.xml msgid "HTTP error." -msgstr "" +msgstr "HTTP feil." #: modules/upnp/doc_classes/UPNP.xml msgid "Socket error." @@ -61168,7 +61474,7 @@ msgstr "" #: modules/upnp/doc_classes/UPNP.xml modules/upnp/doc_classes/UPNPDevice.xml msgid "Unknown error." -msgstr "" +msgstr "Ukjent feil." #: modules/upnp/doc_classes/UPNPDevice.xml msgid "UPNP device." @@ -61453,7 +61759,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/ne.po b/doc/translations/ne.po index 2c380d647b..1d93069025 100644 --- a/doc/translations/ne.po +++ b/doc/translations/ne.po @@ -2742,7 +2742,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3736,8 +3741,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9317,15 +9320,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15392,9 +15397,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15410,17 +15414,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15428,8 +15433,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15437,16 +15444,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15806,6 +15817,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16291,7 +16329,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22049,111 +22095,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23593,9 +23774,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23652,7 +23838,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25372,6 +25560,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29361,7 +29637,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33233,7 +33509,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33247,7 +33523,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33471,7 +33748,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34428,7 +34705,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34496,9 +34773,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34590,12 +34867,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34619,13 +34890,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -34973,7 +35237,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38105,6 +38369,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -39835,6 +40102,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -39952,6 +40223,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44409,7 +44684,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45172,6 +45449,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -47765,9 +48054,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51100,6 +51387,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -51862,6 +52155,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52559,7 +52862,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -52757,7 +53060,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53891,13 +54194,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60340,7 +60643,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61443,7 +61748,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/nl.po b/doc/translations/nl.po index f3b757ffba..cc577df882 100644 --- a/doc/translations/nl.po +++ b/doc/translations/nl.po @@ -2793,7 +2793,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3787,8 +3792,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9387,15 +9390,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15502,9 +15507,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15520,17 +15524,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15538,8 +15543,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15547,16 +15554,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15916,6 +15927,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16401,7 +16439,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22185,111 +22231,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23735,9 +23916,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23794,7 +23980,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25523,6 +25711,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29531,7 +29807,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33425,7 +33701,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33439,7 +33715,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33663,7 +33940,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34634,7 +34911,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34702,9 +34979,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34796,12 +35073,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34825,13 +35096,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35179,7 +35443,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38329,6 +38593,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40061,6 +40328,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40181,6 +40452,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44641,7 +44916,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45404,6 +45681,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -48002,9 +48291,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51351,6 +51638,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52117,6 +52410,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52823,7 +53126,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53021,7 +53324,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54155,13 +54458,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60616,7 +60919,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61721,7 +62026,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/pl.po b/doc/translations/pl.po index 460b6640f5..34ad88e7af 100644 --- a/doc/translations/pl.po +++ b/doc/translations/pl.po @@ -3210,7 +3210,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -4204,8 +4209,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9813,15 +9816,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15945,9 +15950,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15963,17 +15967,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15981,8 +15986,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15990,16 +15997,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -16358,6 +16369,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "Liczy iloczyn wektorowy tego wektora oraz [code]with[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "Liczy iloczyn wektorowy tego wektora oraz [code]with[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "Liczy iloczyn wektorowy tego wektora oraz [code]with[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "Liczy iloczyn wektorowy tego wektora oraz [code]with[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "Liczy iloczyn wektorowy tego wektora oraz [code]with[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "Liczy iloczyn wektorowy tego wektora oraz [code]with[/code]." + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -16844,7 +16888,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22638,111 +22690,247 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "Zwraca sinus parametru." + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -24189,9 +24377,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -24248,7 +24441,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25981,6 +26176,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "Zwraca sinus parametru." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -30001,7 +30285,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33907,7 +34191,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33921,7 +34205,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -34145,7 +34430,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -35141,7 +35426,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -35216,9 +35501,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -35309,12 +35594,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -35340,13 +35619,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35700,7 +35972,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38856,6 +39128,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40620,6 +40895,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40740,6 +41019,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -45209,7 +45492,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45972,6 +46257,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -48578,9 +48875,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51929,6 +52224,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52696,6 +52997,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -53402,7 +53713,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53600,7 +53911,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54737,13 +55048,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -61216,7 +61527,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -62321,8 +62634,17 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." -msgstr "Liczy iloczyn wektorowy tego wektora oraz [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." +msgstr "" #: doc/classes/Vector2.xml msgid "" diff --git a/doc/translations/pt.po b/doc/translations/pt.po index b11d10ee96..4452a8e461 100644 --- a/doc/translations/pt.po +++ b/doc/translations/pt.po @@ -3497,8 +3497,13 @@ msgid "Gamepad button 22." msgstr "Botão 22 do controle." #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." -msgstr "Representa a quantidade máxima de botões de joystick suportados." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." +msgstr "" #: doc/classes/@GlobalScope.xml msgid "DualShock circle button." @@ -4501,8 +4506,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -10094,15 +10097,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -16207,9 +16212,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -16225,17 +16229,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -16243,8 +16248,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -16252,16 +16259,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -16620,6 +16631,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "Retorna o nome do nó em [code]idx[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "Retorna o nome do nó em [code]idx[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "Retorna o nome do nó em [code]idx[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "Retorna o nome do nó em [code]idx[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "Retorna o nome do nó em [code]idx[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "Retorna o nome do nó em [code]idx[/code]." + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -17108,7 +17152,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22872,111 +22924,252 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Discards the changes made in file present at [code]file_path[/code]." +msgstr "Salva a cena como um ficheiro em [code]path[/code]." + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "Retorna o nome do nó em [code]idx[/code]." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Remove a branch from the local VCS." +msgstr "Remove todos os pontos da linha." + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Remove a remote from the local VCS." +msgstr "Remove todos os itens da lista." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "Salva a cena como um ficheiro em [code]path[/code]." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "A new file has been added." +msgstr "Emitido quando uma nova interface é adicionada." + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -24416,9 +24609,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -24475,7 +24673,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -26195,6 +26395,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "A largura de uma textura." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -30184,7 +30473,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -34060,7 +34349,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -34074,7 +34363,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -34298,7 +34588,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -35268,7 +35558,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -35338,9 +35628,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -35434,12 +35724,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -35463,13 +35747,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35820,7 +36097,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38954,6 +39231,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40686,6 +40966,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40803,6 +41087,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -45260,7 +45548,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -46023,6 +46313,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -48616,9 +48918,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51953,6 +52253,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52716,6 +53022,17 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +#, fuzzy +msgid "Emitted when dragging is started." +msgstr "Emitido quando um ficheiro é selecionado." + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -53413,7 +53730,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53615,7 +53932,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54763,13 +55080,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -61217,7 +61534,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -62320,8 +62639,17 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." -msgstr "Retorna o produto cruzado deste vetor e [code]com[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." +msgstr "" #: doc/classes/Vector2.xml msgid "" diff --git a/doc/translations/pt_BR.po b/doc/translations/pt_BR.po index aa55ec1a2f..00f49e35c1 100644 --- a/doc/translations/pt_BR.po +++ b/doc/translations/pt_BR.po @@ -3646,8 +3646,13 @@ msgid "Gamepad button 22." msgstr "Botão 22 do controle." #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." -msgstr "Representa o número máximo de botões de joystick suportados." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." +msgstr "" #: doc/classes/@GlobalScope.xml msgid "DualShock circle button." @@ -4727,8 +4732,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -10350,15 +10353,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -16529,9 +16534,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -16547,17 +16551,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -16565,8 +16570,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -16574,16 +16581,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -16942,6 +16953,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "Retorna o nome do nó em [code]idx[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "Retorna o nome do nó em [code]idx[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "Retorna o nome do nó em [code]idx[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "Retorna o nome do nó em [code]idx[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "Retorna o nome do nó em [code]idx[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "Retorna o nome do nó em [code]idx[/code]." + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -17430,7 +17474,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -23227,111 +23279,252 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Discards the changes made in file present at [code]file_path[/code]." +msgstr "Salva a cena como um arquivo em [code]path[/code]." + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "Retorna o nome do nó em [code]idx[/code]." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Remove a branch from the local VCS." +msgstr "Remove todos os pontos da linha." + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Remove a remote from the local VCS." +msgstr "Remove todos os itens da lista." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "Salva a cena como um arquivo em [code]path[/code]." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "A new file has been added." +msgstr "Emitido quando uma nova interface é adicionada." + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -24779,9 +24972,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -24838,7 +25036,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -26571,6 +26771,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "A largura de uma textura." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -30605,7 +30894,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -34513,7 +34802,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -34527,7 +34816,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -34751,7 +35041,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -35743,7 +36033,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -35815,9 +36105,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -35910,12 +36200,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -35941,13 +36225,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -36304,7 +36581,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -39456,6 +39733,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -41223,6 +41503,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -41343,6 +41627,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -45815,7 +46103,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -46578,6 +46868,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -49182,9 +49484,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -52531,6 +52831,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -53301,6 +53607,17 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +#, fuzzy +msgid "Emitted when dragging is started." +msgstr "Emitido quando um arquivo é selecionado." + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -54008,7 +54325,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54210,7 +54527,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -55361,13 +55678,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -61856,7 +62173,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -62960,8 +63279,17 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." -msgstr "Retorna o produto cruzado deste vetor e [code]com[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." +msgstr "" #: doc/classes/Vector2.xml msgid "" diff --git a/doc/translations/ro.po b/doc/translations/ro.po index 11b2ac9b13..2d61f987eb 100644 --- a/doc/translations/ro.po +++ b/doc/translations/ro.po @@ -2762,7 +2762,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3756,8 +3761,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9356,15 +9359,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15471,9 +15476,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15489,17 +15493,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15507,8 +15512,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15516,16 +15523,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15885,6 +15896,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16370,7 +16408,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22154,111 +22200,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23704,9 +23885,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23763,7 +23949,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25492,6 +25680,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29500,7 +29776,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33394,7 +33670,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33408,7 +33684,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33632,7 +33909,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34603,7 +34880,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34671,9 +34948,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34765,12 +35042,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34794,13 +35065,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35148,7 +35412,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38298,6 +38562,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40030,6 +40297,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40150,6 +40421,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44610,7 +44885,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45373,6 +45650,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -47971,9 +48260,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51319,6 +51606,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52085,6 +52378,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52791,7 +53094,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -52989,7 +53292,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54123,13 +54426,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60584,7 +60887,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61689,7 +61994,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/ru.po b/doc/translations/ru.po index 8c22c1edf5..6bfd3b83b6 100644 --- a/doc/translations/ru.po +++ b/doc/translations/ru.po @@ -3740,9 +3740,13 @@ msgid "Gamepad button 22." msgstr "Кнопка 22 геймпада." #: doc/classes/@GlobalScope.xml -#, fuzzy -msgid "Represents the maximum number of joystick buttons supported." -msgstr "МакÑимальное чиÑло кнопок игрового контроллера." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." +msgstr "" #: doc/classes/@GlobalScope.xml msgid "DualShock circle button." @@ -4865,8 +4869,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -10956,15 +10958,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -17177,9 +17181,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -17192,20 +17195,24 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" +"Возвращает [code]true[/code] еÑли [code]a[/code] и [code]b[/code] " +"приблизительно равны друг другу." #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -17213,8 +17220,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -17222,16 +17231,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -17617,6 +17630,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "Возвращает ÑкалÑрное произведение Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð¾Ð¼ [code]b[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "Возвращает ÑкалÑрное произведение Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð¾Ð¼ [code]b[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "Возвращает ÑкалÑрное произведение Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð¾Ð¼ [code]b[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "Возвращает ÑкалÑрное произведение Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð¾Ð¼ [code]b[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "Возвращает ÑкалÑрное произведение Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð¾Ð¼ [code]b[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "Возвращает ÑкалÑрное произведение Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð¾Ð¼ [code]b[/code]." + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -18105,7 +18151,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -23914,111 +23968,250 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Gets the current branch name defined in the VCS." +msgstr "УÑтанавливает текущий видимый кадр текÑтуры." + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "Возвращает ÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Remove a remote from the local VCS." +msgstr "УдалÑет Ñлемент из маÑÑива по индекÑу." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Pops up an error message in the edior." +msgstr "ИÑпользуетÑÑ Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð¸Ñ€Ð¾Ð²ÐºÐ¸ ÑвойÑтв в редакторе." + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -25468,9 +25661,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -25527,7 +25725,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -27262,6 +27462,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "Цвет Ñффекта отражениÑ." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -31286,7 +31575,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -35213,7 +35502,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -35227,7 +35516,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -35451,7 +35741,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -36447,7 +36737,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -36519,9 +36809,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -36613,12 +36903,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -36644,13 +36928,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -37004,7 +37281,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -40171,6 +40448,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -41940,6 +42220,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -42060,6 +42344,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -46556,7 +46844,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -47323,6 +47613,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -49971,9 +50273,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" "AABB ÑоÑтоит из позиции, размера и неÑкольких вÑпомогательных функций. " "Обычно иÑпользуетÑÑ Ð´Ð»Ñ Ð±Ñ‹Ñтрых теÑтов на перекрытие." @@ -53327,6 +53627,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -54094,6 +54400,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -54806,7 +55122,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -55007,7 +55323,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -56143,18 +56459,26 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml +#, fuzzy msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" "code] will make it so the [code]run[/code] animation uses the normal map." msgstr "" +"ÐÐ½Ð¸Ð¼Ð°Ñ†Ð¸Ñ ÑоздаетÑÑ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ реÑурÑа [SpriteFrames], который можно наÑтроить " +"в редакторе Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ панели SpriteFrames.\n" +"[b]Примечание:[/b] Ð’Ñ‹ можете ÑвÑзать набор карт нормалей, Ñоздав " +"дополнительные реÑурÑÑ‹ [SpriteFrames] Ñ ÑуффикÑом [code]_normal[/code]. " +"Ðапример, наличие двух реÑурÑов [SpriteFrames] [code]run[/code] и " +"[code]run_normal[/code] Ñделает так, что Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ [code]run[/code] будет " +"иÑпользовать карту нормалей." #: doc/classes/SpriteFrames.xml msgid "Adds a new animation to the library." @@ -62684,7 +63008,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -63809,9 +64135,17 @@ msgstr "" "length()[/code]." #: doc/classes/Vector2.xml -#, fuzzy -msgid "Returns the cross product of this vector and [code]with[/code]." -msgstr "Возвращает ÑкалÑрное произведение Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð¾Ð¼ [code]b[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." +msgstr "" #: doc/classes/Vector2.xml #, fuzzy diff --git a/doc/translations/sk.po b/doc/translations/sk.po index 9d36ee690b..1939f0226d 100644 --- a/doc/translations/sk.po +++ b/doc/translations/sk.po @@ -2745,7 +2745,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3739,8 +3744,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9339,15 +9342,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15454,9 +15459,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15472,17 +15476,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15490,8 +15495,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15499,16 +15506,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15868,6 +15879,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16353,7 +16391,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22137,111 +22183,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23687,9 +23868,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23746,7 +23932,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25475,6 +25663,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29483,7 +29759,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33377,7 +33653,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33391,7 +33667,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33615,7 +33892,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34586,7 +34863,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34654,9 +34931,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34748,12 +35025,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34777,13 +35048,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35131,7 +35395,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38281,6 +38545,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40013,6 +40280,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40133,6 +40404,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44593,7 +44868,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45356,6 +45633,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -47954,9 +48243,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51302,6 +51589,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52068,6 +52361,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52774,7 +53077,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -52972,7 +53275,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54106,13 +54409,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60567,7 +60870,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61672,7 +61977,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/sr_Cyrl.po b/doc/translations/sr_Cyrl.po index 7330ba9f1f..7dd34a8986 100644 --- a/doc/translations/sr_Cyrl.po +++ b/doc/translations/sr_Cyrl.po @@ -2756,7 +2756,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3750,8 +3755,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9350,15 +9353,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15465,9 +15470,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15483,17 +15487,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15501,8 +15506,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15510,16 +15517,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15879,6 +15890,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16364,7 +16402,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22148,111 +22194,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23698,9 +23879,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23757,7 +23943,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25486,6 +25674,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29494,7 +29770,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33388,7 +33664,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33402,7 +33678,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33626,7 +33903,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34597,7 +34874,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34665,9 +34942,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34759,12 +35036,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34788,13 +35059,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35142,7 +35406,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38292,6 +38556,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40024,6 +40291,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40144,6 +40415,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44604,7 +44879,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45367,6 +45644,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -47965,9 +48254,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51313,6 +51600,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52079,6 +52372,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52785,7 +53088,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -52983,7 +53286,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54117,13 +54420,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60578,7 +60881,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61683,7 +61988,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/sv.po b/doc/translations/sv.po index bb965079c5..c665310546 100644 --- a/doc/translations/sv.po +++ b/doc/translations/sv.po @@ -2745,7 +2745,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3739,8 +3744,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9320,15 +9323,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15395,9 +15400,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15413,17 +15417,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15431,8 +15436,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15440,16 +15447,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15809,6 +15820,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16294,7 +16332,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22052,111 +22098,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23596,9 +23777,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23655,7 +23841,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25375,6 +25563,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29364,7 +29640,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33236,7 +33512,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33250,7 +33526,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33474,7 +33751,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34431,7 +34708,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34499,9 +34776,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34593,12 +34870,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34622,13 +34893,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -34976,7 +35240,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38108,6 +38372,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -39838,6 +40105,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -39955,6 +40226,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44412,7 +44687,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45175,6 +45452,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -47768,9 +48057,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51103,6 +51390,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -51865,6 +52158,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52562,7 +52865,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -52760,7 +53063,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53894,13 +54197,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60343,7 +60646,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61446,7 +61751,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/th.po b/doc/translations/th.po index ca9954ed1c..c71cda4def 100644 --- a/doc/translations/th.po +++ b/doc/translations/th.po @@ -2838,7 +2838,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3839,8 +3844,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9441,15 +9444,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15558,9 +15563,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15576,17 +15580,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15594,8 +15599,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15603,16 +15610,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15972,6 +15983,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16457,7 +16495,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22241,111 +22287,247 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "คืนค่าผà¸à¸œà¸±à¸™à¸£à¸¹à¸—สà¸à¸‡à¸‚à¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23791,9 +23973,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23850,7 +24037,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25579,6 +25768,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "คืนค่า arc tanh ขà¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29597,7 +29875,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33502,7 +33780,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33516,7 +33794,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33740,7 +34019,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34718,7 +34997,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34786,9 +35065,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34880,12 +35159,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34909,13 +35182,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35263,7 +35529,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38445,6 +38711,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40180,6 +40449,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40300,6 +40573,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44764,7 +45041,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45527,6 +45806,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -48130,9 +48421,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51478,6 +51767,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52244,6 +52539,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52950,7 +53255,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53148,7 +53453,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54283,13 +54588,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60746,7 +61051,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61857,7 +62164,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/tl.po b/doc/translations/tl.po index e7155eb8d5..a30b704472 100644 --- a/doc/translations/tl.po +++ b/doc/translations/tl.po @@ -2817,8 +2817,13 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." -msgstr "Kumakatawan sa pinakamaraming bilang ng joystick na sinusuportahan." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." +msgstr "" #: doc/classes/@GlobalScope.xml msgid "DualShock circle button." @@ -3811,8 +3816,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9392,15 +9395,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15470,9 +15475,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15488,17 +15492,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15506,8 +15511,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15515,16 +15522,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15884,6 +15895,33 @@ msgstr "" #: doc/classes/Control.xml msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "" + +#: doc/classes/Control.xml +msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " "anchor_bottom], [member anchor_left], [member anchor_right] and [member " @@ -16369,7 +16407,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22127,111 +22173,246 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Returns the name of the underlying VCS provider." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23671,9 +23852,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23730,7 +23916,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25450,6 +25638,94 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The [Gradient] used to fill the texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29439,7 +29715,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33311,7 +33587,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33325,7 +33601,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33549,7 +33826,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34512,7 +34789,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34580,9 +34857,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34674,12 +34951,6 @@ msgstr "" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." msgstr "" @@ -34703,13 +34974,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35057,7 +35321,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38189,6 +38453,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -39919,6 +40186,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40036,6 +40307,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44493,7 +44768,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45256,6 +45533,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -47849,9 +48138,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51184,6 +51471,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -51946,6 +52239,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52643,7 +52946,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -52841,7 +53144,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53975,13 +54278,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60427,7 +60730,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61530,7 +61835,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/tr.po b/doc/translations/tr.po index 213c6cb98a..31c0cd045f 100644 --- a/doc/translations/tr.po +++ b/doc/translations/tr.po @@ -3516,7 +3516,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -4510,8 +4515,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -10112,15 +10115,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -16242,9 +16247,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -16260,17 +16264,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -16278,8 +16283,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -16287,16 +16294,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -16655,6 +16666,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "Verilen deÄŸerin sinüsünü döndürür." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "Verilen deÄŸerin sinüsünü döndürür." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "Verilen deÄŸerin sinüsünü döndürür." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "Verilen deÄŸerin sinüsünü döndürür." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "Verilen deÄŸerin sinüsünü döndürür." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "Verilen deÄŸerin sinüsünü döndürür." + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -17141,7 +17185,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22931,111 +22983,247 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "Verilen deÄŸerin sinüsünü döndürür." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -24486,9 +24674,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -24545,7 +24738,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -26276,6 +26471,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "Verilen deÄŸerin sinüsünü döndürür." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -30289,7 +30573,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -34187,7 +34471,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -34201,7 +34485,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -34425,7 +34710,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -35417,7 +35702,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -35486,9 +35771,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -35579,12 +35864,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -35610,13 +35889,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35969,7 +36241,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -39122,6 +39394,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40879,6 +41154,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40999,6 +41278,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -45468,7 +45751,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -46231,6 +46516,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -48836,9 +49133,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -52184,6 +52479,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52950,6 +53251,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -53656,7 +53967,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53854,7 +54165,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54990,13 +55301,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -61461,7 +61772,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -62566,7 +62879,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/uk.po b/doc/translations/uk.po index 41495f384a..c4a4cdbaf5 100644 --- a/doc/translations/uk.po +++ b/doc/translations/uk.po @@ -2869,7 +2869,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3863,8 +3868,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9471,15 +9474,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15594,9 +15599,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15612,17 +15616,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15630,8 +15635,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15639,16 +15646,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -16007,6 +16018,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "ОбчиÑлює векторний добуток двох векторів та [code]with[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "ОбчиÑлює векторний добуток двох векторів та [code]with[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "ОбчиÑлює векторний добуток двох векторів та [code]with[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "ОбчиÑлює векторний добуток двох векторів та [code]with[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "ОбчиÑлює векторний добуток двох векторів та [code]with[/code]." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "ОбчиÑлює векторний добуток двох векторів та [code]with[/code]." + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -16493,7 +16537,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22281,111 +22333,247 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "Повертає ÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23832,9 +24020,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23891,7 +24084,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25621,6 +25816,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "Повертає ÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29637,7 +29921,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33534,7 +33818,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33548,7 +33832,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33772,7 +34057,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34763,7 +35048,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34832,9 +35117,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34925,12 +35210,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -34956,13 +35235,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35312,7 +35584,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38465,6 +38737,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40216,6 +40491,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40336,6 +40615,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44803,7 +45086,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45566,6 +45851,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -48164,9 +48461,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51512,6 +51807,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52279,6 +52580,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52985,7 +53296,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53183,7 +53494,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54318,13 +54629,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60789,7 +61100,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61894,8 +62207,17 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." -msgstr "ОбчиÑлює векторний добуток двох векторів та [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." +msgstr "" #: doc/classes/Vector2.xml msgid "" diff --git a/doc/translations/vi.po b/doc/translations/vi.po index b0fe535eca..f6621f3c4b 100644 --- a/doc/translations/vi.po +++ b/doc/translations/vi.po @@ -3169,7 +3169,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -4174,8 +4179,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9772,15 +9775,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15857,9 +15862,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15875,17 +15879,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15893,8 +15898,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15902,16 +15909,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -16270,6 +16281,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "Trả vá» sin cá»§a tham số." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "Trả vá» sin cá»§a tham số." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "Trả vá» sin cá»§a tham số." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "Trả vá» sin cá»§a tham số." + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "Trả vá» sin cá»§a tham số." + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "Trả vá» sin cá»§a tham số." + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -16756,7 +16800,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22520,111 +22572,247 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "Trả vá» sin cá»§a tham số." + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -24067,9 +24255,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -24126,7 +24319,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25846,6 +26041,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "Trả vá» sin cá»§a tham số." + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29840,7 +30124,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33715,7 +33999,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33729,7 +34013,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33953,7 +34238,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34929,7 +35214,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34999,9 +35284,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -35092,12 +35377,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -35123,13 +35402,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35481,7 +35753,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38616,6 +38888,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40369,6 +40644,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40486,6 +40765,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44955,7 +45238,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45720,6 +46005,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -48318,9 +48615,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51653,6 +51948,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52415,6 +52716,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -53114,7 +53425,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53313,7 +53624,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54448,13 +54759,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60911,7 +61222,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -62014,7 +62327,16 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." msgstr "" #: doc/classes/Vector2.xml diff --git a/doc/translations/zh_CN.po b/doc/translations/zh_CN.po index e65d84756e..94f4b4d5da 100644 --- a/doc/translations/zh_CN.po +++ b/doc/translations/zh_CN.po @@ -61,7 +61,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-01-07 07:07+0000\n" +"PO-Revision-Date: 2022-01-12 16:56+0000\n" "Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot-class-reference/zh_Hans/>\n" @@ -113,69 +113,68 @@ msgid "Method Descriptions" msgstr "方法说明" #: doc/tools/make_rst.py -#, fuzzy msgid "Theme Property Descriptions" -msgstr "属性说明" +msgstr "主题属性说明" #: doc/tools/make_rst.py msgid "Inherits:" -msgstr "" +msgstr "继承:" #: doc/tools/make_rst.py msgid "Inherited By:" -msgstr "" +msgstr "派生:" #: doc/tools/make_rst.py msgid "(overrides %s)" -msgstr "" +msgstr "(覆盖 %s)" #: doc/tools/make_rst.py msgid "Default" -msgstr "" +msgstr "默认" #: doc/tools/make_rst.py msgid "Setter" -msgstr "" +msgstr "Setter" #: doc/tools/make_rst.py msgid "value" -msgstr "" +msgstr "值" #: doc/tools/make_rst.py msgid "Getter" -msgstr "" +msgstr "Getter" #: doc/tools/make_rst.py msgid "" "This method should typically be overridden by the user to have any effect." -msgstr "" +msgstr "本方法通常需è¦ç”¨æˆ·è¦†ç›–æ‰èƒ½ç”Ÿæ•ˆã€‚" #: doc/tools/make_rst.py msgid "" "This method has no side effects. It doesn't modify any of the instance's " "member variables." -msgstr "" +msgstr "本方法没有副作用。ä¸ä¼šä¿®æ”¹è¯¥å®žä¾‹çš„任何æˆå‘˜å˜é‡ã€‚" #: doc/tools/make_rst.py msgid "" "This method accepts any number of arguments after the ones described here." -msgstr "" +msgstr "本方法除了在æ¤å¤„æè¿°çš„傿•°å¤–ï¼Œè¿˜èƒ½å¤Ÿç»§ç»æŽ¥å—ä»»æ„æ•°é‡çš„傿•°ã€‚" #: doc/tools/make_rst.py msgid "This method is used to construct a type." -msgstr "" +msgstr "æœ¬æ–¹æ³•ç”¨äºŽæž„é€ æŸä¸ªç±»åž‹ã€‚" #: doc/tools/make_rst.py msgid "" "This method doesn't need an instance to be called, so it can be called " "directly using the class name." -msgstr "" +msgstr "è°ƒç”¨æœ¬æ–¹æ³•æ— éœ€å®žä¾‹ï¼Œæ‰€ä»¥å¯ä»¥ç›´æŽ¥ä½¿ç”¨ç±»å调用。" #: doc/tools/make_rst.py msgid "" "This method describes a valid operator to use with this type as left-hand " "operand." -msgstr "" +msgstr "本方法æè¿°çš„æ˜¯ä½¿ç”¨æœ¬ç±»åž‹ä½œä¸ºå·¦æ“作数的有效æ“作符。" #: modules/gdscript/doc_classes/@GDScript.xml msgid "Built-in GDScript functions." @@ -847,6 +846,20 @@ msgid "" "[/codeblock]\n" "See also [method lerp] which performs the reverse of this operation." msgstr "" +"返回æ’å€¼æˆ–å¤–æŽ¨çš„å› å。范围用 [code]from[/code] å’Œ [code]to[/code] 指定,æ’值" +"åŽçš„值用 [code]weight[/code] 指定。如果 [code]weight[/code] 在 [code]from[/" +"code] å’Œ [code]to[/code] 之间(包å«ï¼‰ï¼Œé‚£ä¹ˆè¿”回的值在 [code]0.0[/code] å’Œ " +"[code]1.0[/code] 之间。如果 [code]weight[/code] 在该范围之外,则返回的是外推" +"å› å(返回值å°äºŽ [code]0.0[/code] 或大于 [code]1.0[/code])。\n" +"[codeblock]\n" +"# 下é¢çš„ `lerp()` 调用时的æ’值比例是 0.75。\n" +"var middle = lerp(20, 30, 0.75)\n" +"# `middle` 现在是 27.5。\n" +"# 现在,我们å‡è£…忘记了原æ¥çš„æ¯”ä¾‹ï¼Œæƒ³è¦æ‰¾åˆ°æ˜¯å¤šå°‘。\n" +"var ratio = inverse_lerp(20, 30, 27.5)\n" +"# `ratio`现在是 0.75。\n" +"[/codeblock]\n" +"本æ“作的逆æ“作请å‚阅 [method lerp]。" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -908,7 +921,6 @@ msgstr "" "[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml -#, fuzzy msgid "" "Linearly interpolates between two values by the factor defined in " "[code]weight[/code]. To perform interpolation, [code]weight[/code] should be " @@ -928,8 +940,9 @@ msgid "" "To perform eased interpolation with [method lerp], combine it with [method " "ease] or [method smoothstep]." msgstr "" -"用一个归一化的值在两个值之间进行线性æ’值。这是 [method inverse_lerp] 的逆è¿" -"算。\n" +"在两个值之间按照 [code]weight[/code] å®šä¹‰çš„å› æ•°è¿›è¡Œçº¿æ€§æ’值。进行æ’值时," +"[code]weight[/code] 应该在 [code]0.0[/code] å’Œ [code]1.0[/code] 之间(包" +"å«ï¼‰ã€‚然而,在æ¤åŒºé—´å¤–的值也是å…许的,å¯ç”¨äºŽæ‰§è¡Œ[i]外推[/i]。\n" "如果 [code]from[/code] å’Œ [code]to[/code] 傿•°ç±»åž‹æ˜¯ [int] 或 [float],返回值" "都是 [float]。\n" "如果两者都是相åŒçš„å‘é‡ç±»åž‹ï¼ˆ[Vector2]ã€[Vector3]或[Color]),返回值将是相åŒçš„" @@ -938,10 +951,11 @@ msgstr "" "[codeblock]\n" "lerp(0, 4, 0.75) # 返回 3.0\n" "lerp(Vector2(1, 5), Vector2(3, 2), 0.5) # 返回 Vector2(2, 3.5)\n" -"[/codeblock]" +"[/codeblock]\n" +"å¦è¯·å‚阅本æ“作的逆è¿ç®— [method inverse_lerp]ã€‚è¦æ‰§è¡Œç¼“动的 [method lerp] æ’" +"值,请将其与 [method ease] 或 [method smoothstep] 组åˆã€‚" #: modules/gdscript/doc_classes/@GDScript.xml -#, fuzzy msgid "" "Linearly interpolates between two angles (in radians) by a normalized " "value.\n" @@ -959,8 +973,9 @@ msgid "" "[/codeblock]" msgstr "" "通过归一化值在两个角度之间(以弧度为å•ä½ï¼‰è¿›è¡Œçº¿æ€§æ’值。\n" -"与 [method lerp] 相似,但是当角度环绕 [constant @GDScript.TAU] 时会准确æ’" -"值。\n" +"与 [method lerp] 相似,但是当角度环绕 [constant @GDScript.TAU] 时会准确æ’值。" +"è¦ä½¿ç”¨ [method lerp_angle] 执行缓动æ’值,请将其与 [method ease] 或 [method " +"smoothstep] 组åˆã€‚\n" "[codeblock]\n" "extends Sprite\n" "var elapsed = 0.0\n" @@ -2235,7 +2250,7 @@ msgid "" "[b]Note:[/b] Only implemented on Android." msgstr "" "[JavaClassWrapper] å•例。\n" -"[b]注æ„:[/b] 仅在 Android 上实现。" +"[b]注æ„:[/b]仅在 Android 上实现。" #: doc/classes/@GlobalScope.xml msgid "" @@ -2243,26 +2258,23 @@ msgid "" "[b]Note:[/b] Only implemented on HTML5." msgstr "" "[JavaScript] å•例。\n" -"[b]注æ„:[/b] 仅在HTML5上实现。" +"[b]注æ„:[/b]仅在 HTML5 上实现。" #: doc/classes/@GlobalScope.xml msgid "The [Marshalls] singleton." msgstr "[Marshalls] å•例。" #: doc/classes/@GlobalScope.xml -#, fuzzy msgid "The [Navigation2DServer] singleton." -msgstr "[TranslationServer]å•例。" +msgstr "[Navigation2DServer] å•例。" #: doc/classes/@GlobalScope.xml -#, fuzzy msgid "The [NavigationMeshGenerator] singleton." -msgstr "[EditorNavigationMeshGenerator] å•例。" +msgstr "[NavigationMeshGenerator] å•例。" #: doc/classes/@GlobalScope.xml -#, fuzzy msgid "The [NavigationServer] singleton." -msgstr "[TranslationServer]å•例。" +msgstr "[NavigationServer] å•例。" #: doc/classes/@GlobalScope.xml msgid "The [OS] singleton." @@ -2286,7 +2298,7 @@ msgstr "[ProjectSettings] å•例。" #: doc/classes/@GlobalScope.xml msgid "The [ResourceLoader] singleton." -msgstr "[ResourceLoader]å•例。" +msgstr "[ResourceLoader] å•例。" #: doc/classes/@GlobalScope.xml msgid "The [ResourceSaver] singleton." @@ -2298,7 +2310,7 @@ msgstr "[Time] å•例。" #: doc/classes/@GlobalScope.xml msgid "The [TranslationServer] singleton." -msgstr "[TranslationServer]å•例。" +msgstr "[TranslationServer] å•例。" #: doc/classes/@GlobalScope.xml msgid "The [VisualScriptEditor] singleton." @@ -3543,8 +3555,13 @@ msgid "Gamepad button 22." msgstr "æ¸¸æˆæ‰‹æŸ„按钮22。" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." -msgstr "代表支æŒçš„æ“çºµæ†æŒ‰é’®çš„æœ€å¤§æ•°é‡ã€‚" +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." +msgstr "" #: doc/classes/@GlobalScope.xml msgid "DualShock circle button." @@ -3779,30 +3796,34 @@ msgid "" "MIDI note OFF message. See the documentation of [InputEventMIDI] for " "information of how to use MIDI inputs." msgstr "" +"MIDI 音符 OFF 消æ¯ã€‚如何使用 MIDI 输入的信æ¯è¯·å‚阅 [InputEventMIDI] 的文档。" #: doc/classes/@GlobalScope.xml msgid "" "MIDI note ON message. See the documentation of [InputEventMIDI] for " "information of how to use MIDI inputs." msgstr "" +"MIDI 音符 ON 消æ¯ã€‚如何使用 MIDI 输入的信æ¯è¯·å‚阅 [InputEventMIDI] 的文档。" #: doc/classes/@GlobalScope.xml msgid "" "MIDI aftertouch message. This message is most often sent by pressing down on " "the key after it \"bottoms out\"." -msgstr "" +msgstr "MIDI è§¦åŽæ¶ˆæ¯ã€‚这个消æ¯ç»å¸¸éƒ½æ˜¯åœ¨æŒ‰é”®â€œç»“æŸâ€åŽç»§ç»æ–½åŽ‹æ—¶å‘é€ã€‚" #: doc/classes/@GlobalScope.xml msgid "" "MIDI control change message. This message is sent when a controller value " "changes. Controllers include devices such as pedals and levers." msgstr "" +"MIDI 控制å˜åŒ–消æ¯ã€‚这个消æ¯ä¼šåœ¨æŽ§åˆ¶å™¨å€¼å‘生å˜åŒ–æ—¶å‘é€ã€‚æŽ§åˆ¶å™¨åŒ…æ‹¬è¸æ¿ã€æŽ¨æ†ç‰" +"设备。" #: doc/classes/@GlobalScope.xml msgid "" "MIDI program change message. This message sent when the program patch number " "changes." -msgstr "" +msgstr "MIDI 音色å˜åŒ–消æ¯ã€‚这个消æ¯ä¼šåœ¨éŸ³è‰² Patch å·å˜åŒ–æ—¶å‘é€ã€‚" #: doc/classes/@GlobalScope.xml msgid "" @@ -3810,74 +3831,83 @@ msgid "" "down on the key after it \"bottoms out\". This message is different from " "polyphonic after-touch as it indicates the highest pressure across all keys." msgstr "" +"MIDI 通é“压力消æ¯ã€‚这个消æ¯ç»å¸¸éƒ½æ˜¯åœ¨æŒ‰é”®â€œç»“æŸâ€åŽç»§ç»æ–½åŽ‹æ—¶å‘é€ã€‚这个消æ¯ä¸Žå¤" +"音触åŽä¸åŒï¼Œå› 为它表示的是所有键ä¸çš„æœ€å¤§åŽ‹åŠ›ã€‚" #: doc/classes/@GlobalScope.xml msgid "" "MIDI pitch bend message. This message is sent to indicate a change in the " "pitch bender (wheel or lever, typically)." msgstr "" +"MIDI 弯音消æ¯ã€‚å‘é€è¿™ä¸ªæ¶ˆæ¯è¡¨ç¤ºå¼¯éŸ³å™¨ï¼ˆä¸€èˆ¬æ˜¯å¼¯éŸ³è½®æˆ–推æ†ï¼‰äº§ç”Ÿäº†å˜åŒ–。" #: doc/classes/@GlobalScope.xml msgid "" "MIDI system exclusive message. This has behavior exclusive to the device " "you're receiving input from. Getting this data is not implemented in Godot." msgstr "" +"MIDI 系统专有消æ¯ã€‚è¡Œä¸ºç”±ä½ æ‰€ç”¨æ¥èŽ·å–输入的设备专有。Godot 未实现该数æ®çš„获" +"å–。" #: doc/classes/@GlobalScope.xml msgid "" "MIDI quarter frame message. Contains timing information that is used to " "synchronize MIDI devices. Getting this data is not implemented in Godot." msgstr "" +"MIDI 四分帧消æ¯ã€‚包å«ç”¨äºŽåŒæ¥ MIDI 设备的时间信æ¯ã€‚Godot 未实现该数æ®çš„获å–。" #: doc/classes/@GlobalScope.xml msgid "" "MIDI song position pointer message. Gives the number of 16th notes since the " "start of the song. Getting this data is not implemented in Godot." msgstr "" +"MIDI æŒæ›²ä½ç½®æŒ‡é’ˆæ¶ˆæ¯ã€‚æä¾›è‡ªæŒæ›²å¼€å§‹ä»¥æ¥æ‰€ç»è¿‡çš„åå…分音符数。Godot 未实现该" +"æ•°æ®çš„获å–。" #: doc/classes/@GlobalScope.xml msgid "" "MIDI song select message. Specifies which sequence or song is to be played. " "Getting this data is not implemented in Godot." -msgstr "" +msgstr "MIDI æŒæ›²é€‰æ‹©æ¶ˆæ¯ã€‚æŒ‡å®šè¦æ’放的åºåˆ—æˆ–æŒæ›²ã€‚Godot 未实现该数æ®çš„获å–。" #: doc/classes/@GlobalScope.xml msgid "" "MIDI tune request message. Upon receiving a tune request, all analog " "synthesizers should tune their oscillators." -msgstr "" +msgstr "MIDI 调整请求消æ¯ã€‚收到调整请求åŽï¼Œæ‰€æœ‰æ¨¡æ‹Ÿåˆæˆå™¨éƒ½åº”该调整其晶振。" #: doc/classes/@GlobalScope.xml msgid "" "MIDI timing clock message. Sent 24 times per quarter note when " "synchronization is required." -msgstr "" +msgstr "MIDI 时钟消æ¯ã€‚需è¦åŒæ¥æ—¶ï¼Œæ¯å››åˆ†éŸ³ç¬¦ä¼šå‘é€ 24 次。" #: doc/classes/@GlobalScope.xml msgid "" "MIDI start message. Start the current sequence playing. This message will be " "followed with Timing Clocks." -msgstr "" +msgstr "MIDI 开始消æ¯ã€‚开始当å‰åºåˆ—çš„æ’æ”¾ã€‚这个消æ¯åŽä¼šè·Ÿéšæ—¶é’Ÿæ¶ˆæ¯ã€‚" #: doc/classes/@GlobalScope.xml msgid "MIDI continue message. Continue at the point the sequence was stopped." -msgstr "" +msgstr "MIDI ç»§ç»æ¶ˆæ¯ã€‚从åºåˆ—åœæ¢çš„ä½ç½®ç»§ç»ã€‚" #: doc/classes/@GlobalScope.xml msgid "MIDI stop message. Stop the current sequence." -msgstr "" +msgstr "MIDI åœæ¢æ¶ˆæ¯ã€‚åœæ¢å½“å‰åºåˆ—。" #: doc/classes/@GlobalScope.xml msgid "" "MIDI active sensing message. This message is intended to be sent repeatedly " "to tell the receiver that a connection is alive." -msgstr "" +msgstr "MIDI 活跃感知消æ¯ã€‚这个消æ¯çš„目的是è¦é‡å¤å‘é€ï¼Œå‘ŠçŸ¥æŽ¥æ”¶æ–¹è¿žæŽ¥ä»å˜åœ¨ã€‚" #: doc/classes/@GlobalScope.xml msgid "" "MIDI system reset message. Reset all receivers in the system to power-up " "status. It should not be sent on power-up itself." msgstr "" +"MIDI 系统é‡ç½®æ¶ˆæ¯ã€‚将系统ä¸çš„æ‰€æœ‰æŽ¥æ”¶æ–¹é‡ç½®ä¸ºä¸Šç”µçжæ€ã€‚本身ä¸åº”在上电时å‘é€ã€‚" #: doc/classes/@GlobalScope.xml msgid "" @@ -4579,13 +4609,12 @@ msgid "Axis-Aligned Bounding Box." msgstr "轴对é½åŒ…围盒。" #: doc/classes/AABB.xml +#, fuzzy msgid "" "[AABB] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -4977,10 +5006,10 @@ msgid "" "[b]Note:[/b] This function only makes sense when the context is started with " "[constant MODE_CBC_ENCRYPT] or [constant MODE_CBC_DECRYPT]." msgstr "" -"èŽ·å–æ¤ä¸Šä¸‹æ–‡çš„当å‰IV状æ€ï¼ˆè°ƒç”¨[method update]时会更新IV)。通常ä¸éœ€è¦æ¤å‡½" -"数。\n" -"[b]注æ„:[/b]仅当上下文以[constant MODE_CBC_ENCRYPT]或[constant " -"MODE_CBC_DECRYPT]开头时,æ¤å‡½æ•°æ‰æœ‰æ„义。" +"èŽ·å–æ¤ä¸Šä¸‹æ–‡çš„å½“å‰ IV 状æ€ï¼ˆè°ƒç”¨ [method update] 时会更新 IV)。通常ä¸éœ€è¦æ¤" +"函数。\n" +"[b]注æ„:[/b]仅当上下文以 [constant MODE_CBC_ENCRYPT] 或 [constant " +"MODE_CBC_DECRYPT] 开头时,æ¤å‡½æ•°æ‰æœ‰æ„义。" #: doc/classes/AESContext.xml msgid "" @@ -7111,8 +7140,8 @@ msgid "" "animation plays at normal speed. If it's 0.5, then it plays at half speed. " "If it's 2, then it plays at double speed." msgstr "" -"速度缩放比。例如,如果这个值是1,那么动画以æ£å¸¸é€Ÿåº¦æ’放。如果是0.5,则以åŠé€Ÿ" -"æ’æ”¾ã€‚如果是2,则以åŒå€é€Ÿåº¦æ’放。" +"速度缩放比。例如,如果这个值是 1,那么动画以æ£å¸¸é€Ÿåº¦æ’放。如果是 0.5,则以åŠ" +"é€Ÿæ’æ”¾ã€‚如果是 2,则以åŒå€é€Ÿåº¦æ’放。" #: doc/classes/AnimationPlayer.xml msgid "" @@ -10991,7 +11020,7 @@ msgid "" "Two tap delay and feedback options." msgstr "" "ä¸ºéŸ³é¢‘æ€»çº¿æ·»åŠ å»¶è¿ŸéŸ³é¢‘æ•ˆæžœã€‚åœ¨ä¸€æ®µæ—¶é—´åŽå›žæ”¾è¾“入信å·ã€‚\n" -"两个阀值延迟和å馈选项。" +"两个节æ‹å»¶è¿Ÿå’Œå馈选项。" #: doc/classes/AudioEffectDelay.xml msgid "" @@ -11088,7 +11117,7 @@ msgstr "$DOCS_URL/tutorials/audio/audio_buses.html" #: doc/classes/AudioEffectDistortion.xml msgid "Distortion power. Value can range from 0 to 1." -msgstr "失真度。值的范围å¯åœ¨0到1之间。" +msgstr "失真度。值的范围å¯åœ¨ 0 到 1 之间。" #: doc/classes/AudioEffectDistortion.xml msgid "" @@ -11550,15 +11579,19 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "表示[enum FFT_Size]枚举的大å°ã€‚" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +#, fuzzy +msgid "Audio effect used for recording the sound from an audio bus." msgstr "用于录制æ¥è‡ªéº¦å…‹é£Žçš„声音的音频效果。" #: doc/classes/AudioEffectRecord.xml +#, fuzzy msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" "å…许用户录制æ¥è‡ªéº¦å…‹é£Žçš„声音。它设置和获å–è®°å½•éŸ³é¢‘æ–‡ä»¶çš„æ ¼å¼ï¼ˆ8ä½ï¼Œ16使ˆ–压" "缩)。它检查录音是å¦å¤„于活动状æ€ï¼Œå¦‚果是,则记录声音。然åŽè¿”å›žè®°å½•çš„æ ·æœ¬ã€‚" @@ -14766,7 +14799,6 @@ msgid "" msgstr "通过相机æºï¼Œæ‚¨å¯ä»¥è®¿é—®è¿žæŽ¥åˆ°è®¾å¤‡çš„å•个物ç†ç›¸æœºã€‚" #: doc/classes/CameraFeed.xml -#, fuzzy msgid "" "A camera feed gives you access to a single physical camera attached to your " "device. When enabled, Godot will start capturing frames from the camera " @@ -14777,9 +14809,9 @@ msgid "" "background." msgstr "" "通过相机æºï¼Œä½ å¯ä»¥è®¿é—®è¿žæŽ¥åˆ°è®¾å¤‡çš„å•个物ç†ç›¸æœºã€‚å¯ç”¨åŽï¼ŒGodot 将开始从相机æ•" -"获帧,然åŽä½¿ç”¨ã€‚\n" -"[b]注æ„:[/b]很多相机会返回YCbCr图åƒï¼Œè¿™äº›å›¾åƒè¢«åˆ†æˆä¸¤ä¸ªçº¹ç†ï¼Œéœ€è¦åœ¨ç€è‰²å™¨ä¸" -"组åˆã€‚å¦‚æžœä½ å°†çŽ¯å¢ƒè®¾ç½®ä¸ºåœ¨èƒŒæ™¯ä¸æ˜¾ç¤ºç›¸æœºå›¾åƒï¼ŒGodot ä¼šè‡ªåŠ¨ä¸ºå°†æ‰§è¡Œæ¤æ“作。" +"获帧,然åŽä½¿ç”¨ã€‚å¦è¯·å‚阅 [CameraServer]。\n" +"[b]注æ„:[/b]很多相机会返回 YCbCr 图åƒï¼Œè¿™äº›å›¾åƒè¢«åˆ†æˆä¸¤ä¸ªçº¹ç†ï¼Œéœ€è¦åœ¨ç€è‰²å™¨" +"ä¸ç»„åˆã€‚å¦‚æžœä½ å°†çŽ¯å¢ƒè®¾ç½®ä¸ºåœ¨èƒŒæ™¯ä¸æ˜¾ç¤ºç›¸æœºå›¾åƒï¼ŒGodot ä¼šè‡ªåŠ¨ä¸ºå°†æ‰§è¡Œæ¤æ“作。" #: doc/classes/CameraFeed.xml msgid "Returns the unique ID for this feed." @@ -14836,7 +14868,6 @@ msgid "Server keeping track of different cameras accessible in Godot." msgstr "æœåŠ¡å™¨è·Ÿè¸ª Godot ä¸å¯è®¿é—®çš„ä¸åŒæ‘„åƒå¤´ã€‚" #: doc/classes/CameraServer.xml -#, fuzzy msgid "" "The [CameraServer] keeps track of different cameras accessible in Godot. " "These are external cameras such as webcams or the cameras on your phone.\n" @@ -14844,42 +14875,39 @@ msgid "" "[b]Note:[/b] This class is currently only implemented on macOS and iOS. On " "other platforms, no [CameraFeed]s will be available." msgstr "" -"[CameraServer]记录了Godotä¸å¯è®¿é—®çš„ä¸åŒæ‘„åƒæœºã€‚è¿™äº›æ˜¯å¤–éƒ¨æ‘„åƒæœºï¼Œå¦‚ç½‘ç»œæ‘„åƒæœº" -"æˆ–æ‰‹æœºä¸Šçš„æ‘„åƒæœºã€‚\n" -"它主è¦ç”¨äºŽä¸ºARæ¨¡å—æä¾›æ¥è‡ªæ‘„åƒæœºçš„视频资料。" +"[CameraServer] 记录了 Godot ä¸å¯è®¿é—®çš„ä¸åŒæ‘„åƒæœºã€‚è¿™äº›æ˜¯å¤–éƒ¨æ‘„åƒæœºï¼Œå¦‚网络摄" +"åƒå¤´æˆ–æ‰‹æœºä¸Šçš„æ‘„åƒæœºã€‚\n" +"它主è¦ç”¨äºŽä¸º AR æ¨¡å—æä¾›æ¥è‡ªæ‘„åƒæœºçš„视频æºã€‚\n" +"[b]注æ„:[/b]这个类目å‰åªåœ¨ macOS å’Œ iOS 上实现。在其他平å°ä¸Šæ²¡æœ‰å¯ç”¨çš„ " +"[CameraFeed]。" #: doc/classes/CameraServer.xml -#, fuzzy msgid "Adds the camera [code]feed[/code] to the camera server." -msgstr "å°†ç›¸æœºæºæ·»åŠ åˆ°ç›¸æœºæœåŠ¡ã€‚" +msgstr "å°†ç›¸æœºæº [code]feed[/code] æ·»åŠ åˆ°æ‘„åƒæœºæœåС噍ä¸ã€‚" #: doc/classes/CameraServer.xml msgid "Returns an array of [CameraFeed]s." msgstr "返回一个 [CameraFeed] 数组。" #: doc/classes/CameraServer.xml -#, fuzzy msgid "" "Returns the [CameraFeed] corresponding to the camera with the given " "[code]index[/code]." -msgstr "返回带有给定[code]id[/code]的项的索引。" +msgstr "返回与给定索引 [code]index[/code] çš„æ‘„åƒæœºå¯¹åº”çš„ [CameraFeed]。" #: doc/classes/CameraServer.xml msgid "Returns the number of [CameraFeed]s registered." msgstr "返回注册的 [CameraFeed] 的数é‡ã€‚" #: doc/classes/CameraServer.xml -#, fuzzy msgid "Removes the specified camera [code]feed[/code]." -msgstr "移除索引[code]idx[/code]处的项目。" +msgstr "ç§»é™¤æŒ‡å®šçš„ç›¸æœºæº [code]feed[/code]。" #: doc/classes/CameraServer.xml -#, fuzzy msgid "Emitted when a [CameraFeed] is added (e.g. a webcam is plugged in)." msgstr "å½“æ·»åŠ [CameraFeed] 时触å‘(例如,æ’入网络摄åƒå¤´ï¼‰ã€‚" #: doc/classes/CameraServer.xml -#, fuzzy msgid "Emitted when a [CameraFeed] is removed (e.g. a webcam is unplugged)." msgstr "当移除 [CameraFeed] 时触å‘(例如,拔掉网络摄åƒå¤´ï¼‰ã€‚" @@ -14888,10 +14916,8 @@ msgid "The RGBA camera image." msgstr "RGBA 相机图åƒã€‚" #: doc/classes/CameraServer.xml -#, fuzzy msgid "The [url=https://en.wikipedia.org/wiki/YCbCr]YCbCr[/url] camera image." -msgstr "" -"使用 [url=https://en.wikipedia.org/wiki/DEFLATE]DEFLATE[/url] 压缩方法。" +msgstr "[url=https://zh.wikipedia.org/zh-cn/YCbCr]YCbCr[/url] æ‘„åƒæœºå›¾åƒã€‚" #: doc/classes/CameraServer.xml msgid "The Y component camera image." @@ -14996,13 +15022,13 @@ msgid "" msgstr "引擎调用的å¯è¦†ç›–函数(如果定义了)æ¥ç»˜åˆ¶ç”»å¸ƒé¡¹ç›®ã€‚" #: doc/classes/CanvasItem.xml -#, fuzzy msgid "" "Draws a unfilled arc between the given angles. The larger the value of " "[code]point_count[/code], the smoother the curve. See also [method " "draw_circle]." msgstr "" -"在给定的角度之间画一æ¡å¼§çº¿ã€‚[code]point_count[/code] 的值越大,曲线越平滑。" +"在给定的角度之间绘制未填充的弧线。[code]point_count[/code] 的值越大,曲线越平" +"滑。å¦è¯·å‚阅 [method draw_circle]。" #: doc/classes/CanvasItem.xml msgid "" @@ -15017,33 +15043,35 @@ msgid "" "Draws a colored, unfilled circle. See also [method draw_arc], [method " "draw_polyline] and [method draw_polygon]." msgstr "" +"ç»˜åˆ¶ä¸€ä¸ªå½©è‰²ã€æœªå¡«å……的圆。å¦è¯·å‚阅 [method draw_arc]ã€[method " +"draw_polyline]ã€[method draw_polygon]。" #: doc/classes/CanvasItem.xml -#, fuzzy msgid "" "Draws a colored polygon of any amount of points, convex or concave. Unlike " "[method draw_polygon], a single color must be specified for the whole " "polygon." -msgstr "ç»˜åˆ¶ä»»æ„æ•°é‡ç‚¹çš„彩色多边形,凸或凹。" +msgstr "" +"ç»˜åˆ¶ç”±ä»»æ„æ•°é‡çš„点构æˆçš„彩色多边形,å¯ä»¥æ˜¯å‡¸å¤šè¾¹å½¢ä¹Ÿå¯ä»¥æ˜¯å‡¹å¤šè¾¹å½¢ã€‚与 " +"[method draw_polygon] ä¸åŒï¼Œåªèƒ½ä¸ºæ•´ä¸ªå¤šè¾¹å½¢å¿…须指定å•一颜色。" #: doc/classes/CanvasItem.xml -#, fuzzy msgid "" "Draws a line from a 2D point to another, with a given color and width. It " "can be optionally antialiased. See also [method draw_multiline] and [method " "draw_polyline]." msgstr "" -"绘制一æ¡ä»Ž 2D 点到å¦ä¸€ä¸ªç‚¹çš„线,具有给定的颜色和宽度。它å¯ä»¥é€‰æ‹©æŠ—锯齿。" +"使用给定的颜色和宽度,绘制一æ¡ä»Žä¸€ä¸ª 2D 点到å¦ä¸€ä¸ªç‚¹çš„直线。还å¯ä»¥é€‰æ‹©æŠ—锯" +"齿。å¦è¯·å‚阅 [method draw_multiline] å’Œ [method draw_polyline]。" #: doc/classes/CanvasItem.xml msgid "" "Draws a [Mesh] in 2D, using the provided texture. See [MeshInstance2D] for " "related documentation." msgstr "" -"使用所æä¾›çš„纹ç†ä»¥2Dæ–¹å¼ç»˜åˆ¶ä¸€ä¸ª[Mesh]。相关文档请å‚阅[MeshInstance2D]。" +"使用所æä¾›çš„纹ç†ä»¥ 2D æ–¹å¼ç»˜åˆ¶ä¸€ä¸ª [Mesh]。相关文档请å‚阅 [MeshInstance2D]。" #: doc/classes/CanvasItem.xml -#, fuzzy msgid "" "Draws multiple disconnected lines with a uniform [code]color[/code]. When " "drawing large amounts of lines, this is faster than using individual [method " @@ -15052,13 +15080,13 @@ msgid "" "[b]Note:[/b] [code]width[/code] and [code]antialiased[/code] are currently " "not implemented and have no effect." msgstr "" -"以 uniform çš„ [code]width[/code] å’Œé€æ®µç€è‰²ç»˜åˆ¶å¤šæ¡å¹³è¡Œçº¿ã€‚分é…给线段的颜色" -"按 [code]points[/code] å’Œ [code]colors[/code] 之间的索引匹é…。\n" -"[b]注æ„:[/b][code]width[/code] å’Œ [code]antialiased[/code] ç›®å‰æ²¡æœ‰å®žçŽ°ï¼Œæ²¡" -"有效果。" +"使用å•一颜色 [code]color[/code] 绘制多æ¡ä¸ç›¸è¿žçš„直线。绘制大é‡ç›´çº¿æ—¶ï¼Œæ¯”å•独" +"调用 [method draw_line] è¦å¿«ã€‚è¦ç»˜åˆ¶ç›¸è¿žçš„直线,请æ¢ç”¨ [method " +"draw_polyline]。\n" +"[b]注æ„:[/b]ç›®å‰æœªå®žçް [code]width[/code] å’Œ [code]antialiased[/code],没有" +"效果。" #: doc/classes/CanvasItem.xml -#, fuzzy msgid "" "Draws multiple disconnected lines with a uniform [code]width[/code] and " "segment-by-segment coloring. Colors assigned to line segments match by index " @@ -15069,10 +15097,12 @@ msgid "" "[b]Note:[/b] [code]width[/code] and [code]antialiased[/code] are currently " "not implemented and have no effect." msgstr "" -"以 uniform çš„ [code]width[/code] å’Œé€æ®µç€è‰²ç»˜åˆ¶å¤šæ¡å¹³è¡Œçº¿ã€‚分é…给线段的颜色" -"按 [code]points[/code] å’Œ [code]colors[/code] 之间的索引匹é…。\n" -"[b]注æ„:[/b][code]width[/code] å’Œ [code]antialiased[/code] ç›®å‰æ²¡æœ‰å®žçŽ°ï¼Œæ²¡" -"有效果。" +"使用å•一宽度 [code]width[/code] 绘制多æ¡ä¸ç›¸è¿žçš„直线,ä¸åŒçº¿æ®µé¢œè‰²å¯ä»¥ä¸åŒã€‚" +"线段的颜色使用 [code]points[/code] å’Œ [code]colors[/code] 的索引进行匹é…。绘" +"制大é‡ç›´çº¿æ—¶ï¼Œæ¯”å•独调用 [method draw_line] è¦å¿«ã€‚è¦ç»˜åˆ¶ç›¸è¿žçš„直线,请æ¢ç”¨ " +"[method draw_polyline_colors]。\n" +"[b]注æ„:[/b]ç›®å‰æœªå®žçް [code]width[/code] å’Œ [code]antialiased[/code],没有" +"效果。" #: doc/classes/CanvasItem.xml msgid "" @@ -15089,6 +15119,9 @@ msgid "" "individually. See also [method draw_polyline] and [method " "draw_polyline_colors]." msgstr "" +"ç»˜åˆ¶ç”±ä»»æ„æ•°é‡çš„点构æˆçš„实心多边形,å¯ä»¥æ˜¯å‡¸å¤šè¾¹å½¢ä¹Ÿå¯ä»¥æ˜¯å‡¹å¤šè¾¹å½¢ã€‚与 " +"[method draw_colored_polygon] ä¸åŒï¼Œæ¯ä¸ªç‚¹çš„颜色都å¯ä»¥å•独修改。å¦è¯·å‚阅 " +"[method draw_polyline] å’Œ [method draw_polyline_colors]。" #: doc/classes/CanvasItem.xml msgid "" @@ -15098,9 +15131,12 @@ msgid "" "draw disconnected lines, use [method draw_multiline] instead. See also " "[method draw_polygon]." msgstr "" +"使用å•一颜色 [code]color[/code] 和宽度 [code]width[/code] 绘制多æ¡ç›¸è¿žçš„线" +"段,还å¯ä»¥é€‰æ‹©æŠ—锯齿。绘制大é‡ç›´çº¿æ—¶ï¼Œæ¯”å•独调用 [method draw_line] è¦å¿«ã€‚è¦" +"绘制ä¸ç›¸è¿žçš„直线,请æ¢ç”¨ [method draw_multiline]。å¦è¯·å‚阅 [method " +"draw_polygon]。" #: doc/classes/CanvasItem.xml -#, fuzzy msgid "" "Draws interconnected line segments with a uniform [code]width[/code] and " "segment-by-segment coloring, and optional antialiasing. Colors assigned to " @@ -15109,8 +15145,10 @@ msgid "" "individual [method draw_line] calls. To draw disconnected lines, use [method " "draw_multiline_colors] instead. See also [method draw_polygon]." msgstr "" -"以uniformçš„[code]width[/code]ç»˜åˆ¶ç›¸äº’è¿žæŽ¥çš„çº¿æ®µï¼Œé€æ®µç€è‰²ï¼Œå¯é€‰æŠ—锯齿。分é…ç»™" -"线段的颜色通过[code]points[/code]å’Œ[code]colors[/code]之间的索引进行匹é…。" +"使用å•一宽度 [code]width[/code] 绘制多æ¡ç›¸è¿žçš„直线,ä¸åŒçº¿æ®µé¢œè‰²å¯ä»¥ä¸åŒã€‚线" +"段的颜色使用 [code]points[/code] å’Œ [code]colors[/code] 的索引进行匹é…。绘制" +"大é‡ç›´çº¿æ—¶ï¼Œæ¯”å•独调用 [method draw_line] è¦å¿«ã€‚è¦ç»˜åˆ¶ä¸ç›¸è¿žçš„直线,请æ¢ç”¨ " +"[method draw_multiline_colors]。å¦è¯·å‚阅 [method draw_polygon]。" #: doc/classes/CanvasItem.xml msgid "" @@ -15120,6 +15158,10 @@ msgid "" "See also [method draw_line], [method draw_polyline], [method draw_polygon], " "and [method draw_rect]." msgstr "" +"绘制自定义图元。1 个点的是个点,2 个点的是线段,3 个点的是三角形,4 个点的是" +"四边形。如果没有指定点或者指定了超过 4 个点,则ä¸ä¼šç»˜åˆ¶ä»»ä½•东西,åªä¼šè¾“出错误" +"消æ¯ã€‚å¦è¯·å‚阅 [method draw_line]ã€[method draw_polyline]ã€[method " +"draw_polygon]ã€[method draw_rect]。" #: doc/classes/CanvasItem.xml msgid "" @@ -15262,11 +15304,12 @@ msgid "Returns the [World2D] where this item is in." msgstr "返回æ¤ç‰©å“所在的[World2D]。" #: doc/classes/CanvasItem.xml -#, fuzzy msgid "" "Hide the [CanvasItem] if it's currently visible. This is equivalent to " "setting [member visible] to [code]false[/code]." -msgstr "清空数组。与调用 [method resize] 时指定大å°ä¸º [code]0[/code] ç‰ä»·ã€‚" +msgstr "" +"如果该 [CanvasItem] ç›®å‰æ˜¯å¯è§çš„,则将其éšè—。ç‰ä»·äºŽå°† [member visible] 设为 " +"[code]false[/code]。" #: doc/classes/CanvasItem.xml msgid "" @@ -15331,15 +15374,15 @@ msgstr "" "如果[code]enable[/code]为[code]true[/code]ï¼Œåˆ™å°†ä½¿ç”¨å…¨å±€å˜æ¢æ•°æ®æ›´æ–°å项。" #: doc/classes/CanvasItem.xml -#, fuzzy msgid "" "Show the [CanvasItem] if it's currently hidden. This is equivalent to " "setting [member visible] to [code]true[/code]. For controls that inherit " "[Popup], the correct way to make them visible is to call one of the multiple " "[code]popup*()[/code] functions instead." msgstr "" -"如果[CanvasItem]当剿˜¯éšè—的,则显示它。对于继承[Popup]的控件,使其å¯è§çš„æ£ç¡®" -"方法是调用多个[code]popup*()[/code]函数ä¸çš„一个æ¥ä»£æ›¿ã€‚" +"如果该 [CanvasItem] ç›®å‰æ˜¯éšè—的,则将其显示。ç‰ä»·äºŽå°† [member visible] 设为 " +"[code]true[/code]。对于继承自 [Popup] 的控件,让它们å¯è§çš„æ£ç¡®åšæ³•æ˜¯æ¢æˆè°ƒç”¨" +"å„ç§ [code]popup*()[/code] 函数的其ä¸ä¹‹ä¸€ã€‚" #: doc/classes/CanvasItem.xml msgid "" @@ -15581,8 +15624,8 @@ msgid "" "above), or backgrounds (in layer -1 or below)." msgstr "" "画布绘图层。[CanvasLayer] 的直接或间接å级的 [CanvasItem] 节点将在该层ä¸ç»˜" -"制。该层是一个数å—索引,用于定义绘制顺åºã€‚默认 2D 场景的渲染索引为 0ï¼Œå› æ¤ç´¢" -"引为 -1 çš„ [CanvasLayer] 会在其下方绘制,索引为 1 的则会在其上方绘制。这对于 " +"制。层是一个决定绘制顺åºçš„æ•°å—索引。默认 2D 场景的渲染索引为 0ï¼Œå› æ¤ç´¢å¼•为 " +"-1 çš„ [CanvasLayer] 会在其下方绘制,索引为 1 的则会在其上方绘制。这对于 " "HUD(在 1+ 层或更高层ä¸ï¼‰æˆ–背景(在 -1 层或更低层ä¸ï¼‰éžå¸¸æœ‰ç”¨ã€‚" #: doc/classes/CanvasLayer.xml @@ -15703,13 +15746,15 @@ msgstr "使å级控件居ä¸ã€‚" msgid "" "CenterContainer keeps children controls centered. This container keeps all " "children to their minimum size, in the center." -msgstr "CenterContainer使å节点居ä¸ã€‚该容器将所有åèŠ‚ç‚¹ä¿æŒåœ¨æœ€å°å°ºå¯¸çš„ä¸é—´ã€‚" +msgstr "" +"CenterContainer 会使å节点居ä¸ã€‚该容器会将所有åèŠ‚ç‚¹ä¿æŒåœ¨æœ€å°å°ºå¯¸å¹¶å±…ä¸ã€‚" #: doc/classes/CenterContainer.xml msgid "" "If [code]true[/code], centers children relative to the [CenterContainer]'s " "top left corner." -msgstr "如果[code]true[/code],将å节点相对于[CenterContainer]的左上角居ä¸ã€‚" +msgstr "" +"如果为 [code]true[/code],会将å节点相对于 [CenterContainer] 的左上角居ä¸ã€‚" #: doc/classes/CharFXTransform.xml msgid "" @@ -15735,11 +15780,12 @@ msgstr "" "https://github.com/Eoin-ONeill-Yokai/Godot-Rich-Text-Effect-Test-Project" #: doc/classes/CharFXTransform.xml -#, fuzzy msgid "" "The index of the current character (starting from 0) for the " "[RichTextLabel]'s BBCode text. Setting this property won't affect drawing." -msgstr "当å‰å—符的索引(从0开始)。设置æ¤å±žæ€§ä¸ä¼šå½±å“图形。" +msgstr "" +"该 [RichTextLabel] çš„ BBCode 文本ä¸å½“å‰å—符的索引å·ï¼ˆä»Ž 0 开始)。设置该属性" +"ä¸ä¼šå½±å“绘制。" #: doc/classes/CharFXTransform.xml msgid "" @@ -15807,11 +15853,12 @@ msgid "The position offset the character will be drawn with (in pixels)." msgstr "绘制å—符的ä½ç½®åç§»é‡ï¼ˆä»¥åƒç´ 为å•ä½ï¼‰ã€‚" #: doc/classes/CharFXTransform.xml -#, fuzzy msgid "" "The index of the current character (starting from 0) for this " "[RichTextEffect] custom block. Setting this property won't affect drawing." -msgstr "当å‰å—符的索引(从0开始)。设置æ¤å±žæ€§ä¸ä¼šå½±å“图形。" +msgstr "" +"该 [RichTextEffect] 自定义å—ä¸å½“å‰å—符的索引å·ï¼ˆä»Ž 0 开始)。设置该属性ä¸ä¼šå½±" +"å“绘制。" #: doc/classes/CharFXTransform.xml msgid "" @@ -16527,7 +16574,7 @@ msgid "" msgstr "" "当对象收到未处ç†çš„ [InputEvent] æ—¶å‘出。 [code]position[/code] æ˜¯é¼ æ ‡æŒ‡é’ˆåœ¨å…·" "有索引 [code]shape_idx[/code] 的形状表é¢åœ¨ä¸–界空间ä¸çš„ä½ç½®ï¼Œ[code]normal[/" -"code] 是该点表é¢çš„æ³•å‘é‡." +"code] 是该点表é¢çš„æ³•å‘é‡ã€‚" #: doc/classes/CollisionObject.xml msgid "Emitted when the mouse pointer enters any of this object's shapes." @@ -16890,7 +16937,6 @@ msgid "Color in RGBA format using floats on the range of 0 to 1." msgstr "RGBA æ ¼å¼çš„颜色,使用 0 到 1 范围内的浮点数。" #: doc/classes/Color.xml -#, fuzzy msgid "" "A color represented by red, green, blue, and alpha (RGBA) components. The " "alpha component is often used for opacity. Values are in floating-point and " @@ -16908,9 +16954,9 @@ msgid "" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" "color_constants.png]Color constants cheatsheet[/url]" msgstr "" -"由红ã€ç»¿ã€è“ã€Alpha(RGBA)分é‡è¡¨ç¤ºçš„颜色。Alpha 分é‡é€šå¸¸ç”¨äºŽé€æ˜Žåº¦ã€‚这些值都" -"是浮点数,范围一般在 0 到 1 之间。有些属性(如 CanvasItem.modulate)å¯ä»¥æŽ¥å—" -"大于 1 的值(过亮或 HDR 颜色)。\n" +"由红ã€ç»¿ã€è“ã€Alpha(RGBA)分é‡è¡¨ç¤ºçš„颜色。Alpha 分é‡é€šå¸¸ç”¨äºŽä¸é€æ˜Žåº¦ã€‚这些值" +"都是浮点数,范围一般在 0 到 1 之间。有些属性(如 CanvasItem.modulate)å¯ä»¥æŽ¥" +"å—大于 1 的值(过亮或 HDR 颜色)。\n" "您也å¯ä»¥é€šè¿‡ä½¿ç”¨ [method @GDScript.ColorN] ä»Žæ ‡å‡†åŒ–é¢œè‰²åç§°ä¸åˆ›å»ºé¢œè‰²ï¼Œæˆ–者直" "接使用这里定义的颜色常é‡ã€‚æ ‡å‡†åŒ–é¢œè‰²é›†å–自 [url=https://en.wikipedia.org/" "wiki/X11_color_names]X11 颜色åç§°[/url]。\n" @@ -17268,6 +17314,8 @@ msgid "" "means that the color is fully transparent. A value of 1 means that the color " "is fully opaque." msgstr "" +"颜色的 Alpha 分é‡ï¼Œä¸€èˆ¬åœ¨ 0 到 1 的范围内。0 è¡¨ç¤ºè¯¥é¢œè‰²å®Œå…¨é€æ˜Žã€‚1 表示该颜色" +"完全ä¸é€æ˜Žã€‚" #: doc/classes/Color.xml msgid "Wrapper for [member a] that uses the range 0 to 255 instead of 0 to 1." @@ -17275,7 +17323,7 @@ msgstr "[member a]的包装程åºï¼Œä½¿ç”¨çš„范围是0到255ï¼Œè€Œä¸æ˜¯0到1〠#: doc/classes/Color.xml msgid "The color's blue component, typically on the range of 0 to 1." -msgstr "颜色的è“色分é‡ï¼Œä¸€èˆ¬åœ¨0到1的范围内。" +msgstr "颜色的è“色分é‡ï¼Œä¸€èˆ¬åœ¨ 0 到 1 的范围内。" #: doc/classes/Color.xml msgid "Wrapper for [member b] that uses the range 0 to 255 instead of 0 to 1." @@ -17283,7 +17331,7 @@ msgstr "[member b]çš„å°è£…器,使用0到255çš„èŒƒå›´ï¼Œè€Œä¸æ˜¯0到1。" #: doc/classes/Color.xml msgid "The color's green component, typically on the range of 0 to 1." -msgstr "颜色的绿色分é‡ï¼Œä¸€èˆ¬åœ¨0到1的范围内。" +msgstr "颜色的绿色分é‡ï¼Œä¸€èˆ¬åœ¨ 0 到 1 的范围内。" #: doc/classes/Color.xml msgid "Wrapper for [member g] that uses the range 0 to 255 instead of 0 to 1." @@ -17941,9 +17989,8 @@ msgstr "" "动事件ä¸ä¹Ÿä¼šç«‹å³åº”用(ä¼šé€ æˆæ€§èƒ½é—®é¢˜)。" #: doc/classes/ColorPicker.xml -#, fuzzy msgid "If [code]true[/code], shows an alpha channel slider (opacity)." -msgstr "如果 [code]true[/code],显示 Alpha é€šé“æ»‘å—ï¼ˆé€æ˜Žåº¦ï¼‰ã€‚" +msgstr "如果为 [code]true[/code],则显示 Alpha é€šé“æ»‘动æ¡ï¼ˆä¸é€æ˜Žåº¦ï¼‰ã€‚" #: doc/classes/ColorPicker.xml msgid "" @@ -18843,12 +18890,12 @@ msgstr "" "[method Node._unhandled_input]或[method Node._unhandled_key_input]的节点。" #: doc/classes/Control.xml +#, fuzzy msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -18872,23 +18919,25 @@ msgstr "" "[/codeblock]" #: doc/classes/Control.xml +#, fuzzy msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" -"为指定 [code]name[/code] 的主题常é‡åˆ›å»ºæœ¬åœ°è¦†ç›–é¡¹ã€‚èŽ·å–æŽ§ä»¶çš„ä¸»é¢˜é¡¹æ—¶ï¼Œæœ¬åœ°è¦†" -"ç›–é¡¹å§‹ç»ˆä¼˜å…ˆã€‚æ— æ³•åˆ é™¤è¦†ç›–é¡¹ï¼Œä½†å¯ä»¥ä½¿ç”¨ç›¸åº”的默认值覆盖它。\n" -"å‚阅[method get_constant]。" +"为指定 [code]name[/code] 的主题ç€è‰²å™¨åˆ›å»ºæœ¬åœ°è¦†ç›–é¡¹ã€‚èŽ·å–æŽ§ä»¶çš„ä¸»é¢˜é¡¹æ—¶ï¼Œæœ¬åœ°" +"覆盖项始终优先。å¯ä»¥é€šè¿‡ä¸ºå…¶åˆ†é… [code]null[/code] 值æ¥åˆ 除覆盖。" #: doc/classes/Control.xml +#, fuzzy msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" "使用指定的 [code]name[/code] 为主题 [Font] åˆ›å»ºæœ¬åœ°è¦†ç›–é¡¹ã€‚èŽ·å–æŽ§ä»¶çš„ä¸»é¢˜é¡¹" @@ -18896,11 +18945,14 @@ msgstr "" "å‚阅[method get_font]。" #: doc/classes/Control.xml +#, fuzzy msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" "为指定 [code]name[/code] çš„ä¸»é¢˜å›¾æ ‡åˆ›å»ºæœ¬åœ°è¦†ç›–é¡¹ã€‚èŽ·å–æŽ§ä»¶çš„ä¸»é¢˜é¡¹æ—¶ï¼Œæœ¬åœ°è¦†" @@ -18908,21 +18960,28 @@ msgstr "" "å‚阅[method get_icon]。" #: doc/classes/Control.xml +#, fuzzy msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" -"为指定 [code]name[/code] 的主题ç€è‰²å™¨åˆ›å»ºæœ¬åœ°è¦†ç›–é¡¹ã€‚èŽ·å–æŽ§ä»¶çš„ä¸»é¢˜é¡¹æ—¶ï¼Œæœ¬åœ°" -"覆盖项始终优先。å¯ä»¥é€šè¿‡ä¸ºå…¶åˆ†é… [code]null[/code] 值æ¥åˆ 除覆盖。" +"使用指定的 [code]name[/code] 为主题 [Font] åˆ›å»ºæœ¬åœ°è¦†ç›–é¡¹ã€‚èŽ·å–æŽ§ä»¶çš„ä¸»é¢˜é¡¹" +"时,本地覆盖项始终优先。å¯ä»¥é€šè¿‡ä¸ºå…¶åˆ†é… [code]null[/code] 值æ¥åˆ 除覆盖。\n" +"å‚阅[method get_font]。" #: doc/classes/Control.xml +#, fuzzy msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -19430,6 +19489,39 @@ msgid "" msgstr "æ”¾å¼ƒç„¦ç‚¹ã€‚å…¶ä»–æŽ§ä»¶å°†æ— æ³•æŽ¥æ”¶é”®ç›˜è¾“å…¥ã€‚" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "移除按键[code]name[/code]的动画。" + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "移除按键[code]name[/code]的动画。" + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "移除按键[code]name[/code]的动画。" + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "移除按键[code]name[/code]的动画。" + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "返回带有给定[code]id[/code]的项的索引。" + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "返回带有给定[code]id[/code]的项的索引。" + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -19980,9 +20072,9 @@ msgid "" "[member rect_scale], it will scale around this pivot. Set this property to " "[member rect_size] / 2 to center the pivot in the node's rectangle." msgstr "" -"默认情况下,节点的轴是其左上角。当您更改其[member rect_scale]æ—¶ï¼Œå®ƒå°†å›´ç»•æ¤æž¢" -"轴进行缩放。将æ¤å±žæ€§è®¾ç½®ä¸º[member rect_size] / 2,以将枢轴在节点的矩形ä¸å±…" -"ä¸ã€‚" +"默认情况下,该节点的轴心ä½äºŽå…¶å·¦ä¸Šè§’。当您更改其 [member rect_scale] 时,它将" +"围绕æ¤è½´å¿ƒè¿›è¡Œç¼©æ”¾ã€‚å°†æ¤å±žæ€§è®¾ç½®ä¸º [member rect_size] / 2,以将轴心在节点的矩" +"å½¢ä¸å±…ä¸ã€‚" #: doc/classes/Control.xml msgid "" @@ -19990,16 +20082,16 @@ msgid "" "rectangle's top-left corner. The property is not affected by [member " "rect_pivot_offset]." msgstr "" -"节点相对于其父节点的ä½ç½®ã€‚它对应于矩形的左上角。该属性ä¸å—[member " -"rect_pivot_offset]的影å“。" +"节点相对于其父节点的ä½ç½®ã€‚它对应于矩形的左上角。该属性ä¸å— [member " +"rect_pivot_offset] 的影å“。" #: doc/classes/Control.xml msgid "" "The node's rotation around its pivot, in degrees. See [member " "rect_pivot_offset] to change the pivot's position." msgstr "" -"节点围绕其枢轴的旋转(以度为å•ä½ï¼‰ã€‚请å‚阅[member rect_pivot_offset]更改枢轴" -"çš„ä½ç½®ã€‚" +"节点围绕其轴心的旋转(以度为å•ä½ï¼‰ã€‚更改轴心的ä½ç½®è¯·å‚阅 [member " +"rect_pivot_offset]。" #: doc/classes/Control.xml msgid "" @@ -20108,12 +20200,21 @@ msgstr "" "mouse_entered]。" #: doc/classes/Control.xml +#, fuzzy msgid "" "Emitted when the mouse leaves the control's [code]Rect[/code] area, provided " "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" "å½“é¼ æ ‡ç¦»å¼€æŽ§ä»¶çš„[code]Rect[/code]区域时触å‘,åªè¦å…¶[member mouse_filter]å…许" "事件到达。\n" @@ -20672,6 +20773,8 @@ msgid "" "[method set_point_cloud] to generate a convex hull shape from concave shape " "points." msgstr "" +"è¯¥å¤šè¾¹å½¢çš„é¡¶ç‚¹åˆ—è¡¨ã€‚é¡ºæ—¶é’ˆé¡ºåºæˆ–逆时针顺åºéƒ½æœ‰å¯èƒ½ã€‚请用凸包点设置该属性,å¯" +"以用 [method set_point_cloud] 从凹形状点设æˆå‡¸åŒ…形状。" #: doc/classes/CPUParticles.xml msgid "CPU-based 3D particle emitter." @@ -22226,9 +22329,8 @@ msgstr "" "å¦è¯·å‚阅[GodotSharp]。" #: modules/mono/doc_classes/CSharpScript.xml -#, fuzzy msgid "$DOCS_URL/tutorials/scripting/c_sharp/index.html" -msgstr "$DOCS_URL/tutorials/scripting/index.html" +msgstr "$DOCS_URL/tutorials/scripting/c_sharp/index.html" #: modules/mono/doc_classes/CSharpScript.xml #: modules/gdnative/doc_classes/PluginScript.xml @@ -24245,6 +24347,8 @@ msgid "" "font oversampling, ignoring [member SceneTree.use_font_oversampling] value " "and viewport stretch mode." msgstr "" +"如果设为比 [code]0.0[/code] 大的值,则会覆盖默认的å—ä½“è¿‡é‡‡æ ·ï¼Œå¿½ç•¥ [member " +"SceneTree.use_font_oversampling] çš„å€¼å’Œè§†å£æ‹‰ä¼¸æ¨¡å¼ã€‚" #: doc/classes/DynamicFontData.xml msgid "Disables font hinting (smoother but less crisp)." @@ -24263,7 +24367,6 @@ msgid "A script that is executed when exporting the project." msgstr "在导出项目时执行的脚本。" #: doc/classes/EditorExportPlugin.xml -#, fuzzy msgid "" "[EditorExportPlugin]s are automatically invoked whenever the user exports " "the project. Their most common use is to determine what files are being " @@ -24273,9 +24376,11 @@ msgid "" "To use [EditorExportPlugin], register it using the [method EditorPlugin." "add_export_plugin] method first." msgstr "" -"æ¯å½“用户导出项目时,会自动激活编辑器的导出æ’件。其最常用在确定哪些文件被包å«" -"到导出的项目ä¸ã€‚对于æ¯ä¸ªæ’件,在导出过程开始时调用[method _export_begin],然" -"åŽè°ƒç”¨æ¯ä¸ªå¯¼å‡ºæ–‡ä»¶çš„[method _export_file]。" +"[EditorExportPlugin] 会在用户导出项目时自动调用。它们最常è§çš„用途是确定哪些文" +"件应该包å«åœ¨å¯¼å‡ºçš„项目ä¸ã€‚对于æ¯ä¸ªæ’件,导出过程开始时都会调用 [method " +"_export_begin],然åŽä¼šä¸ºæ¯ä¸€ä¸ªå¯¼å‡ºçš„æ–‡ä»¶è°ƒç”¨ [method _export_file]。\n" +"è¦ä½¿ç”¨ [EditorExportPlugin],请先用 [method EditorPlugin.add_export_plugin] " +"注册。" #: doc/classes/EditorExportPlugin.xml msgid "" @@ -24369,7 +24474,7 @@ msgstr "为iOSå±žæ€§åˆ—è¡¨æ–‡ä»¶æ·»åŠ å†…å®¹ã€‚" #: doc/classes/EditorExportPlugin.xml msgid "Adds a static lib from the given [code]path[/code] to the iOS project." -msgstr "从给定的[code]path[/code]æ·»åŠ é™æ€åº“到iOS项目。" +msgstr "å°†ä½äºŽç»™å®šè·¯å¾„ [code]path[/code] çš„é™æ€åº“æ·»åŠ åˆ° iOS 项目ä¸ã€‚" #: doc/classes/EditorExportPlugin.xml msgid "" @@ -24377,6 +24482,9 @@ msgid "" "directory of macOS app bundle.\n" "[b]Note:[/b] This is useful only for macOS exports." msgstr "" +"将与路径 [code]path[/code] 相匹é…çš„æ–‡ä»¶æˆ–ç›®å½•æ·»åŠ åˆ° macOS App æ†ç»‘包的 " +"[code]PlugIns[/code] 目录ä¸ã€‚\n" +"[b]注æ„:[/b]仅适用于 macOS 导出。" #: doc/classes/EditorExportPlugin.xml msgid "" @@ -24387,6 +24495,11 @@ msgid "" "In case of a directory code-sign will error if you place non code object in " "directory." msgstr "" +"æ·»åŠ å…±äº«å¯¹è±¡æˆ–ä»…åŒ…å«å…±äº«å¯¹è±¡çš„目录,共享对象ä½äºŽ [code]path[/code],需è¦ä¸Žç»™" +"定的 [code]tags[/code] æ ‡ç¾åŒ¹é…。\n" +"[b]注æ„:[/b]使用 macOS å¯¼å‡ºæ—¶ï¼Œè¿™äº›å…±äº«å¯¹è±¡ä¼šè¢«åŠ å…¥åˆ° App æ†ç»‘包的 " +"[code]Frameworkds[/code] 目录。\n" +"å¦‚æžœä½¿ç”¨çš„æ˜¯ç›®å½•ï¼Œå¹¶ä¸”ä½ åœ¨è¯¥ç›®å½•ä¸åŠ å…¥äº†éžä»£ç 对象,则代ç ç¾å时会报错。" #: doc/classes/EditorExportPlugin.xml msgid "" @@ -24897,7 +25010,6 @@ msgstr "" "æºç±»åž‹å¯¼å…¥ã€‚" #: doc/classes/EditorImportPlugin.xml -#, fuzzy msgid "" "[EditorImportPlugin]s provide a way to extend the editor's resource import " "functionality. Use them to import resources from custom files or to provide " @@ -24954,16 +25066,15 @@ msgid "" "To use [EditorImportPlugin], register it using the [method EditorPlugin." "add_import_plugin] method first." msgstr "" -"EditorImportPluginsæä¾›äº†ä¸€ç§æ‰©å±•编辑器资æºå¯¼å…¥åŠŸèƒ½çš„æ–¹æ³•ã€‚ä½¿ç”¨å®ƒä»¬æ¥å¯¼å…¥è‡ªå®š" -"义文件ä¸çš„资æºï¼Œæˆ–æˆä¸ºç¼–辑器现有导入器的替代å“。用[method EditorPlugin." -"add_import_plugin]æ³¨å†Œä½ çš„[EditorPlugin]。\n" -"EditorImportPlugins通过与特定的文件扩展å和资æºç±»åž‹ç›¸å…³è”æ¥å·¥ä½œã€‚å‚阅 " +"[EditorImportPlugin] æä¾›äº†ä¸€ç§æ‰©å±•编辑器资æºå¯¼å…¥åŠŸèƒ½çš„æ–¹æ³•ã€‚ä½¿ç”¨å®ƒä»¬æ¥å¯¼å…¥è‡ª" +"定义文件ä¸çš„资æºï¼Œæˆ–æˆä¸ºç¼–辑器现有导入器的替代å“。\n" +"EditorImportPlugin 通过与特定的文件扩展å和资æºç±»åž‹ç›¸å…³è”æ¥å·¥ä½œã€‚å‚阅 " "[method get_recognized_extensions] å’Œ [method get_resource_type]。其å¯ä»¥é€‰æ‹©" -"性地指定一些影å“导入过程的导入预置。EditorImportPlugins负责创建资æºå¹¶å°†å…¶ä¿å˜" -"在[code].import[/code]目录ä¸ï¼Œå‚阅[member ProjectSettings.application/config/" -"use_hidden_project_data_directory]。\n" -"䏋颿˜¯ä¸€ä¸ªEditorImportPlugin的例å,它从扩展å为 \".special\" 或 \".spec\" çš„" -"文件ä¸å¯¼å…¥ä¸€ä¸ª[Mesh]:\n" +"性地指定一些影å“导入过程的导入预置。EditorImportPlugin 负责创建资æºå¹¶å°†å…¶ä¿å˜" +"在 [code].import[/code] 目录ä¸ï¼Œå‚阅 [member ProjectSettings.application/" +"config/use_hidden_project_data_directory]。\n" +"䏋颿˜¯ä¸€ä¸ª EditorImportPlugin 的例å,它会从扩展å为“.specialâ€æˆ–“.specâ€çš„æ–‡ä»¶" +"ä¸å¯¼å…¥ä¸€ä¸ª [Mesh]:\n" "[codeblock]\n" "tool\n" "extends EditorImportPlugin\n" @@ -24998,12 +25109,13 @@ msgstr "" " return FAILED\n" "\n" " var mesh = Mesh.new()\n" -" # Fill the Mesh with data read in \"file\", left as an exercise to the " -"reader\n" +" # 使用从“fileâ€ä¸è¯»å–的数æ®å¡«å…… Meshï¼Œç•™ä½œè¯»è€…çš„ç»ƒä¹ \n" "\n" " var filename = save_path + \".\" + get_save_extension()\n" " return ResourceSaver.save(filename, mesh)\n" -"[/codeblock]" +"[/codeblock]\n" +"è¦ä½¿ç”¨ä½ çš„ [EditorImportPlugin],请先通过 [method EditorPlugin." +"add_import_plugin] 注册。" #: doc/classes/EditorImportPlugin.xml doc/classes/ResourceImporter.xml msgid "$DOCS_URL/tutorials/plugins/editor/import_plugins.html" @@ -25221,7 +25333,6 @@ msgid "Plugin for adding custom property editors on inspector." msgstr "ç”¨äºŽåœ¨æ£€æŸ¥å™¨ä¸Šæ·»åŠ è‡ªå®šä¹‰å±žæ€§ç¼–è¾‘å™¨çš„æ’件。" #: doc/classes/EditorInspectorPlugin.xml -#, fuzzy msgid "" "[EditorInspectorPlugin] allows adding custom property editors to " "[EditorInspector].\n" @@ -25237,15 +25348,17 @@ msgid "" "To use [EditorInspectorPlugin], register it using the [method EditorPlugin." "add_inspector_plugin] method first." msgstr "" -"该æ’ä»¶å…许å‘[EditorInspector]æ·»åŠ è‡ªå®šä¹‰å±žæ€§ç¼–è¾‘å™¨ã€‚\n" -"æ’件通过[method EditorPlugin.add_inspector_plugin]注册。\n" -"当一个对象被编辑时,[method can_handle]函数被调用,如果支æŒå¯¹è±¡ç±»åž‹ï¼Œå¿…须返回" -"[code]true[/code]。\n" -"如果支æŒï¼Œå‡½æ•°[method parse_begin]将被调用,å…许在类的开头放置自定义控件。\n" -"éšåŽï¼Œè°ƒç”¨æ¯ä¸ªç±»åž‹å’Œå±žæ€§[method parse_category]å’Œ[method parse_property]。其" -"也æä¾›äº†å‘æ£€æŸ¥å™¨æ·»åŠ è‡ªå®šä¹‰æŽ§ä»¶çš„èƒ½åŠ›ã€‚\n" -"最åŽï¼Œè°ƒç”¨[method parse_end]。\n" -"在这些调用ä¸ï¼Œæ¯ä¸€ä¸ªéƒ½å¯ä»¥è°ƒç”¨ \"add\"函数。" +"[EditorInspectorPlugin] å¯ç”¨äºŽå‘ [EditorInspector] æ·»åŠ è‡ªå®šä¹‰å±žæ€§ç¼–è¾‘å™¨ã€‚\n" +"当一个对象被编辑时,[method can_handle] 函数被调用,如果支æŒå¯¹è±¡ç±»åž‹ï¼Œå¿…须返" +"回 [code]true[/code]。\n" +"如果支æŒï¼Œå‡½æ•° [method parse_begin] 将被调用,å…许在类的开头放置自定义控" +"件。\n" +"éšåŽï¼Œè°ƒç”¨æ¯ä¸ªç±»åž‹å’Œå±žæ€§ [method parse_category] å’Œ [method parse_property]。" +"其也æä¾›äº†å‘æ£€æŸ¥å™¨æ·»åŠ è‡ªå®šä¹‰æŽ§ä»¶çš„èƒ½åŠ›ã€‚\n" +"最åŽï¼Œè°ƒç”¨ [method parse_end]。\n" +"在这些调用ä¸ï¼Œæ¯ä¸€ä¸ªéƒ½å¯ä»¥è°ƒç”¨â€œaddâ€å‡½æ•°ã€‚\n" +"è¦ä½¿ç”¨ [EditorInspectorPlugin],请先通过 [method EditorPlugin." +"add_inspector_plugin] 方法注册。" #: doc/classes/EditorInspectorPlugin.xml msgid "$DOCS_URL/tutorials/plugins/editor/inspector_plugins.html" @@ -25520,7 +25633,7 @@ msgstr "将场景ä¿å˜ä¸º[code]path[/code]处的文件。" msgid "" "Selects the file, with the path provided by [code]file[/code], in the " "FileSystem dock." -msgstr "选择文件,路径由[code]file[/code]æä¾›ï¼Œåœ¨æ–‡ä»¶ç³»ç»Ÿé¢æ¿å¤„。" +msgstr "åœ¨æ–‡ä»¶ç³»ç»Ÿé¢æ¿ä¸é€‰ä¸æ–‡ä»¶ï¼Œè·¯å¾„ç”± [code]file[/code] æä¾›ã€‚" #: doc/classes/EditorInterface.xml msgid "" @@ -25553,7 +25666,7 @@ msgstr "" #: doc/classes/EditorPlugin.xml msgid "Used by the editor to extend its functionality." -msgstr "由编辑器用于扩展其功能。" +msgstr "由编辑器使用,用于扩展其功能。" #: doc/classes/EditorPlugin.xml msgid "" @@ -25599,12 +25712,11 @@ msgid "" "with [method remove_control_from_container] and free it with [method Node." "queue_free]." msgstr "" -"å°†è‡ªå®šä¹‰æŽ§ä»¶æ·»åŠ åˆ°å®¹å™¨ä¸ï¼ˆå‚阅[enum CustomControlContainer])。在编辑器用户界" -"é¢ä¸ï¼Œæœ‰è®¸å¤šä½ç½®å¯ä»¥æ·»åŠ è‡ªå®šä¹‰æŽ§ä»¶ï¼Œè¯·è®°ä½ï¼Œæ‚¨å¿…é¡»è‡ªå·±ç®¡ç†æ‚¨çš„自定义控件的å¯" -"è§æ€§ï¼ˆå¹¶ä¸”很å¯èƒ½åœ¨æ·»åŠ åŽéšè—它)。\n" +"å°†è‡ªå®šä¹‰æŽ§ä»¶æ·»åŠ åˆ°å®¹å™¨ä¸ï¼ˆå‚阅 [enum CustomControlContainer])。在编辑器用户" +"界é¢ä¸ï¼Œæœ‰è®¸å¤šä½ç½®å¯ä»¥æ·»åŠ è‡ªå®šä¹‰æŽ§ä»¶ã€‚\n" "请记ä½ï¼Œæ‚¨å¿…é¡»è‡ªå·±ç®¡ç†æ‚¨çš„自定义控件的å¯è§æ€§ï¼ˆå¹¶ä¸”很å¯èƒ½åœ¨æ·»åŠ åŽéšè—它)。\n" -"å½“ä½ çš„æ’ä»¶åœç”¨æ—¶ï¼Œè¯·ç¡®ä¿ä½¿ç”¨[method remove_control_from_container]åˆ é™¤ä½ çš„è‡ª" -"定义控件,并使用[method Node.queue_free]释放它。" +"å½“ä½ çš„æ’ä»¶åœç”¨æ—¶ï¼Œè¯·ç¡®ä¿ä½¿ç”¨ [method remove_control_from_container] åˆ é™¤ä½ çš„" +"自定义控件,并使用 [method Node.queue_free] 释放它。" #: doc/classes/EditorPlugin.xml msgid "" @@ -26644,10 +26756,13 @@ msgid "" "To use [EditorSceneImporter], register it using the [method EditorPlugin." "add_scene_import_plugin] method first." msgstr "" +"[EditorSceneImporter] å¯ç”¨äºŽå®šä¹‰ç¬¬ä¸‰æ–¹ 3D æ ¼å¼çš„导入脚本。\n" +"è¦ä½¿ç”¨ [EditorSceneImporter],请先使用 [method EditorPlugin." +"add_scene_import_plugin] 注册。" #: modules/fbx/doc_classes/EditorSceneImporterFBX.xml msgid "FBX 3D asset importer." -msgstr "FBX 3D资产导入器。" +msgstr "FBX 3D ç´ æå¯¼å…¥å™¨ã€‚" #: modules/fbx/doc_classes/EditorSceneImporterFBX.xml msgid "" @@ -26676,8 +26791,8 @@ msgid "" "- Binary format in FBX 2017\n" "[/codeblock]" msgstr "" -"这是一个FBX 3D资产导入器,完全支æŒå¤§å¤šæ•°FBX功能。\n" -"如果从Autodesk Maya导出一个FBX场景,请使用这些FBX导出设置:\n" +"这是一个 FBX 3D ç´ æå¯¼å…¥å™¨ï¼Œå®Œå…¨æ”¯æŒå¤§å¤šæ•° FBX 功能。\n" +"如果从 Autodesk Maya 导出一个 FBX 场景,请使用这些 FBX 导出设置:\n" "[codeblock]\n" "- Smoothing Groups 平滑化组\n" "- Smooth Mesh å¹³æ»‘ç½‘æ ¼\n" @@ -27291,7 +27406,6 @@ msgid "Used by the editor to define Spatial gizmo types." msgstr "由编辑部用于定义空间å°å·¥å…·çš„类型。" #: doc/classes/EditorSpatialGizmoPlugin.xml -#, fuzzy msgid "" "[EditorSpatialGizmoPlugin] allows you to define a new type of Gizmo. There " "are two main ways to do so: extending [EditorSpatialGizmoPlugin] for the " @@ -27300,9 +27414,11 @@ msgid "" "To use [EditorSpatialGizmoPlugin], register it using the [method " "EditorPlugin.add_spatial_gizmo_plugin] method first." msgstr "" -"EditorSpatialGizmoPlugin å…è®¸æ‚¨å®šä¹‰ä¸€ç§æ–°çš„è¾…åŠ©å·¥å…·ç±»åž‹ã€‚è¿™æ ·åšçš„ä¸»è¦æ–¹æ³•有两" -"ç§ï¼šæ‰©å±• [EditorSpatialGizmoPlugin] 以获得更简å•çš„Gizmos,或创建新的 " -"[EditorSpatialGizmoPlugin] 类型。有关更多信æ¯ï¼Œè¯·å‚阅文档ä¸çš„æ•™ç¨‹ã€‚" +"[EditorSpatialGizmoPlugin] å¯ç”¨äºŽå®šä¹‰æ–°çš„æŽ§åˆ¶å™¨ç±»åž‹ã€‚è¿™æ ·åšçš„ä¸»è¦æ–¹æ³•有两ç§ï¼š" +"比较简å•的控制器å¯ä»¥æ‰©å±• [EditorSpatialGizmoPlugin],或者å¯ä»¥åˆ›å»ºæ–°çš„ " +"[EditorSpatialGizmo] 类型。有关更多信æ¯ï¼Œè¯·å‚阅文档ä¸çš„æ•™ç¨‹ã€‚\n" +"è¦ä½¿ç”¨ [EditorSpatialGizmoPlugin],请先用 [method EditorPlugin." +"add_spatial_gizmo_plugin] 注册。" #: doc/classes/EditorSpatialGizmoPlugin.xml msgid "$DOCS_URL/tutorials/plugins/editor/spatial_gizmos.html" @@ -27465,20 +27581,23 @@ msgstr "" "[EditorInspectorPlugin] ä¸€èµ·ä½¿ç”¨ï¼Œä»¥é‡æ–°åˆ›å»ºç›¸åŒçš„行为。" #: doc/classes/EditorVCSInterface.xml +#, fuzzy msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "版本控制系统(VCS)接å£ï¼Œå¯å¯¹æ£åœ¨ä½¿ç”¨çš„æœ¬åœ°VCS进行读写。" #: doc/classes/EditorVCSInterface.xml +#, fuzzy msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." msgstr "" "由编辑器用æ¥åœ¨ç¼–è¾‘å™¨ä¸æ˜¾ç¤ºVCSæå–的信æ¯ã€‚这个API的实现包å«åœ¨VCSé™„åŠ ç»„ä»¶ä¸ï¼Œè¿™" "äº›é™„åŠ ç»„ä»¶æœ¬è´¨ä¸Šæ˜¯GDNativeæ’ä»¶ï¼Œéœ€è¦æ”¾åˆ°é¡¹ç›®æ–‡ä»¶å¤¹ä¸ã€‚这些VCSé™„åŠ ç»„ä»¶æ˜¯è„šæœ¬ï¼Œ" @@ -27487,129 +27606,242 @@ msgstr "" "用的体验。" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "从列表ä¸åˆ é™¤è‡ªåŠ¨åŠ è½½[code]name[/code]。" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." +msgstr "创建[code]class[/code]的实例。" + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." msgstr "" -"如果add-onå·²ç»åˆå§‹åŒ–,则创建一个版本æäº¤ï¼Œå¦åˆ™ä¸åšä»»ä½•äº‹æƒ…å°±è¿”å›žã€‚ä½¿ç”¨ä¹‹å‰æš‚" -"å˜çš„æ–‡ä»¶ï¼Œæäº¤ä¿¡æ¯è®¾ç½®ä¸ºå‚æ•°ä¸æä¾›çš„å€¼ã€‚" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Discards the changes made in file present at [code]file_path[/code]." +msgstr "将场景ä¿å˜ä¸º[code]path[/code]处的文件。" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." -msgstr "" -"如果VCS addon被åˆå§‹åŒ–,返回一个[Array]çš„[Dictionary]å¯¹è±¡ï¼ŒåŒ…å«æ£åœ¨ä½¿ç”¨çš„VCSçš„" -"diff输出,å¦åˆ™è¿”回一个空[Array]对象。diff内容还包括一些上下文,这些上下文行为" -"文件ä¸è§‚察到的行å˜åŒ–æä¾›ä¸Šä¸‹æ–‡ã€‚\n" -"æ¯ä¸ª[Dictionary]对象的键下都有行差内容。\n" -"- [code]\"content\"[/code]å˜å‚¨ä¸€ä¸ªåŒ…å«è¡Œå†…容的[String]。\n" -"- [code]\"status\"[/code]å˜å‚¨ä¸€ä¸ª[String]ï¼Œå¦‚æžœå†…å®¹æ˜¯æ·»åŠ è¡Œï¼Œåˆ™åŒ…å«[code]\"+" -"\"[/code]ï¼Œä½†å¦‚æžœæ˜¯åˆ é™¤ï¼Œåˆ™å˜å‚¨[code]\"-\"[/code]ï¼Œå¦‚æžœè¡Œå†…å®¹æ—¢ä¸æ˜¯æ·»åŠ ä¹Ÿä¸æ˜¯" -"åˆ é™¤ï¼Œåˆ™å˜å‚¨ä¸€ä¸ªç©ºå—符串。\n" -"- [code]\"new_line_number\"[/code]å˜å‚¨ä¸€ä¸ªåŒ…å«è¡Œå†…容新行å·çš„æ•´æ•°ã€‚\n" -"- [code]\"line_count\"[/code]å˜å‚¨ä¸€ä¸ªæ•´æ•°ï¼ŒåŒ…å«è¡Œå†…容的行数。\n" -"- [code]\"old_line_number\"[/code]å˜å‚¨åŒ…å«è¡Œå†…容的旧行å·çš„æ•´æ•°ã€‚\n" -"- [code]\"offset\"[/code]å˜å‚¨è‡ªç¬¬ä¸€ä¸ªä¸Šä¸‹æ–‡è¡Œå†…容以æ¥è¡Œå˜åŒ–çš„åç§»é‡ã€‚" +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." +msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" -msgstr "" -"返回一个 [Dictionary]ï¼ŒåŒ…å«æ£€æµ‹åˆ°çš„æ›´æ”¹æ–‡ä»¶çš„è·¯å¾„ï¼Œæ˜ å°„åˆ°ä¸€ä¸ªæ•´æ•°ï¼Œè¯¥æ•´æ•°è¡¨ç¤º" -"相应文件更改的状æ€ã€‚\n" -"以下整数值用于表示检测到的文件是:\n" -"- [code]0[/code]:新的 VCS 工作目录\n" -"- [code]1[/code]:修改\n" -"- [code]2[/code]:é‡å‘½å\n" -"- [code]3[/code]ï¼šåˆ é™¤\n" -"- [code]4[/code]:类型改å˜" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Gets the current branch name defined in the VCS." +msgstr "返回在[FileSystemDock]䏿Ÿ¥çœ‹çš„当å‰è·¯å¾„。" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." -msgstr "返回VCS工作目录的项目å称。" +msgid "" +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." +msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." -msgstr "如果VCSå·²ç»åˆå§‹åŒ–,返回VCSçš„å称,å¦åˆ™è¿”回一个空å—符串。" +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." +msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" -"åˆå§‹åŒ–VCS addon(如果还未åˆå§‹åŒ–ï¼‰ã€‚ä½¿ç”¨å‚æ•°å€¼ä½œä¸ºé¡¹ç›®å·¥ä½œç›®å½•的路径。如果需" -"è¦ï¼Œåˆ›å»ºåˆå§‹æäº¤ã€‚如果æˆåŠŸï¼Œè¿”å›ž[code]true[/code],å¦åˆ™è¿”回[code]false[/" -"code]。" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." msgstr "" -"如果addon准备好å“应函数调用,返回[code]true[/code],å¦åˆ™è¿”回[code]false[/" -"code]。" #: doc/classes/EditorVCSInterface.xml +#, fuzzy msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." +msgstr "è¿”å›žåŒ…å«æ‰€æœ‰èŠ‚ç‚¹åç§°çš„[PoolStringArray]。" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "返回[code]idx[/code]处的节点å称。" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." msgstr "" -"如果VCSæ’ä»¶å·²ç»åˆå§‹åŒ–,返回[code]true[/code],å¦åˆ™è¿”回[code]false[/code]。" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Remove a branch from the local VCS." +msgstr "从选择ä¸åˆ 除一个节点。" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Remove a remote from the local VCS." +msgstr "从选择ä¸åˆ 除一个节点。" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "å°†ç›¸æœºæº [code]feed[/code] æ·»åŠ åˆ°æ‘„åƒæœºæœåС噍ä¸ã€‚" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." msgstr "" -"å…³é—VCSæ’件,å…许清ç†ä»£ç 去调用è¿è¡Œã€‚如果没有失败,返回[code]true[/code],å¦" -"则返回[code]false[/code]。" #: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." msgstr "" -"调用[method EditorVCSInterface.commit]时应æäº¤çš„æ–‡ä»¶ã€‚傿•°åº”包å«ç»å¯¹è·¯å¾„。" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Pops up an error message in the edior." +msgstr "在编辑器ä¸ç”¨äºŽä¸ºå±žæ€§åˆ†ç»„。" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "A new file has been added." +msgstr "æ·»åŠ æ–°æŽ¥å£æ—¶è§¦å‘。" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "A file is encountered from the staged area." +msgstr "状æ€ï¼šä¸ŽæœåС噍æ–开连接。" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" -"è§£é™¤ä¹‹å‰æš‚å˜çš„è¦æäº¤çš„æ–‡ä»¶ï¼Œä»¥ä¾¿åœ¨è°ƒç”¨[method EditorVCSInterface.commit]æ—¶ä¸" -"å†æäº¤ã€‚å‚æ•°åº”包å«ç»å¯¹è·¯å¾„。" #: doc/classes/EncodedObjectAsID.xml msgid "Holds a reference to an [Object]'s instance ID." @@ -27940,7 +28172,6 @@ msgstr "" "[member physics_jitter_fix]设置为[code]0[/code]æ¥ç¦ç”¨ç‰©ç†æŠ–动修å¤ã€‚" #: doc/classes/Engine.xml -#, fuzzy msgid "" "If [code]false[/code], stops printing error and warning messages to the " "console and editor Output log. This can be used to hide error and warning " @@ -27954,13 +28185,13 @@ msgid "" "[b]Note:[/b] This property does not impact the editor's Errors tab when " "running a project from the editor." msgstr "" -"如果 [code]false[/code]ï¼Œåœæ¢æ‰“å°é”™è¯¯å’Œè¦å‘Šä¿¡æ¯åˆ°æŽ§åˆ¶å°å’Œç¼–辑器输出日志。这å¯" -"以用æ¥åœ¨å•元测试套件è¿è¡ŒæœŸé—´éšè—错误和è¦å‘Šä¿¡æ¯ã€‚这个属性ç‰åŒäºŽ [member " +"如果为 [code]false[/code]ï¼Œåˆ™åœæ¢æ‰“å°é”™è¯¯å’Œè¦å‘Šä¿¡æ¯åˆ°æŽ§åˆ¶å°å’Œç¼–辑器输出日志。" +"è¿™å¯ä»¥ç”¨æ¥åœ¨å•元测试套件è¿è¡ŒæœŸé—´éšè—错误和è¦å‘Šä¿¡æ¯ã€‚这个属性ç‰åŒäºŽ [member " "ProjectSettings.application/run/disable_stderr] 项目设置。\n" "[b]è¦å‘Šï¼š[/b]å¦‚æžœä½ åœ¨é¡¹ç›®çš„ä»»æ„ä½ç½®å°†å…¶è®¾ç½®ä¸º [code]false[/code],é‡è¦çš„错误" -"ä¿¡æ¯å¯èƒ½ä¼šè¢«éšè—,å³ä½¿å®ƒä»¬æ˜¯ç”±å…¶ä»–脚本触å‘。如果在 [code]@tool[/code] 脚本ä¸" -"把这个设置为 [code]false[/code],这也会影å“到编辑器本身。在确ä¿é”™è¯¯ä¿¡æ¯è¢«å¯ç”¨" -"之å‰ï¼Œ[i]ä¸[/i]报告错误(默认情况下)。\n" +"ä¿¡æ¯å¯èƒ½ä¼šè¢«éšè—,å³ä½¿å®ƒä»¬æ˜¯ç”±å…¶ä»–脚本触å‘。如果在 [code]tool[/code] è„šæœ¬ä¸æŠŠ" +"这个设置为 [code]false[/code],这也会影å“到编辑器本身。在确ä¿é”™è¯¯ä¿¡æ¯è¢«å¯ç”¨ä¹‹" +"å‰ï¼Œ[i]ä¸[/i]报告错误(默认情况下)。\n" "[b]注æ„:[/b]当从编辑器è¿è¡Œä¸€ä¸ªé¡¹ç›®æ—¶ï¼Œè¿™ä¸ªå±žæ€§ä¸å½±å“编辑器的错误选项å¡ã€‚" #: doc/classes/Engine.xml @@ -29466,13 +29697,15 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" -"æ·»åŠ [code]filter[/code]作为自定义过滤器; [code]filter[/code]çš„æ ¼å¼åº”为" -"[code]“ filename.extension; Descriptionâ€[/code]。例如,[code]\"*.png ; PNG " -"Images\"[/code]。" #: doc/classes/FileDialog.xml msgid "Clear all the added filters in the dialog." @@ -29535,10 +29768,13 @@ msgid "The currently selected file path of the file dialog." msgstr "当å‰é€‰æ‹©çš„æ–‡ä»¶å¯¹è¯æ¡†çš„æ–‡ä»¶è·¯å¾„。" #: doc/classes/FileDialog.xml +#, fuzzy msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" "å¯ç”¨çš„æ–‡ä»¶ç±»åž‹è¿‡æ»¤å™¨ã€‚例如,这仅显示 [code].png[/code] å’Œ [code].gd[/code] æ–‡" "件: [code]set_filters(PoolStringArray([\"*.png ; PNG Images\", \"*.gd ; " @@ -29906,14 +30142,12 @@ msgstr "" "个平å°å’Œæž¶æž„进行编译。" #: modules/gdnative/doc_classes/GDNativeLibrary.xml -#, fuzzy msgid "$DOCS_URL/tutorials/scripting/gdnative/gdnative-c-example.html" -msgstr "$DOCS_URL/tutorials/plugins/gdnative/gdnative-c-example.html" +msgstr "$DOCS_URL/tutorials/scripting/gdnative/gdnative-c-example.html" #: modules/gdnative/doc_classes/GDNativeLibrary.xml -#, fuzzy msgid "$DOCS_URL/tutorials/scripting/gdnative/gdnative-cpp-example.html" -msgstr "$DOCS_URL/tutorials/plugins/gdnative/gdnative-cpp-example.html" +msgstr "$DOCS_URL/tutorials/scripting/gdnative/gdnative-cpp-example.html" #: modules/gdnative/doc_classes/GDNativeLibrary.xml msgid "" @@ -30006,9 +30240,8 @@ msgstr "" "[method Object.set_script] 会扩展该对象。" #: modules/gdscript/doc_classes/GDScript.xml -#, fuzzy msgid "$DOCS_URL/tutorials/scripting/gdscript/index.html" -msgstr "$DOCS_URL/tutorials/scripting/index.html" +msgstr "$DOCS_URL/tutorials/scripting/gdscript/index.html" #: modules/gdscript/doc_classes/GDScript.xml msgid "Returns byte code for the script source code." @@ -30277,7 +30510,7 @@ msgstr "如果[code]true[/code],整个X轴的线性è¿åЍå—到é™åˆ¶ã€‚" #: doc/classes/Generic6DOFJoint.xml msgid "The minimum difference between the pivot points' X axis." -msgstr "枢轴点的X轴之间的最å°å·®å¼‚。" +msgstr "轴心点的 X 轴之间的最å°å·®å¼‚。" #: doc/classes/Generic6DOFJoint.xml msgid "" @@ -30293,7 +30526,7 @@ msgstr "应用于X轴上移动的一个系数。值越低,移动的就越慢〠#: doc/classes/Generic6DOFJoint.xml msgid "The maximum difference between the pivot points' X axis." -msgstr "枢轴点的X轴之间的最å°å·®å¼‚。" +msgstr "轴心点的 X 轴之间的最大差异。" #: doc/classes/Generic6DOFJoint.xml msgid "The amount of damping that happens at the Y motion." @@ -30305,7 +30538,7 @@ msgstr "如果[code]true[/code],é™åˆ¶è·¨è¶ŠY轴的线性è¿åŠ¨ã€‚" #: doc/classes/Generic6DOFJoint.xml msgid "The minimum difference between the pivot points' Y axis." -msgstr "枢轴点的Y轴之间的最å°å·®å¼‚。" +msgstr "轴心点的 Y 轴之间的最å°å·®å¼‚。" #: doc/classes/Generic6DOFJoint.xml msgid "" @@ -30321,7 +30554,7 @@ msgstr "应用于Y轴上移动的一个系数。值越低,移动的就越慢〠#: doc/classes/Generic6DOFJoint.xml msgid "The maximum difference between the pivot points' Y axis." -msgstr "枢轴点的Y轴之间的最大差异。" +msgstr "轴心点的 Y 轴之间的最大差异。" #: doc/classes/Generic6DOFJoint.xml msgid "The amount of damping that happens at the Z motion." @@ -30333,7 +30566,7 @@ msgstr "如果[code]true[/code],跨Z轴的线性è¿åЍå—到é™åˆ¶ã€‚" #: doc/classes/Generic6DOFJoint.xml msgid "The minimum difference between the pivot points' Z axis." -msgstr "枢轴点的Z轴之间的最å°å·®å¼‚。" +msgstr "轴心点的 Z 轴之间的最å°å·®å¼‚。" #: doc/classes/Generic6DOFJoint.xml msgid "" @@ -30349,7 +30582,7 @@ msgstr "适用于跨Z轴移动的一个系数。值越低,移动的就越慢〠#: doc/classes/Generic6DOFJoint.xml msgid "The maximum difference between the pivot points' Z axis." -msgstr "枢轴点的Z轴之间的最大差异。" +msgstr "轴心点的 Z 轴之间的最大差异。" #: doc/classes/Generic6DOFJoint.xml msgid "" @@ -30407,11 +30640,11 @@ msgstr "线性马达在Z轴上试图达到的速度。" #: doc/classes/Generic6DOFJoint.xml doc/classes/PhysicsServer.xml msgid "The minimum difference between the pivot points' axes." -msgstr "枢轴点之间的最å°å·®å¼‚。" +msgstr "轴心点的轴之间的最å°å·®å¼‚。" #: doc/classes/Generic6DOFJoint.xml doc/classes/PhysicsServer.xml msgid "The maximum difference between the pivot points' axes." -msgstr "枢轴点的轴之间的最大差异。" +msgstr "轴心点的轴之间的最大差异。" #: doc/classes/Generic6DOFJoint.xml msgid "" @@ -31634,6 +31867,102 @@ msgstr "将用于填充纹ç†çš„[Gradient]。" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "将从[Gradient]ä¸èŽ·å¾—çš„é¢œè‰²æ ·æœ¬çš„æ•°é‡ã€‚" +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "Gradient-filled 2D texture." +msgstr "æ¸å˜å¡«å……纹ç†ã€‚" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" +"GradientTexture使用[Gradient]æ¥å¡«å……çº¹ç†æ•°æ®ã€‚æ¸å˜å°†ä½¿ç”¨ä»Žä¸èŽ·å¾—çš„é¢œè‰²ä»Žå·¦åˆ°å³" +"填充。这æ„味ç€çº¹ç†ä¸ä¸€å®šä»£è¡¨æ¸å˜çš„精确副本,而是以固定的æ¥é•¿ä»Žæ¸å˜ä¸èŽ·å¾—çš„æ ·" +"本的æ’值,è§[member width]。" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "将用于填充纹ç†çš„[Gradient]。" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "将从[Gradient]ä¸èŽ·å¾—çš„é¢œè‰²æ ·æœ¬çš„æ•°é‡ã€‚" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "将从[Gradient]ä¸èŽ·å¾—çš„é¢œè‰²æ ·æœ¬çš„æ•°é‡ã€‚" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -32531,7 +32860,7 @@ msgstr "指定的 [MeshLibrary]。" msgid "" "Overrides the default friction and bounce physics properties for the whole " "[GridMap]." -msgstr "" +msgstr "覆盖整个 [GridMap] 的默认摩擦力和å弹物ç†å±žæ€§ã€‚" #: modules/gridmap/doc_classes/GridMap.xml msgid "" @@ -32792,7 +33121,6 @@ msgid "Used to create an HMAC for a message using a key." msgstr "用æ¥ä¸ºä¸€ä¸ªä½¿ç”¨å¯†é’¥çš„ä¿¡æ¯åˆ›å»º HMAC。" #: doc/classes/HMACContext.xml -#, fuzzy msgid "" "The HMACContext class is useful for advanced HMAC use cases, such as " "streaming the message as it supports creating the message over time rather " @@ -32852,7 +33180,7 @@ msgstr "" " var err = ctx.start(HashingContext.HASH_SHA256, key)\n" " assert(err == OK)\n" " var msg1 = \"this is \".to_utf8()\n" -" var msg2 = \"vewy vewy secret\".to_utf8()\n" +" var msg2 = \"super duper secret\".to_utf8()\n" " err = ctx.update(msg1)\n" " assert(err == OK)\n" " err = ctx.update(msg2)\n" @@ -32875,7 +33203,7 @@ msgstr "" " Error err = ctx.Start(HashingContext.HASH_SHA256, key);\n" " GD.Assert(err == OK);\n" " PoolByteArray msg1 = String(\"this is \").to_utf8();\n" -" PoolByteArray msg2 = String(\"vewy vew secret\").to_utf8();\n" +" PoolByteArray msg2 = String(\"super duper secret\").to_utf8();\n" " err = ctx.Update(msg1);\n" " GD.Assert(err == OK);\n" " err = ctx.Update(msg2);\n" @@ -35811,7 +36139,6 @@ msgstr "" "想è¦çš„值(在 0 到 1 的范围内)。" #: doc/classes/Input.xml -#, fuzzy msgid "" "Returns [code]true[/code] when the user starts pressing the action event, " "meaning it's [code]true[/code] only on the frame that the user pressed down " @@ -35826,13 +36153,16 @@ msgid "" "[url=$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]Input " "examples[/url] in the documentation for more information." msgstr "" -"当用户开始按下动作事件时,返回[code]true[/code]ï¼Œä¹Ÿå°±æ˜¯è¯´ï¼Œåªæœ‰åœ¨ç”¨æˆ·æŒ‰ä¸‹æŒ‰é’®" -"çš„é‚£ä¸€å¸§æ‰æ˜¯[code]true[/code]。\n" +"当用户开始按下动作事件时,返回 [code]true[/code]ï¼Œä¹Ÿå°±æ˜¯è¯´ï¼Œåªæœ‰åœ¨ç”¨æˆ·æŒ‰ä¸‹æŒ‰" +"é’®çš„é‚£ä¸€å¸§æ‰æ˜¯ [code]true[/code]。\n" "这对那些åªéœ€è¦åœ¨åŠ¨ä½œè¢«æŒ‰ä¸‹æ—¶è¿è¡Œä¸€æ¬¡çš„代ç ä¸å¾ˆæœ‰ç”¨ï¼Œè€Œä¸æ˜¯åœ¨æŒ‰ä¸‹æ—¶æ¯ä¸€å¸§éƒ½è¦" "è¿è¡Œã€‚\n" -"如果[code]exact[/code]是[code]false[/code],它将忽略[InputEventKey]å’Œ" -"[InputEventMouseButton]事件的输入修饰符,以åŠ[InputEventJoypadMotion]事件的方" -"å‘。" +"如果 [code]exact[/code] 是 [code]false[/code],它将忽略 [InputEventKey] å’Œ " +"[InputEventMouseButton] äº‹ä»¶çš„è¾“å…¥ä¿®é¥°ç¬¦ï¼Œä»¥åŠ [InputEventJoypadMotion] 事件" +"的方å‘。\n" +"[b]注æ„:[/b]由于键盘冲çªï¼Œ[method is_action_just_pressed] å¯èƒ½ä¼šåœ¨åŠ¨ä½œçš„æŸä¸ª" +"键按下时也返回 [code]false[/code]。详情请å‚阅文档[url=$DOCS_URL/tutorials/" +"inputs/input_examples.html#keyboard-events]《输入示例》[/url]。" #: doc/classes/Input.xml msgid "" @@ -35850,7 +36180,6 @@ msgstr "" "å‘。" #: doc/classes/Input.xml -#, fuzzy msgid "" "Returns [code]true[/code] if you are pressing the action event. Note that if " "an action has multiple buttons assigned and more than one of them is " @@ -35864,12 +36193,15 @@ msgid "" "$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]Input " "examples[/url] in the documentation for more information." msgstr "" -"å¦‚æžœä½ æ£åœ¨æŒ‰ä¸‹åŠ¨ä½œäº‹ä»¶ï¼Œè¿”å›ž[code]true[/code]。请注æ„,如果一个动作有多个分é…" -"çš„æŒ‰é’®ï¼Œå¹¶ä¸”ä¸æ¢ä¸€ä¸ªè¢«æŒ‰ä¸‹ï¼Œé‡Šæ”¾ä¸€ä¸ªæŒ‰é’®å°†é‡Šæ”¾è¿™ä¸ªåŠ¨ä½œï¼Œå³ä½¿å…¶ä»–分é…给这个动" -"作的按钮ä»ç„¶è¢«æŒ‰ä¸‹ã€‚\n" -"如果[code]exact[/code]是[code]false[/code],它将忽略[InputEventKey]å’Œ" -"[InputEventMouseButton]事件的输入修饰符,以åŠ[InputEventJoypadMotion]事件的方" -"å‘。" +"å¦‚æžœä½ æ£åœ¨æŒ‰ä¸‹åŠ¨ä½œäº‹ä»¶ï¼Œè¿”å›ž [code]true[/code]。请注æ„,如果一个动作有多个分" +"é…çš„æŒ‰é’®ï¼Œå¹¶ä¸”ä¸æ¢ä¸€ä¸ªè¢«æŒ‰ä¸‹ï¼Œé‡Šæ”¾ä¸€ä¸ªæŒ‰é’®å°†é‡Šæ”¾è¿™ä¸ªåŠ¨ä½œï¼Œå³ä½¿å…¶ä»–分é…给这个" +"动作的按钮ä»ç„¶è¢«æŒ‰ä¸‹ã€‚\n" +"如果 [code]exact[/code] 是 [code]false[/code],它将忽略 [InputEventKey] å’Œ " +"[InputEventMouseButton] äº‹ä»¶çš„è¾“å…¥ä¿®é¥°ç¬¦ï¼Œä»¥åŠ [InputEventJoypadMotion] 事件" +"的方å‘。\n" +"[b]注æ„:[/b]由于键盘冲çªï¼Œ[method is_action_pressed] å¯èƒ½ä¼šåœ¨åŠ¨ä½œçš„æŸä¸ªé”®æŒ‰" +"下时也返回 [code]false[/code]。详情请å‚阅文档[url=$DOCS_URL/tutorials/inputs/" +"input_examples.html#keyboard-events]《输入示例》[/url]。" #: doc/classes/Input.xml msgid "" @@ -35903,6 +36235,15 @@ msgid "" "$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]Input " "examples[/url] in the documentation for more information." msgstr "" +"å¦‚æžœä½ æ£åœ¨æŒ‰å½“å‰é”®ç›˜å¸ƒå±€ä¸çš„这个键,则返回 [code]true[/code]。å¯ä»¥ä¼ [enum " +"KeyList] 常é‡ã€‚\n" +"åªæœ‰éžæ¸¸æˆåº”用程åºä¸æ‰æŽ¨è [method is_key_pressed] è€Œä¸æ˜¯ [method " +"is_physical_key_pressed]。å¯ä»¥ç¡®ä¿å¿«æ·é”®çš„è¡Œä¸ºä¸Žç”¨æˆ·çš„é”®ç›˜å¸ƒå±€æœ‰å…³ï¼Œå› ä¸ºéžæ¸¸" +"æˆåº”用程åºçš„键盘快æ·é”®é€šå¸¸ä¸Žé”®ç›˜å¸ƒå±€æœ‰å…³ã€‚如果有疑问,就请使用 [method " +"is_physical_key_pressed]。\n" +"[b]注æ„:[/b]由于键盘冲çªï¼Œ[method is_key_pressed] å¯èƒ½ä¼šåœ¨åŠ¨ä½œçš„æŸä¸ªé”®æŒ‰ä¸‹æ—¶" +"也返回 [code]false[/code]。详情请å‚阅文档[url=$DOCS_URL/tutorials/inputs/" +"input_examples.html#keyboard-events]《输入示例》[/url]。" #: doc/classes/Input.xml msgid "" @@ -35926,6 +36267,15 @@ msgid "" "[url=$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]Input " "examples[/url] in the documentation for more information." msgstr "" +"å¦‚æžœä½ æ£åœ¨æŒ‰ 101/102 é”®ç¾Žå¼ QWERTY 键盘ä¸è¿™ä¸ªé”®çš„物ç†ä½ç½®ï¼Œåˆ™è¿”回 " +"[code]true[/code]。å¯ä»¥ä¼ [enum KeyList] 常é‡ã€‚\n" +"游æˆå†…的动作推è [method is_physical_key_pressed] è€Œä¸æ˜¯ [method " +"is_key_pressed]ï¼Œå› ä¸ºå¯ä»¥è®© W/A/S/D å¸ƒå±€æ— è®ºç”¨æˆ·ä½¿ç”¨ä»€ä¹ˆé”®ç›˜å¸ƒå±€éƒ½å¯ç”¨ã€‚" +"[method is_physical_key_pressed] 还å¯ä»¥ä¿è¯é¡¶éƒ¨çš„æ•°å—键在任何键盘布局ä¸éƒ½å¯" +"用。如果有疑问,就请使用 [method is_physical_key_pressed]。\n" +"[b]注æ„:[/b]由于键盘冲çªï¼Œ[method is_physical_key_pressed] å¯èƒ½ä¼šåœ¨åŠ¨ä½œçš„æŸ" +"个键按下时也返回 [code]false[/code]。详情请å‚阅文档[url=$DOCS_URL/tutorials/" +"inputs/input_examples.html#keyboard-events]《输入示例》[/url]。" #: doc/classes/Input.xml msgid "" @@ -36317,7 +36667,6 @@ msgstr "" "å‘。" #: doc/classes/InputEvent.xml -#, fuzzy msgid "" "Returns [code]true[/code] if the given action is being pressed (and is not " "an echo event for [InputEventKey] events, unless [code]allow_echo[/code] is " @@ -36331,12 +36680,15 @@ msgid "" "$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]Input " "examples[/url] in the documentation for more information." msgstr "" -"如果给定的动作被按下,则返回[code]true[/code]ï¼Œå¹¶ä¸”ä¸æ˜¯ [InputEventKey] 事件" -"çš„å›žæ˜¾äº‹ä»¶ï¼Œé™¤éž [code]allow_echo[/code] 是 [code]true[/code]。与" -"[InputEventMouseMotion]或[InputEventScreenDrag]ç±»åž‹çš„äº‹ä»¶æ— å…³ã€‚\n" -"如果[code]exact_match[/code]是[code]false[/code],它将忽略[InputEventKey]å’Œ" -"[InputEventMouseButton]事件的输入修饰符,以åŠ[InputEventJoypadMotion]事件的方" -"å‘。" +"如果给定的动作被按下,则返回 [code]true[/code]ï¼Œå¹¶ä¸”ä¸æ˜¯ [InputEventKey] 事件" +"çš„å›žæ˜¾äº‹ä»¶ï¼Œé™¤éž [code]allow_echo[/code] 是 [code]true[/code]。与 " +"[InputEventMouseMotion] 或 [InputEventScreenDrag] ç±»åž‹çš„äº‹ä»¶æ— å…³ã€‚\n" +"如果 [code]exact_match[/code] 是 [code]false[/code],它将忽略 " +"[InputEventKey] å’Œ [InputEventMouseButton] äº‹ä»¶çš„è¾“å…¥ä¿®é¥°ç¬¦ï¼Œä»¥åŠ " +"[InputEventJoypadMotion] 事件的方å‘。\n" +"[b]注æ„:[/b]由于键盘冲çªï¼Œ[method is_action_pressed] å¯èƒ½ä¼šåœ¨åŠ¨ä½œçš„æŸä¸ªé”®æŒ‰" +"下时也返回 [code]false[/code]。详情请å‚阅文档[url=$DOCS_URL/tutorials/inputs/" +"input_examples.html#keyboard-events]《输入示例》[/url]。" #: doc/classes/InputEvent.xml msgid "" @@ -36358,18 +36710,17 @@ msgid "" "Returns [code]true[/code] if this input event's type is one that can be " "assigned to an input action." msgstr "" -"如果æ¤è¾“入事件的类型是å¯ä»¥åˆ†é…给输入动作的类型,则返回 [code]true[/code]。" +"如果这个输入事件的类型是å¯ä»¥åˆ†é…给输入动作的类型,则返回 [code]true[/code]。" #: doc/classes/InputEvent.xml msgid "" "Returns [code]true[/code] if this input event is an echo event (only for " "events of type [InputEventKey])." msgstr "" -"如果æ¤è¾“入事件是回显事件(仅适用于 [InputEventKey] 类型的事件),则返回 " +"如果这个输入事件是回显事件(仅适用于 [InputEventKey] 类型的事件),则返回 " "[code]true[/code]。" #: doc/classes/InputEvent.xml -#, fuzzy msgid "" "Returns [code]true[/code] if this input event is pressed. Not relevant for " "events of type [InputEventMouseMotion] or [InputEventScreenDrag].\n" @@ -36378,11 +36729,11 @@ msgid "" "$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]Input " "examples[/url] in the documentation for more information." msgstr "" -"å¦‚æžœç»™å®šçš„åŠ¨ä½œè¢«é‡Šæ”¾ï¼Œå³æœªè¢«æŒ‰ä¸‹ï¼Œåˆ™è¿”回[code]true[/code]。与" -"[InputEventMouseMotion]或[InputEventScreenDrag]ç±»åž‹çš„äº‹ä»¶æ— å…³ã€‚\n" -"如果[code]exact_match[/code]是[code]false[/code],它将忽略[InputEventKey]å’Œ" -"[InputEventMouseButton]事件的输入修饰符,以åŠ[InputEventJoypadMotion]事件的方" -"å‘。" +"如果这个输入事件被按下,则返回 [code]true[/code]。与 [InputEventMouseMotion] " +"或 [InputEventScreenDrag] ç±»åž‹çš„äº‹ä»¶æ— å…³ã€‚\n" +"[b]注æ„:[/b]由于键盘冲çªï¼Œ[method is_action_pressed] å¯èƒ½ä¼šåœ¨åŠ¨ä½œçš„æŸä¸ªé”®æŒ‰" +"下时也返回 [code]false[/code]。详情请å‚阅文档[url=$DOCS_URL/tutorials/inputs/" +"input_examples.html#keyboard-events]《输入示例》[/url]。" #: doc/classes/InputEvent.xml msgid "" @@ -36633,9 +36984,8 @@ msgstr "" "set_ime_active]。" #: doc/classes/InputEventMIDI.xml -#, fuzzy msgid "Input event for MIDI inputs." -msgstr "动作的输入事件类型。" +msgstr "MIDI 输入的输入事件。" #: doc/classes/InputEventMIDI.xml msgid "" @@ -36650,26 +37000,34 @@ msgid "" "Note that Godot does not currently support MIDI output, so there is no way " "to emit MIDI signals from Godot. Only MIDI input works." msgstr "" +"InputEventMIDI å¯ä»¥å®žçŽ°ä»Žé’¢ç´ç‰ MIDI 设备接收输入事件。MIDI 是 Musical " +"Instrument Digital Interface 的缩写,å³éŸ³ä¹æ•°å—接å£ã€‚\n" +"MIDI ä¿¡å·å¯ä»¥é€šè¿‡ 5 é’ˆ MIDI 接头或 UDB ä¼ è¾“ï¼Œå¦‚æžœä½ çš„è®¾å¤‡ä¸¤è€…éƒ½æ”¯æŒï¼Œè¯·ç¡®è®¤è¯¥" +"è®¾å¤‡çš„è®¾ç½®ä¸æ£åœ¨ä½¿ç”¨çš„æ˜¯å“ªä¸€ç§è¾“出。\n" +"è¦ä»Ž MIDI è®¾å¤‡æŽ¥æ”¶è¾“å…¥äº‹ä»¶ï¼Œä½ éœ€è¦è°ƒç”¨ [method OS.open_midi_inputs]ã€‚ä½ å¯ä»¥ä½¿" +"用 [method OS.get_connected_midi_inputs] 查看检测到的设备。\n" +"è¯·æ³¨æ„ Godot ç›®å‰ä¸æ”¯æŒ MIDI è¾“å‡ºï¼Œå› æ¤æ— 法从 Godot ä¸å‘出 MIDI ä¿¡å·ã€‚åªèƒ½è¿›" +"行 MIDI 输入。" #: doc/classes/InputEventMIDI.xml msgid "" "https://www.midi.org/specifications-old/item/table-2-expanded-messages-list-" "status-bytes" msgstr "" +"https://www.midi.org/specifications-old/item/table-2-expanded-messages-list-" +"status-bytes" #: doc/classes/InputEventMIDI.xml -#, fuzzy msgid "https://en.wikipedia.org/wiki/General_MIDI#Program_change_events" msgstr "" -"https://zh.wikipedia.org/zh-cn/%E5%96%AE%E7%B2%BE%E5%BA%A6%E6%B5%AE%E9%BB%9E" -"%E6%95%B8" +"https://zh.wikipedia.org/zh-cn/General_MIDI#%E9%9F%B3%E8%89%B2%E8%BD%89%E6%8F" +"%9B%E4%BA%8B%E4%BB%B6%EF%BC%88Program_change_events%EF%BC%89" #: doc/classes/InputEventMIDI.xml -#, fuzzy msgid "https://en.wikipedia.org/wiki/Piano_key_frequencies#List" msgstr "" -"https://zh.wikipedia.org/zh-cn/%E5%96%AE%E7%B2%BE%E5%BA%A6%E6%B5%AE%E9%BB%9E" -"%E6%95%B8" +"https://zh.wikipedia.org/zh-cn/%E9%8B%BC%E7%90%B4%E9%8D%B5%E9%A0%BB%E7%8E%87#" +"%E5%88%97%E8%A1%A8" #: doc/classes/InputEventMIDI.xml msgid "" @@ -36677,6 +37035,8 @@ msgid "" "ranges from 0 to 15. MIDI channel 9 is reserved for the use with percussion " "instruments, the rest of the channels are for non-percussion instruments." msgstr "" +"这个输入事件的 MIDI 通é“。总共有 16 个通é“,所以这个值的范围是 0 到 15。MIDI " +"é€šé“ 9 是为打击ä¹å™¨ä¿ç•™çš„,其余通é“ä¾›éžæ‰“击ä¹å™¨ä½¿ç”¨ã€‚" #: doc/classes/InputEventMIDI.xml msgid "" @@ -36684,6 +37044,8 @@ msgid "" "the controller number, otherwise this is zero. Controllers include devices " "such as pedals and levers." msgstr "" +"å¦‚æžœæ¶ˆæ¯æ˜¯ [code]MIDI_MESSAGE_CONTROL_CHANGE[/code],则表示控制器å·ï¼Œå¦åˆ™ä¸º" +"零。控制器包å«è¸æ¿ã€æŽ¨æ†ç‰è®¾å¤‡ã€‚" #: doc/classes/InputEventMIDI.xml msgid "" @@ -36691,6 +37053,8 @@ msgid "" "the controller value, otherwise this is zero. Controllers include devices " "such as pedals and levers." msgstr "" +"å¦‚æžœæ¶ˆæ¯æ˜¯ [code]MIDI_MESSAGE_CONTROL_CHANGE[/code],则表示控制器值,å¦åˆ™ä¸º" +"零。控制器包å«è¸æ¿ã€æŽ¨æ†ç‰è®¾å¤‡ã€‚" #: doc/classes/InputEventMIDI.xml msgid "" @@ -36700,11 +37064,15 @@ msgid "" "every number on that chart. A standard piano will have an instrument number " "of 0." msgstr "" +"这个输入事件的ä¹å™¨ã€‚这个值的范围是 0 到 127。ä¹å™¨åˆ—表请å‚考维基百科的 " +"General MIDI æ–‡ä¸çš„ä¹å™¨åˆ—表,ä¸è¿‡è¿™ä¸ªå€¼æ˜¯ä»Ž 0 å¼€å§‹çš„ï¼Œæ‰€ä»¥è¯·æŠŠé‚£å¼ è¡¨ä¸çš„æ•°å—" +"都å‡ä¸€ã€‚æ ‡å‡†é’¢ç´çš„ä¹å™¨å·ä¸º 0。" #: doc/classes/InputEventMIDI.xml +#, fuzzy msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -36715,6 +37083,14 @@ msgid "" "For more information, see the MIDI message status byte list chart linked " "above." msgstr "" +"返回表示这个 MIDI ä¿¡å·ç±»åž‹çš„值,是 MidiMessageList 枚举的æˆå‘˜ã€‚\n" +"对于在 0x80 å’Œ 0xEF 之间的 MIDI 消æ¯ï¼Œè¿™ä¸ªå€¼è¿”回的是左åŠéƒ¨åˆ†çš„æ¯”特ä½ï¼Œå¦ä¸€åŠ" +"是通é“(例:0x94 ä¼šå˜æˆ 0x9)。对于在 0xF0 到 0xFF 之间的 MIDI 消æ¯ï¼Œè¿™ä¸ªå€¼æ˜¯" +"åŽŸæ ·è¿”å›žçš„ã€‚\n" +"激活音符时会返回 [code]MIDI_MESSAGE_NOTE_ON[/code],但失活时并ä¸ä¸€å®šä¼šè¿”回 " +"[code]MIDI_MESSAGE_NOTE_OFF[/code]ï¼Œå› æ¤ä½ 的代ç 应该在ç»è¿‡ä¸€æ®µæ—¶é—´åŽå°†è¾“入处" +"ç†ä¸ºåœæ¢ã€‚\n" +"更多消æ¯è¯·å‚阅上é¢é“¾æŽ¥çš„ MIDI 消æ¯çжæ€å—节列表。" #: doc/classes/InputEventMIDI.xml msgid "" @@ -36722,12 +37098,14 @@ msgid "" "On a piano, middle C is 60, and A440 is 69, see the \"MIDI note\" column of " "the piano key frequency chart on Wikipedia for more information." msgstr "" +"这个 MIDI ä¿¡å·çš„音调索引å·ã€‚这个值的范围为 0 到 127。在钢ç´ä¸Šï¼Œä¸å¤® C 是 60," +"而 A440 是 69,更多信æ¯è¯·å‚阅维基百科钢ç´ç´é”®é¢‘率表的“MIDI 音符â€åˆ—。" #: doc/classes/InputEventMIDI.xml msgid "" "The pressure of the MIDI signal. This value ranges from 0 to 127. For many " "devices, this value is always zero." -msgstr "" +msgstr "MIDI ä¿¡å·çš„压力。这个值在 0 到 127 之间。对于很多设备,这个值总是 0。" #: doc/classes/InputEventMIDI.xml msgid "" @@ -36735,6 +37113,8 @@ msgid "" "piano, this corresponds to how quickly the key was pressed, and is rarely " "above about 110 in practice." msgstr "" +"MIDI ä¿¡å·çš„速度。这个值在 0 到 127 之间。对于钢ç´ï¼Œè¿™å¯¹åº”的是按键有多å—,实际" +"很少超过 110。" #: doc/classes/InputEventMouse.xml msgid "Base input event type for mouse events." @@ -36751,25 +37131,24 @@ msgid "" msgstr "é¼ æ ‡æŒ‰é’®æŽ©ç æ ‡è¯†ç¬¦ï¼Œæ˜¯[enum ButtonList] 按钮掩ç 之一或按ä½ç»„åˆã€‚" #: doc/classes/InputEventMouse.xml -#, fuzzy msgid "" "The global mouse position relative to the current [Viewport]. If used in " "[method Control._gui_input] and if the current [Control] is not under the " "mouse, moving it will not update this value." msgstr "" -"相对于[Viewport]çš„æœ¬åœ°å±€éƒ¨é¼ æ ‡ä½ç½®ã€‚如果在[method Control._gui_input]ä¸ä½¿ç”¨ï¼Œ" -"ä½ç½®æ˜¯ç›¸å¯¹äºŽå½“å‰å¤„äºŽé¼ æ ‡ä¸‹çš„æŽ§ä»¶[Control]。" +"ç›¸å¯¹äºŽå½“å‰ [Viewport] çš„å…¨å±€é¼ æ ‡ä½ç½®ã€‚如果在 [method Control._gui_input] ä¸ä½¿" +"ç”¨ï¼Œå¹¶ä¸”å½“å‰ [Control] ä¸åœ¨é¼ æ ‡ä¹‹ä¸‹ï¼Œç§»åŠ¨ä¸ä¼šæ›´æ–°è¿™ä¸ªå€¼ã€‚" #: doc/classes/InputEventMouse.xml -#, fuzzy msgid "" "The local mouse position relative to the [Viewport]. If used in [method " "Control._gui_input], the position is relative to the current [Control] which " "is under the mouse. If the current [Control] is not under the mouse, moving " "it will not update this value." msgstr "" -"相对于[Viewport]çš„æœ¬åœ°å±€éƒ¨é¼ æ ‡ä½ç½®ã€‚如果在[method Control._gui_input]ä¸ä½¿ç”¨ï¼Œ" -"ä½ç½®æ˜¯ç›¸å¯¹äºŽå½“å‰å¤„äºŽé¼ æ ‡ä¸‹çš„æŽ§ä»¶[Control]。" +"ç›¸å¯¹äºŽå½“å‰ [Viewport] çš„å±€éƒ¨é¼ æ ‡ä½ç½®ã€‚如果在 [method Control._gui_input] ä¸ä½¿" +"用,该ä½ç½®æ˜¯ç›¸å¯¹äºŽé¼ æ ‡ä¹‹ä¸‹çš„å½“å‰ [Control] çš„ã€‚å¦‚æžœå½“å‰ [Control] ä¸åœ¨é¼ æ ‡ä¹‹" +"下,移动ä¸ä¼šæ›´æ–°è¿™ä¸ªå€¼ã€‚" #: doc/classes/InputEventMouseButton.xml msgid "Input event type for mouse button events." @@ -37062,7 +37441,7 @@ msgstr "" #: doc/classes/InstancePlaceholder.xml msgid "Placeholder for the root [Node] of a [PackedScene]." -msgstr "[PackedScene] æ ¹ [Node] çš„å ä½ã€‚" +msgstr "[PackedScene] æ ¹ [Node] çš„å ä½ç¬¦ã€‚" #: doc/classes/InstancePlaceholder.xml msgid "" @@ -37077,18 +37456,18 @@ msgid "" "a scene with a transform will transform children relatively to their parent " "again." msgstr "" -"在编辑器ä¸ä¸ºå®žä¾‹åŒ–场景打开选项 [b]åŠ è½½ä¸ºå ä½ç¬¦[/b] 会导致在è¿è¡Œæ¸¸æˆæ—¶å°†å…¶æ›¿æ¢" -"为实例å ä½ç¬¦[InstancePlaceholder]ã€‚è¿™ä½¿å¾—å®žé™…åŠ è½½åœºæ™¯çš„æ—¶é—´å¯ä»¥æŽ¨è¿Ÿåˆ°è°ƒç”¨" -"[method replace_by_instance]ã€‚è¿™å¯¹äºŽé€šè¿‡é€‰æ‹©æ€§åŠ è½½éƒ¨åˆ†åœºæ™¯æ¥é¿å…ä¸€æ¬¡æ€§åŠ è½½å¤§" -"场景很有用。\n" -"实例å ä½ç¬¦æ²¡æœ‰å˜æ¢(transform)属性。这导致任何å节点从点(0,0)开始相对于视窗" -"进行定ä½ï¼Œè€Œä¸æ˜¯åœ¨ç¼–è¾‘å™¨ä¸æ˜¾ç¤ºçš„çˆ¶èŠ‚ç‚¹ã€‚ç”¨ä¸€ä¸ªå…·æœ‰å˜æ¢å±žæ€§çš„åœºæ™¯æ¥æ›¿æ¢å ä½" -"符,将使åèŠ‚ç‚¹å†æ¬¡ç›¸å¯¹äºŽå®ƒä»¬çš„çˆ¶èŠ‚ç‚¹è¿›è¡Œå˜æ¢ã€‚" +"在编辑器ä¸ä¸ºå®žä¾‹åŒ–的场景打开[b]åŠ è½½ä¸ºå ä½ç¬¦[/b]选项会导致在è¿è¡Œæ¸¸æˆæ—¶å°†å…¶æ›¿æ¢" +"为 InstancePlaceholderã€‚è¿™æ ·å°±å¯ä»¥å°†åœºæ™¯çš„å®žé™…åŠ è½½æŽ¨è¿Ÿåˆ°è°ƒç”¨ [method " +"replace_by_instance] æ—¶ã€‚è¿™å¯¹äºŽé€šè¿‡é€‰æ‹©æ€§åŠ è½½éƒ¨åˆ†åœºæ™¯æ¥é¿å…ä¸€æ¬¡æ€§åŠ è½½å¤§åœºæ™¯å¾ˆ" +"有用。\n" +"InstancePlaceholder ä¸å…·å¤‡å˜æ¢å±žæ€§ã€‚å› æ¤ä»»ä½•å节点都会相对于 Viewport 从 (0, " +"0) 点开始定ä½ï¼Œè€Œä¸æ˜¯åœ¨ç¼–è¾‘å™¨ä¸æ˜¾ç¤ºçš„çˆ¶èŠ‚ç‚¹ã€‚ç”¨ä¸€ä¸ªå…·æœ‰å˜æ¢å±žæ€§çš„åœºæ™¯æ¥æ›¿æ¢å " +"ä½ç¬¦ï¼Œå°†ä½¿åèŠ‚ç‚¹å†æ¬¡ç›¸å¯¹äºŽå®ƒä»¬çš„çˆ¶èŠ‚ç‚¹è¿›è¡Œå˜æ¢ã€‚" #: doc/classes/InstancePlaceholder.xml msgid "" "Not thread-safe. Use [method Object.call_deferred] if calling from a thread." -msgstr "䏿˜¯çº¿ç¨‹å®‰å…¨çš„。如果从线程调用,请使用[method Object.call_deferred]。" +msgstr "䏿˜¯çº¿ç¨‹å®‰å…¨çš„。如果从线程调用,请使用 [method Object.call_deferred]。" #: doc/classes/InstancePlaceholder.xml msgid "" @@ -37106,9 +37485,9 @@ msgid "" "loaded only if it's not loaded already. By manually loading the scene " "beforehand, delays caused by this function can be avoided." msgstr "" -"ç”¨ä½œä¸ºå‚æ•°çš„场景替æ¢è¿™ä¸ªå ä½ç¬¦ï¼Œå¦‚æžœæ²¡æœ‰ç»™å‡ºå‚æ•°ï¼Œåˆ™æ›¿æ¢åŽŸå§‹åœºæ™¯ã€‚å¯¹äºŽæ‰€æœ‰çš„" -"èµ„æºæ¥è¯´ï¼Œåªæœ‰å½“åœºæ™¯è¿˜æ²¡æœ‰è¢«åŠ è½½æ—¶æ‰ä¼šè¢«åŠ è½½ã€‚é€šè¿‡äº‹å…ˆæ‰‹åŠ¨åŠ è½½åœºæ™¯ï¼Œå¯ä»¥é¿å…" -"由这个函数引起的延迟。" +"ç”¨ä½œä¸ºå‚æ•°çš„场景替æ¢è¿™ä¸ªå ä½ç¬¦ï¼Œå¦‚æžœæ²¡æœ‰ç»™å‡ºå‚æ•°ï¼Œåˆ™ç”¨åŽŸå§‹åœºæ™¯æ›¿æ¢ã€‚与所有资" +"æºç›¸åŒï¼Œåªæœ‰å½“åœºæ™¯è¿˜æ²¡æœ‰è¢«åŠ è½½æ—¶æ‰ä¼šè¢«åŠ è½½ã€‚é€šè¿‡äº‹å…ˆæ‰‹åŠ¨åŠ è½½åœºæ™¯ï¼Œå¯ä»¥é¿å…ç”±" +"这个函数引起的延迟。" #: doc/classes/int.xml msgid "Integer built-in type." @@ -37161,8 +37540,8 @@ msgid "" "Cast a [bool] value to an integer value, [code]int(true)[/code] will be " "equals to 1 and [code]int(false)[/code] will be equals to 0." msgstr "" -"将一个[bool]å€¼è½¬æ¢æˆä¸€ä¸ªæ•´æ•°å€¼ï¼Œ[code]int(true)[/code]å°†ç‰äºŽ1," -"[code]int(false)[/code] å°†ç‰äºŽ0。" +"å°† [bool] å€¼è½¬æ¢æˆæ•´æ•°å€¼ï¼Œ[code]int(true)[/code] å°†ç‰äºŽ 1,[code]int(false)[/" +"code] å°†ç‰äºŽ 0。" #: doc/classes/int.xml msgid "" @@ -38686,10 +39065,12 @@ msgid "" "applied. See [enum MovingPlatformApplyVelocityOnLeave] constants for " "available behavior." msgstr "" +"è®¾ç½®ç¦»å¼€ç§»åŠ¨å¹³å°æ—¶è¦åº”用的行为。为了达到物ç†å‡†ç¡®ï¼Œé»˜è®¤ä¼šåº”ç”¨ä½ ç¦»å¼€çš„æœ€åŽä¸€ä¸ª" +"å¹³å°çš„速度。å¯ç”¨çš„行为请å‚阅 [enum MovingPlatformApplyVelocityOnLeave] 常é‡ã€‚" #: doc/classes/KinematicBody.xml doc/classes/KinematicBody2D.xml msgid "Add the last platform velocity when you leave a moving platform." -msgstr "" +msgstr "ç¦»å¼€ç§»åŠ¨å¹³å°æ—¶ï¼Œè¿½åŠ æœ€åŽä¸€ä¸ªå¹³å°çš„速度。" #: doc/classes/KinematicBody.xml doc/classes/KinematicBody2D.xml msgid "" @@ -38697,15 +39078,16 @@ msgid "" "downward motion is ignored. It's useful to keep full jump height even when " "the platform is moving down." msgstr "" +"ç¦»å¼€ç§»åŠ¨å¹³å°æ—¶ï¼Œè¿½åŠ æœ€åŽä¸€ä¸ªå¹³å°çš„速度,但忽略å‘下的è¿åŠ¨ã€‚å¯ä»¥ç”¨æ¥åœ¨å¹³å°å‘下" +"ç§»åŠ¨æ—¶ä¹Ÿä¿æŒå®Œæ•´çš„跳跃高度。" #: doc/classes/KinematicBody.xml doc/classes/KinematicBody2D.xml -#, fuzzy msgid "Do nothing when leaving a platform." -msgstr "使用 2D å˜æ¢æ—¶ä½¿ç”¨æ¤é€‰é¡¹ã€‚" +msgstr "ç¦»å¼€å¹³å°æ—¶ä»€ä¹ˆä¹Ÿä¸åšã€‚" #: doc/classes/KinematicBody2D.xml msgid "Kinematic body 2D node." -msgstr "2Dè¿åŠ¨ä½“èŠ‚ç‚¹ã€‚" +msgstr "2D è¿åŠ¨ä½“èŠ‚ç‚¹ã€‚" #: doc/classes/KinematicBody2D.xml msgid "" @@ -41420,9 +41802,10 @@ msgid "Returns the number of faces in this [Mesh]." msgstr "返回这个[Mesh]ä¸çš„颿•°ã€‚" #: doc/classes/MeshDataTool.xml +#, fuzzy msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" "返回与给定é¢å…³è”的指定边。\n" "Edge傿•°å¿…é¡»å°äºŽç‰äºŽ2ï¼Œå› ä¸ºé¢åªæœ‰3æ¡è¾¹ã€‚" @@ -41436,9 +41819,11 @@ msgid "Calculates and returns the face normal of the given face." msgstr "计算并返回给定é¢çš„颿³•线。" #: doc/classes/MeshDataTool.xml +#, fuzzy msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" "返回给定é¢çš„æŒ‡å®šé¡¶ç‚¹ã€‚\n" "é¡¶ç‚¹å‚æ•°å¿…é¡»å°äºŽç‰äºŽ2ï¼Œå› ä¸ºé¢åŒ…å«3个顶点。" @@ -41695,9 +42080,10 @@ msgid "The [Mesh] that will be drawn by the [MeshInstance2D]." msgstr "[Mesh]将由[MeshInstance2D]绘制。" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml +#, fuzzy msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -42553,7 +42939,6 @@ msgid "Mesh-based navigation and pathfinding node." msgstr "åŸºäºŽç½‘æ ¼çš„å¯¼èˆªå’Œå¯»è·¯èŠ‚ç‚¹ã€‚" #: doc/classes/Navigation.xml -#, fuzzy msgid "" "Provides navigation and pathfinding within a collection of " "[NavigationMesh]es. By default, these will be automatically collected from " @@ -42561,11 +42946,9 @@ msgid "" "class also assists with aligning navigation agents with the meshes they are " "navigating on." msgstr "" -"在[NavigationMesh]的集åˆä¸æä¾›å¯¼èˆªå’Œå¯»è·¯åŠŸèƒ½ã€‚é»˜è®¤æƒ…å†µä¸‹ï¼Œè¿™äº›å°†è‡ªåŠ¨ä»Žå" -"[NavigationMeshInstance]èŠ‚ç‚¹ä¸æ”¶é›†ï¼Œä¹Ÿå¯ä»¥é€šè¿‡[method navmesh_add]峿—¶æ·»åŠ ã€‚" -"除了基本的寻路之外,这个类还能帮助导航代ç†ä¸Žå…¶æ‰€å¯¼èˆªçš„ç½‘æ ¼å¯¹é½ã€‚\n" -"[b]注æ„:[/b] ç›®å‰çš„å¯¼èˆªç³»ç»Ÿæœ‰è®¸å¤šå·²çŸ¥çš„é—®é¢˜ï¼Œå¹¶ä¸æ€»æ˜¯èƒ½åƒé¢„æœŸçš„é‚£æ ·è¿”å›žæœ€ä½³" -"路径。这些问题将在Godot 4.0ä¸å¾—到解决。" +"在 [NavigationMesh] 的集åˆä¸æä¾›å¯¼èˆªå’Œå¯»è·¯åŠŸèƒ½ã€‚é»˜è®¤æƒ…å†µä¸‹ï¼Œè¿™äº›å°†è‡ªåŠ¨ä»Žå " +"[NavigationMeshInstance] èŠ‚ç‚¹ä¸æ”¶é›†ï¼Œä¹Ÿå¯ä»¥é€šè¿‡ [method navmesh_add] 峿—¶æ·»" +"åŠ ã€‚é™¤äº†åŸºæœ¬çš„å¯»è·¯ä¹‹å¤–ï¼Œè¿™ä¸ªç±»è¿˜èƒ½å¸®åŠ©å¯¼èˆªä»£ç†ä¸Žå…¶æ‰€å¯¼èˆªçš„ç½‘æ ¼å¯¹é½ã€‚" #: doc/classes/Navigation.xml doc/classes/NavigationMesh.xml #: doc/classes/NavigationServer.xml @@ -42588,14 +42971,12 @@ msgstr "" "代ç†ã€‚" #: doc/classes/Navigation.xml -#, fuzzy msgid "" "Returns the owner of the [NavigationMesh] which contains the navigation " "point closest to the point given. This is usually a [NavigationMeshInstance]." msgstr "" "è¿”å›žåŒ…å«æœ€æŽ¥è¿‘给定点的导航点的 [NavigationMesh] 的所有者。这通常是一个 " -"[NavigationMeshInstance]。对于通过 [method navmesh_add] æ·»åŠ çš„ç½‘æ ¼ï¼Œè¿”å›žç»™å®š" -"的所有者(如果çœç•¥ [code]owner[/code] 傿•°ï¼Œåˆ™è¿”回 [code]null[/code])。" +"[NavigationMeshInstance]。" #: doc/classes/Navigation.xml msgid "" @@ -42608,18 +42989,15 @@ msgstr "" "å¯¼èˆªç½‘æ ¼ä¹‹é—´çš„äº¤ç‚¹ã€‚å¦‚æžœæ‰¾åˆ°å¤šä¸ªäº¤ç‚¹ï¼Œåˆ™è¿”å›žæœ€æŽ¥è¿‘çº¿æ®µèµ·ç‚¹çš„äº¤ç‚¹ã€‚" #: doc/classes/Navigation.xml -#, fuzzy msgid "" "Returns the path between two given points. Points are in local coordinate " "space. If [code]optimize[/code] is [code]true[/code] (the default), the " "agent properties associated with each [NavigationMesh] (radius, height, " "etc.) are considered in the path calculation, otherwise they are ignored." msgstr "" -"è¿”å›žä¸¤ä¸ªç»™å®šç‚¹ä¹‹é—´çš„è·¯å¾„ã€‚ç‚¹æ˜¯åœ¨å±€éƒ¨åæ ‡ç©ºé—´ä¸ã€‚如果[code]optimize[/code]是" -"[code]true[/code](默认),与æ¯ä¸ª[NavigationMesh]相关的代ç†å±žæ€§ï¼ˆåŠå¾„ã€é«˜åº¦" -"ç‰ï¼‰åœ¨è·¯å¾„计算ä¸è¢«è€ƒè™‘,å¦åˆ™å…¶è¢«å¿½ç•¥ã€‚\n" -"[b]注æ„:[/b] 这个方法有已知的问题,ç»å¸¸ä¼šè¿”å›žéžæœ€ä½³çš„路径。这些问题将在" -"Godot 4.0ä¸å¾—到修æ£ã€‚" +"è¿”å›žä¸¤ä¸ªç»™å®šç‚¹ä¹‹é—´çš„è·¯å¾„ã€‚ç‚¹æ˜¯åœ¨å±€éƒ¨åæ ‡ç©ºé—´ä¸ã€‚如果 [code]optimize[/code] " +"是 [code]true[/code](默认),与æ¯ä¸ª [NavigationMesh] 相关的代ç†å±žæ€§ï¼ˆåŠå¾„ã€" +"高度ç‰ï¼‰åœ¨è·¯å¾„计算ä¸è¢«è€ƒè™‘,å¦åˆ™å…¶è¢«å¿½ç•¥ã€‚" #: doc/classes/Navigation.xml doc/classes/NavigationMesh.xml msgid "The XZ plane cell size to use for fields." @@ -42628,7 +43006,7 @@ msgstr "ç”¨äºŽå—æ®µçš„XZå¹³é¢å•元尺寸。" #: doc/classes/Navigation.xml doc/classes/Navigation2D.xml msgid "" "This value is used to detect the near edges to connect compatible regions." -msgstr "" +msgstr "该值用于检测相近的边界,连接兼容的地区。" #: doc/classes/Navigation.xml msgid "" @@ -42640,20 +43018,17 @@ msgstr "" #: doc/classes/Navigation2D.xml msgid "2D navigation and pathfinding node." -msgstr "2D导航和寻路节点。" +msgstr "2D 导航和寻路节点。" #: doc/classes/Navigation2D.xml -#, fuzzy msgid "" "Navigation2D provides navigation and pathfinding within a 2D area, specified " "as a collection of [NavigationPolygon] resources. By default, these are " "automatically collected from child [NavigationPolygonInstance] nodes." msgstr "" -"Navigation2D在2D区域内æä¾›å¯¼èˆªå’Œå¯»è·¯ï¼ŒæŒ‡å®šä¸º[NavigationPolygon]资æºçš„集åˆã€‚默" -"认情况下,这些资æºè‡ªåŠ¨ä»Žå[NavigationPolygonInstance]èŠ‚ç‚¹ä¸æ”¶é›†ï¼Œä½†å…¶ä¹Ÿå¯ä»¥é€š" -"过[method navpoly_add]峿—¶æ·»åŠ ã€‚\n" -"[b]注æ„:[/b] 当å‰çš„å¯¼èˆªç³»ç»Ÿæœ‰è®¸å¤šå·²çŸ¥çš„é—®é¢˜ï¼Œå¹¶ä¸æ€»æ˜¯èƒ½åƒé¢„æœŸçš„é‚£æ ·è¿”å›žæœ€ä½³" -"的路径。这些问题将在Godot 4.0ä¸å¾—到解决。" +"Navigation2D 在 2D 区域内æä¾›å¯¼èˆªå’Œå¯»è·¯ï¼Œè¯¥åŒºåŸŸä»¥ [NavigationPolygon] 资æºåˆ" +"é›†çš„å½¢å¼æŒ‡å®šã€‚é»˜è®¤æƒ…å†µä¸‹ï¼Œè¿™äº›èµ„æºæ˜¯è‡ªåŠ¨ä»Žå项 [NavigationPolygonInstance] 节" +"ç‚¹ä¸æ”¶é›†çš„。" #: doc/classes/Navigation2D.xml doc/classes/Navigation2DServer.xml #: doc/classes/NavigationPolygon.xml @@ -42661,37 +43036,30 @@ msgid "https://godotengine.org/asset-library/asset/117" msgstr "https://godotengine.org/asset-library/asset/117" #: doc/classes/Navigation2D.xml -#, fuzzy msgid "" "Returns the owner of the [NavigationPolygon] which contains the navigation " "point closest to the point given. This is usually a " "[NavigationPolygonInstance]." msgstr "" "è¿”å›žåŒ…å«æœ€æŽ¥è¿‘给定点的导航点的 [NavigationPolygon] 的所有者。这通常是一个 " -"[NavigationPolygonInstance]。对于通过 [method navpoly_add] æ·»åŠ çš„å¤šè¾¹å½¢ï¼Œè¿”å›ž" -"给定的所有者(如果çœç•¥ [code]owner[/code] 傿•°ï¼Œåˆ™è¿”回 [code]null[/code])。" +"[NavigationPolygonInstance]。" #: doc/classes/Navigation2D.xml -#, fuzzy msgid "" "Returns the path between two given points. Points are in local coordinate " "space. If [code]optimize[/code] is [code]true[/code] (the default), the path " "is smoothed by merging path segments where possible." msgstr "" -"è¿”å›žä¸¤ä¸ªç»™å®šç‚¹ä¹‹é—´çš„è·¯å¾„ã€‚ç‚¹æ˜¯åœ¨å±€éƒ¨åæ ‡ç©ºé—´ä¸ã€‚如果[code]optimize[/code]为" -"[code]true[/code](默认值),路径将尽å¯èƒ½åœ°åˆå¹¶è·¯å¾„段,从而平滑。\n" -"[b]注æ„:[/b] 这个方法有已知的问题,ç»å¸¸ä¼šè¿”å›žéžæœ€ä½³çš„路径。这些问题将在" -"Godot 4.0ä¸å¾—到解决。" +"è¿”å›žä¸¤ä¸ªç»™å®šç‚¹ä¹‹é—´çš„è·¯å¾„ã€‚ç‚¹æ˜¯åœ¨å±€éƒ¨åæ ‡ç©ºé—´ä¸ã€‚如果 [code]optimize[/code] " +"为 [code]true[/code](默认值),路径将尽å¯èƒ½åœ°åˆå¹¶è·¯å¾„段,从而平滑。" #: doc/classes/Navigation2D.xml -#, fuzzy msgid "The XY plane cell size to use for fields." -msgstr "ç”¨äºŽå—æ®µçš„XZå¹³é¢å•元尺寸。" +msgstr "ç”¨äºŽå—æ®µçš„ XZ å¹³é¢å•元尺寸。" #: doc/classes/Navigation2DServer.xml -#, fuzzy msgid "Server interface for low-level 2D navigation access." -msgstr "低级音频访问的æœåŠ¡å™¨æŽ¥å£ã€‚" +msgstr "访问底层 2D 导航的æœåŠ¡å™¨æŽ¥å£ã€‚" #: doc/classes/Navigation2DServer.xml msgid "" @@ -42714,25 +43082,34 @@ msgid "" "phase. This means that you can request any change to the map, using any " "thread, without worrying." msgstr "" +"Navigation2DServer 是负责所有 2D 导航的æœåŠ¡å™¨ï¼Œå¤„ç†çš„对象有地图(map)ã€åœ°åŒº" +"(region)ã€ä»£ç†ï¼ˆagent)。\n" +"地图是由地区组æˆçš„,地区åˆç”±å¯¼èˆªå¤šè¾¹å½¢ç»„æˆã€‚å®ƒä»¬ä¸€åŒæž„æˆäº† 2D 世界ä¸çš„å¯å¯¼èˆª" +"区域。两个地区必须共有一æ¡ç›¸ä¼¼çš„边界(edge)æ‰èƒ½ç›¸è¿žã€‚如果一æ¡è¾¹ç•Œçš„两个顶点" +"(vertex)与å¦ä¸€æ¡è¾¹ç•Œçš„对应顶点的è·ç¦»å°äºŽ [member Navigation." +"edge_connection_margin],则认为这两æ¡è¾¹ç•Œç›¸è¿žã€‚\n" +"è¦ä½¿ç”¨é˜²æ’žç³»ç»Ÿï¼Œå¯ä»¥ä½¿ç”¨ä»£ç†ã€‚ä½ å¯ä»¥è®¾ç½®ä»£ç†çš„ç›®æ ‡é€Ÿåº¦ï¼ŒæœåŠ¡å™¨å°±ä¼šä½¿ç”¨ä¿®æ£åŽ" +"的速度触å‘回调。\n" +"[b]注æ„:[/b]防撞系统会忽略地区。直接使用修æ£åŽçš„速度å¯èƒ½ä¼šå°†ä»£ç†æŽ¨åˆ°å¯å¯¼èˆªåŒº" +"åŸŸä¹‹å¤–ã€‚è¿™æ˜¯é˜²æ’žç³»ç»Ÿçš„ç¼ºé™·ï¼Œæ›´å¤æ‚的情况å¯èƒ½éœ€è¦ç”¨åˆ°ç‰©ç†å¼•擎。\n" +"æœåŠ¡å™¨ä¼šè®°å½•æ‰€æœ‰çš„è°ƒç”¨ï¼Œåœ¨åŒæ¥é˜¶æ®µç»Ÿä¸€æ‰§è¡Œã€‚è¿™æ„味ç€ä½ å¯ä»¥æ”¾å¿ƒå¤§èƒ†åœ°ä»Žä»»ä½•线" +"程ä¸è¯·æ±‚对地图进行任何修改。" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Creates the agent." -msgstr "创建一个 [HingeJoint]关节。" +msgstr "创建代ç†ã€‚" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Returns [code]true[/code] if the map got changed the previous frame." -msgstr "如果脚本å¯ä»¥å®žä¾‹åŒ–,则返回 [code]true[/code]。" +msgstr "如果地图在上一帧å‘生了改å˜ï¼Œåˆ™è¿”回 [code]true[/code]。" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "Callback called at the end of the RVO process." -msgstr "" +msgstr "在 RVO å¤„ç†æœ«å°¾è°ƒç”¨çš„回调。" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Puts the agent in the map." -msgstr "返回输入的æ£åˆ‡å€¼ã€‚" +msgstr "å°†ä»£ç†æ”¾å…¥åœ°å›¾ä¸ã€‚" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "" @@ -42740,11 +43117,12 @@ msgid "" "navigation. The larger this number, the longer the running time of the " "simulation. If the number is too low, the simulation will not be safe." msgstr "" +"设置在导航ä¸ï¼Œè¯¥ä»£ç†æ‰€è€ƒè™‘的其他代ç†çš„æœ€å¤§æ•°é‡ã€‚这个数越大,模拟的è¿è¡Œæ—¶é—´è¶Š" +"长。如果这个数太å°ï¼Œåˆ™æ¨¡æ‹Ÿä¼šä¸å®‰å…¨ã€‚" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the maximum speed of the agent. Must be positive." -msgstr "设置自动图å—çš„[enum BitmaskMode]ä½æŽ©ç æ¨¡å¼ã€‚" +msgstr "设置该代ç†çš„æœ€å¤§é€Ÿåº¦ã€‚å¿…é¡»ä¸ºæ£æ•°ã€‚" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "" @@ -42752,21 +43130,20 @@ msgid "" "the navigation. The larger this number, the longer the running time of the " "simulation. If the number is too low, the simulation will not be safe." msgstr "" +"设置在导航ä¸ï¼Œè¯¥ä»£ç†æ‰€è€ƒè™‘的其他代ç†çš„æœ€å¤§è·ç¦»ã€‚这个数越大,模拟的è¿è¡Œæ—¶é—´è¶Š" +"长。如果这个数太å°ï¼Œåˆ™æ¨¡æ‹Ÿä¼šä¸å®‰å…¨ã€‚" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the position of the agent in world space." -msgstr "设置给定顶点的ä½ç½®ã€‚" +msgstr "设置该代ç†åœ¨ä¸–界空间ä¸çš„ä½ç½®ã€‚" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the radius of the agent." -msgstr "设置给定顶点的法线。" +msgstr "设置该代ç†çš„åŠå¾„。" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the new target velocity." -msgstr "设置给定顶点的骨架。" +msgstr "è®¾ç½®æ–°çš„ç›®æ ‡é€Ÿåº¦ã€‚" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "" @@ -42776,96 +43153,84 @@ msgid "" "agents, but the less freedom this agent has in choosing its velocities. Must " "be positive." msgstr "" +"考虑其他代ç†çš„å‰æä¸‹ï¼Œè¯¥ä»£ç†çš„速度的最çŸå®‰å…¨æ—¶é—´ï¼Œè¿™ä¸ªé€Ÿåº¦æ˜¯é€šè¿‡æ¨¡æ‹Ÿå¾—到的。" +"这个数越大,该代ç†å“应其他代ç†çš„速度越快,但该代ç†é€‰æ‹©é€Ÿåº¦çš„自由度也越å°ã€‚å¿…" +"é¡»ä¸ºæ£æ•°ã€‚" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the current velocity of the agent." -msgstr "è¿”å›žè¡¥é—´çš„å½“å‰æ—¶é—´ã€‚" +msgstr "设置该代ç†çš„当å‰é€Ÿåº¦ã€‚" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Destroys the given RID." -msgstr "ç§»é™¤ç»™å®šçš„å›¾å— ID。" +msgstr "销æ¯ç»™å®šçš„ RID。" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Create a new map." -msgstr "创建一个[Area]区域。" +msgstr "åˆ›å»ºä¸€å¼ æ–°åœ°å›¾ã€‚" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Returns the map cell size." -msgstr "返回数组大å°ã€‚" +msgstr "返回地图的å•å…ƒæ ¼å¤§å°ã€‚" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "" "Returns the point closest to the provided [code]to_point[/code] on the " "navigation mesh surface." -msgstr "" -"返回索引[code]point[/code]处的点在索引[code]triangle[/code]的三角形ä¸çš„ä½ç½®ã€‚" +msgstr "è¿”å›žåœ¨å¯¼èˆªç½‘æ ¼è¡¨é¢ä¸Šä¸Žæä¾›çš„ [code]to_point[/code] è·ç¦»æœ€è¿‘的点。" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "" "Returns the owner region RID for the point returned by [method " "map_get_closest_point]." -msgstr "返回æ£åœ¨ä½¿ç”¨çš„输入端å£çš„æ•°é‡ã€‚替代[method get_free_input_port_id]。" +msgstr "返回由 [method map_get_closest_point] 返回的点的所有者地区的 RID。" #: doc/classes/Navigation2DServer.xml msgid "" "Returns the edge connection margin of the map. The edge connection margin is " "a distance used to connect two regions." -msgstr "" +msgstr "返回地图的边界连接边è·ã€‚è¾¹ç•Œè¿žæŽ¥è¾¹è·æ˜¯ç”¨äºŽè¿žæŽ¥ä¸¤ä¸ªåœ°åŒºçš„è·ç¦»ã€‚" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Returns the navigation path to reach the destination from the origin." -msgstr "返回图å—的导航多边形。" +msgstr "返回从原点到终点的导航路径。" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Returns [code]true[/code] if the map is active." -msgstr "如果选择处于活动状æ€ï¼Œåˆ™è¿”回 [code]true[/code]。" +msgstr "如果地图处于活动状æ€ï¼Œåˆ™è¿”回 [code]true[/code]。" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the map active." -msgstr "åœæ¢å®šæ—¶å™¨ã€‚" +msgstr "设置地图的激活æ€ã€‚" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Set the map cell size used to weld the navigation mesh polygons." -msgstr "è¿”å›žåº”ç”¨äºŽè¯¥é¡¹å¯¼èˆªç½‘æ ¼çš„è½¬æ¢ã€‚" +msgstr "è®¾ç½®ç”¨äºŽç„ŠæŽ¥å¯¼èˆªç½‘æ ¼å¤šè¾¹å½¢çš„åœ°å›¾å•å…ƒæ ¼å¤§å°ã€‚" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml msgid "" "Set the map edge connection margin used to weld the compatible region edges." -msgstr "" +msgstr "设置用于焊接兼容地区边界的地图边界连接边è·ã€‚" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Creates a new region." -msgstr "创建一个[Area]区域。" +msgstr "创建一个新的地区。" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the map for the region." -msgstr "设置给定边的元数æ®ã€‚" +msgstr "设置该地区的地图。" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the navigation mesh for the region." -msgstr "设置æ¤é¡¹çš„å¯¼èˆªç½‘æ ¼ã€‚" +msgstr "è®¾ç½®è¯¥åœ°å›¾çš„å¯¼èˆªç½‘æ ¼ã€‚" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the global transformation for the region." -msgstr "è®¾ç½®è§†çª—çš„å…¨å±€å˜æ¢çŸ©é˜µã€‚" +msgstr "è®¾ç½®è¯¥åœ°åŒºçš„å…¨å±€å˜æ¢ã€‚" #: doc/classes/NavigationAgent.xml msgid "3D agent used in navigation for collision avoidance." -msgstr "" +msgstr "在导航ä¸ç”¨äºŽé˜²æ’žçš„ 3D 代ç†ã€‚" #: doc/classes/NavigationAgent.xml msgid "" @@ -42876,6 +43241,10 @@ msgid "" "child of a [Navigation] node, or using [method set_navigation]. " "[NavigationAgent] is physics safe." msgstr "" +"导航ä¸ä½¿ç”¨çš„ 3D 代ç†ï¼Œå¯ä»¥åœ¨å‰å¾€æŸä¸ªä½ç½®æ—¶èº²é¿é™æ€å’ŒåЍæ€éšœç¢ç‰©ã€‚躲é¿åЍæ€éšœç¢" +"物使用的是 RVO(Reciprocal Velocity Obstacles,相对速度障ç¢ç‰©ï¼‰é˜²æ’žç®—法。代ç†" +"需è¦å¯¼èˆªæ•°æ®æ‰èƒ½æ£ç¡®å·¥ä½œã€‚å¯ä»¥é€šè¿‡è®©ä»£ç†æˆä¸º [Navigation] 节点的å项实现,也" +"å¯ä»¥ä½¿ç”¨ [method set_navigation]。[NavigationAgent] 是物ç†å®‰å…¨çš„。" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -42883,32 +43252,33 @@ msgid "" "position. The user must set the target location with [method " "set_target_location] in order for this to be accurate." msgstr "" +"è¿”å›žä¸Žç›®æ ‡ä½ç½®çš„è·ç¦»ï¼Œä½¿ç”¨çš„æ˜¯ä»£ç†çš„全局ä½ç½®ã€‚用户必须使用 [method " +"set_target_location] è®¾ç½®ç›®æ ‡ä½ç½®ï¼Œæ‰èƒ½èŽ·å¾—ç²¾ç¡®ç»“æžœã€‚" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " "best to check this each frame." msgstr "" +"返回å¯åˆ°è¾¾çš„æœ€ç»ˆä½ç½®çš„å…¨å±€åæ ‡ã€‚å¦‚æžœå¯¼èˆªè·¯å¾„ç”±äºŽä»»ä½•åŽŸå› å‘生改å˜ï¼Œè¿™ä¸ªä½ç½®ä¹Ÿ" +"å¯èƒ½å‘生å˜åŒ–ã€‚å› æ¤ï¼Œæœ€å¥½æ¯ä¸€å¸§éƒ½æ£€æŸ¥ä¸€ä¸‹ã€‚" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "Returns the path from start to finish in global coordinates." -msgstr "返回全局å±å¹•åæ ‡ä¸çš„å¯è§çŸ©å½¢ã€‚" +msgstr "è¿”å›žä»Žèµ·ç‚¹åˆ°ç»ˆç‚¹çš„è·¯å¾„ï¼Œä½¿ç”¨å…¨å±€åæ ‡ã€‚" #: doc/classes/NavigationAgent.xml -#, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector3Array]." -msgstr "以 [PoolVector3Array] 的形å¼è¿”回缓å˜çš„点。" +msgstr "返回该代ç†å½“å‰ä½äºŽå¯¼èˆªè·¯å¾„ [PoolVector3Array] ä¸çš„哪个索引ä½ç½®ã€‚" #: doc/classes/NavigationAgent.xml -#, fuzzy msgid "" "Returns the [Navigation] node that the agent is using for its navigation " "system." -msgstr "返回指定å称的动画节点。" +msgstr "返回该代ç†çš„导航系统所使用的 [Navigation] 节点。" #: doc/classes/NavigationAgent.xml msgid "" @@ -42916,28 +43286,28 @@ msgid "" "that there are no static objects in the way. If the agent does not have a " "navigation path, it will return the origin of the agent's parent." msgstr "" +"返回å¯ä»¥ç§»åŠ¨è‡³çš„ [Vector3] å…¨å±€åæ ‡ï¼Œç¡®ä¿ä¸é€”æ²¡æœ‰é™æ€ç‰©ä½“é˜»æŒ¡ã€‚å¦‚æžœä»£ç†æ²¡æœ‰å¯¼" +"航路径,则会返回代ç†çˆ¶èŠ‚ç‚¹çš„åŽŸç‚¹ã€‚" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "" "Returns the user-defined target location (set with [method " "set_target_location])." -msgstr "返回用[method set_size_override]设置的尺寸é‡å†™ã€‚" +msgstr "è¿”å›žç”¨æˆ·å®šä¹‰çš„ç›®æ ‡ä½ç½®ï¼ˆä½¿ç”¨ [method set_target_location] 设置)。" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "" "Returns [code]true[/code] if the navigation path's final location has been " "reached." -msgstr "返回[code]true[/code]是å¦å¯¹æŒ‡å®šè·¯å¾„进行过滤。" +msgstr "如果到达了导航路径的终点ä½ç½®ï¼Œåˆ™è¿”回 [code]true[/code]。" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "" "Returns [code]true[/code] if the target location is reachable. The target " "location is set using [method set_target_location]." msgstr "" -"如果å¯ç”¨äº†å°ºå¯¸é‡å†™ï¼Œè¿”回[code]true[/code]。å‚阅[method set_size_override]。" +"å¦‚æžœç›®æ ‡ä½ç½®å¯è¾¾ï¼Œåˆ™è¿”回 [code]true[/code]ã€‚ç›®æ ‡ä½ç½®ä½¿ç”¨ [method " +"set_target_location] 设置。" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -42946,51 +43316,54 @@ msgid "" "possible to reach the target location. It should always be possible to reach " "the final location though. See [method get_final_location]." msgstr "" +"å¦‚æžœå·²åˆ°è¾¾ç›®æ ‡ä½ç½®ï¼Œåˆ™è¿”回 [code]true[/code]ã€‚ç›®æ ‡ä½ç½®ä½¿ç”¨ [method " +"set_target_location] è®¾ç½®ã€‚ç›®æ ‡ä½ç½®å¹¶ä¸æ€»æ˜¯å¯è¾¾ã€‚但终点ä½ç½®åº”该总是å¯è¾¾çš„。请" +"å‚阅 [method get_final_location]。" #: doc/classes/NavigationAgent.xml msgid "" "Sets the [Navigation] node used by the agent. Useful when you don't want to " "make the agent a child of a [Navigation] node." msgstr "" +"è®¾ç½®ä»£ç†æ‰€ä½¿ç”¨çš„ [Navigation] 节点。å¯ä»¥åœ¨ä½ 䏿ƒ³è®©ä»£ç†ä½œä¸º [Navigation] 节点" +"çš„å节点时使用。" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Sets the user desired final location. This will clear the current navigation " "path." -msgstr "" +msgstr "设置用户期望的终点ä½ç½®ã€‚会将当å‰å¯¼èˆªè·¯å¾„清空。" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" +"å°†ä¼ å…¥çš„é€Ÿåº¦å‘é€ç»™é˜²æ’žç®—æ³•ã€‚ç®—æ³•ä¼šä¸ºäº†é˜²æ¢æ’žå‡»è€Œè°ƒæ•´é€Ÿåº¦ã€‚速度的调整完æˆåŽï¼Œ" +"ä¼šè§¦å‘ [signal velocity_computed] ä¿¡å·ã€‚" #: doc/classes/NavigationAgent.xml -#, fuzzy msgid "The agent height offset to match the navigation mesh height." -msgstr "返回图å—的导航多边形的åç§»é‡ã€‚" +msgstr "代ç†çš„高度åç§»é‡ï¼Œç”¨äºŽåŒ¹é…å¯¼èˆªç½‘æ ¼çš„é«˜åº¦ã€‚" #: doc/classes/NavigationAgent.xml msgid "" "Ignores collisions on the Y axis. Must be [code]true[/code] to move on a " "horizontal plane." -msgstr "" +msgstr "忽略 Y 轴上的碰撞。在水平é¢ä¸Šç§»åŠ¨æ—¶å¿…é¡»ä¸º [code]true[/code]。" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "The maximum number of neighbors for the agent to consider." -msgstr "自动æ›å…‰çš„æœ€å¤§äº®åº¦å€¼ã€‚" +msgstr "ä»£ç†æ‰€éœ€è€ƒè™‘的最大邻居数。" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "The maximum speed that an agent can move." -msgstr "曲线能达到的最大值。" +msgstr "ä»£ç†æ‰€èƒ½è¾¾åˆ°çš„æœ€å¤§ç§»åŠ¨é€Ÿåº¦ã€‚" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "The distance to search for other agents." -msgstr "实例没有类型。" +msgstr "æœç´¢å…¶ä»–代ç†çš„è·ç¦»ã€‚" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -42998,11 +43371,12 @@ msgid "" "final location. This can happen due to trying to avoid collisions. When the " "maximum distance is exceeded, it recalculates the ideal path." msgstr "" +"å…许代ç†åç¦»ç†æƒ³è·¯å¾„的最大è·ç¦»ã€‚å¯èƒ½ä¸ºäº†é˜²æ’žè€Œäº§ç”Ÿå离。超出最大è·ç¦»æ—¶ï¼Œä¼šé‡" +"æ–°è®¡ç®—ç†æƒ³è·¯å¾„。" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "The radius of the agent." -msgstr "圆柱体的åŠå¾„。" +msgstr "代ç†çš„åŠå¾„。" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -43010,6 +43384,8 @@ msgid "" "will allow an agent to not have to hit a point on the path exactly, but in " "the area." msgstr "" +"è®¤ä¸ºåˆ°è¾¾ç›®æ ‡çš„è·ç¦»é˜ˆå€¼ã€‚å¯ä»¥è®©ä»£ç†æ— 需精准到达路径上的æŸä¸ªç‚¹ï¼Œåˆ°è¾¾æŸä¸ªåŒºåŸŸå³" +"å¯ã€‚" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -43019,33 +43395,36 @@ msgid "" "other agents, but the less freedom in choosing its velocities. Must be " "positive." msgstr "" +"考虑其他代ç†çš„å‰æä¸‹ï¼Œè¯¥ä»£ç†çš„速度的最çŸå®‰å…¨æ—¶é—´ï¼Œè¿™ä¸ªé€Ÿåº¦æ˜¯ç”±é˜²æ’žç®—法计算而" +"æ¥çš„。这个数越大,该代ç†å“应其他代ç†çš„速度越快,但选择速度的自由度也越å°ã€‚å¿…" +"é¡»ä¸ºæ£æ•°ã€‚" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "Notifies when the final location is reached." -msgstr "å½“åŠ¨ç”»æ’æ”¾ç»“æŸæ—¶é€šçŸ¥ã€‚" +msgstr "抵达终点ä½ç½®æ—¶å‘出通知。" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Notifies when the navigation path changes. This can be triggered by the " "navigation system or by the user changing the path." msgstr "" +"å¯¼èˆªè·¯å¾„æ”¹å˜æ—¶å‘出通知。å¯ä»¥ç”±å¯¼èˆªç³»ç»Ÿè§¦å‘,也å¯ä»¥ç”±ç”¨æˆ·å¯¹è·¯å¾„的修改触å‘。" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Notifies when the player-defined target, set with [method " "set_target_location], is reached." -msgstr "" +msgstr "抵达由 [method set_target_location] è®¾ç½®çš„çŽ©å®¶å®šä¹‰ç›®æ ‡æ—¶å‘出通知。" #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Notifies when the collision avoidance velocity is calculated after a call to " "[method set_velocity]." -msgstr "" +msgstr "调用 [method set_velocity] åŽï¼Œè®¡ç®—出防撞速度时å‘出通知。" #: doc/classes/NavigationAgent2D.xml msgid "2D agent used in navigation for collision avoidance." -msgstr "" +msgstr "在导航ä¸ç”¨äºŽé˜²æ’žçš„ 2D 代ç†ã€‚" #: doc/classes/NavigationAgent2D.xml msgid "" @@ -43056,26 +43435,22 @@ msgid "" "child of a [Navigation2D] node, or using [method set_navigation]. " "[NavigationAgent2D] is physics safe." msgstr "" +"导航ä¸ä½¿ç”¨çš„ 2D 代ç†ï¼Œå¯ä»¥åœ¨å‰å¾€æŸä¸ªä½ç½®æ—¶èº²é¿é™æ€å’ŒåЍæ€éšœç¢ç‰©ã€‚躲é¿åЍæ€éšœç¢" +"物使用的是 RVO(Reciprocal Velocity Obstacles,相对速度障ç¢ç‰©ï¼‰é˜²æ’žç®—法。代ç†" +"需è¦å¯¼èˆªæ•°æ®æ‰èƒ½æ£ç¡®å·¥ä½œã€‚å¯ä»¥é€šè¿‡è®©ä»£ç†æˆä¸º [Navigation2D] 节点的å项实现," +"也å¯ä»¥ä½¿ç”¨ [method set_navigation]。[NavigationAgent2D] 是物ç†å®‰å…¨çš„。" #: doc/classes/NavigationAgent2D.xml msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml -#, fuzzy -msgid "" "Returns which index the agent is currently on in the navigation path's " "[PoolVector2Array]." -msgstr "以[PoolVector2Array]的形å¼è¿”回缓å˜çš„点。" +msgstr "返回该代ç†å½“å‰ä½äºŽå¯¼èˆªè·¯å¾„ [PoolVector2Array] ä¸çš„哪个索引ä½ç½®ã€‚" #: doc/classes/NavigationAgent2D.xml -#, fuzzy msgid "" "Returns the [Navigation2D] node that the agent is using for its navigation " "system." -msgstr "返回指定å称的动画节点。" +msgstr "返回该代ç†çš„导航系统所使用的 [Navigation2D] 节点。" #: doc/classes/NavigationAgent2D.xml msgid "" @@ -43083,19 +43458,16 @@ msgid "" "that there are no static objects in the way. If the agent does not have a " "navigation path, it will return the position of the agent's parent." msgstr "" +"返回å¯ä»¥ç§»åŠ¨è‡³çš„ [Vector2] å…¨å±€åæ ‡ï¼Œç¡®ä¿ä¸é€”æ²¡æœ‰é™æ€ç‰©ä½“é˜»æŒ¡ã€‚å¦‚æžœä»£ç†æ²¡æœ‰å¯¼" +"航路径,则会返回代ç†çˆ¶èŠ‚ç‚¹çš„åŽŸç‚¹ã€‚" #: doc/classes/NavigationAgent2D.xml msgid "" "Sets the [Navigation2D] node used by the agent. Useful when you don't want " "to make the agent a child of a [Navigation2D] node." msgstr "" - -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" +"è®¾ç½®ä»£ç†æ‰€ä½¿ç”¨çš„ [Navigation2D] 节点。å¯ä»¥åœ¨ä½ 䏿ƒ³è®©ä»£ç†ä½œä¸º [Navigation2D] " +"节点的å节点时使用。" #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." @@ -43395,23 +43767,21 @@ msgstr "表示[enum SourceGeometryMode]枚举的大å°ã€‚" #: doc/classes/NavigationMeshGenerator.xml msgid "This class is responsible for creating and clearing navigation meshes." -msgstr "" +msgstr "è¿™ä¸ªç±»è´Ÿè´£å¯¼èˆªç½‘æ ¼çš„åˆ›å»ºå’Œæ¸…ç†ã€‚" #: doc/classes/NavigationMeshGenerator.xml msgid "" "Bakes the navigation mesh. This will allow you to use pathfinding with the " "navigation system." -msgstr "" +msgstr "çƒ˜ç„™å¯¼èˆªç½‘æ ¼ã€‚å¯ä»¥ç”¨äºŽå¯¼èˆªç³»ç»Ÿä¸çš„寻路。" #: doc/classes/NavigationMeshGenerator.xml -#, fuzzy msgid "Clears the navigation mesh." -msgstr "设置æ¤é¡¹çš„å¯¼èˆªç½‘æ ¼ã€‚" +msgstr "æ¸…é™¤å¯¼èˆªç½‘æ ¼ã€‚" #: doc/classes/NavigationMeshInstance.xml -#, fuzzy msgid "An instance of a [NavigationMesh]." -msgstr "实例化 [MultiMesh] 的节点。" +msgstr "[NavigationMesh] 的一个实例。" #: doc/classes/NavigationMeshInstance.xml msgid "" @@ -43419,6 +43789,8 @@ msgid "" "be navigated and what cannot, based on the [NavigationMesh] resource. This " "should be a child of a [Navigation] node." msgstr "" +"[NavigationMesh] çš„ä¸€ä¸ªå®žä¾‹ã€‚å®ƒä¼šæ ¹æ® [NavigationMesh] 资æºï¼Œå‘ŠçŸ¥ " +"[Navigation] 节点什么å¯ä»¥å¯¼èˆªã€ä»€ä¹ˆä¸å¯ä»¥ã€‚应该是 [Navigation] 节点的å节点。" #: doc/classes/NavigationMeshInstance.xml msgid "" @@ -43426,30 +43798,28 @@ msgid "" "navigation baking is not a cheap operation. This can be done at runtime. " "When it is completed, it automatically sets the new [NavigationMesh]." msgstr "" +"烘焙 [NavigationMesh]。烘焙是在å•独的线程ä¸è¿›è¡Œçš„ï¼Œå› ä¸ºå¯¼èˆªçš„çƒ˜ç„™å¹¶ä¸æ˜¯å»‰ä»·æ“" +"作。å¯ä»¥åœ¨è¿è¡Œæ—¶è¿›è¡Œã€‚完æˆåŽï¼Œä¼šè‡ªåŠ¨è®¾ç½®æ–°çš„ [NavigationMesh]。" #: doc/classes/NavigationMeshInstance.xml -#, fuzzy msgid "Determines if the [NavigationMeshInstance] is enabled or disabled." -msgstr "递归扫æ [NavigationMeshInstance] çš„å节点以获å–å‡ ä½•ä½“ã€‚" +msgstr "决定该 [NavigationMeshInstance] å·²å¯ç”¨è¿˜æ˜¯å·²ç¦ç”¨ã€‚" #: doc/classes/NavigationMeshInstance.xml -#, fuzzy msgid "The [NavigationMesh] resource to use." -msgstr "实例的 [NavigationMesh] 资æºã€‚" +msgstr "使用的 [NavigationMesh] 资æºã€‚" #: doc/classes/NavigationMeshInstance.xml -#, fuzzy msgid "Notifies when the navigation mesh bake operation is completed." -msgstr "å½“åŠ¨ç”»å¼€å§‹æ’æ”¾æ—¶é€šçŸ¥ã€‚" +msgstr "å¯¼èˆªç½‘æ ¼çƒ˜ç„™æ“ä½œå®Œæˆæ—¶å‘出通知。" #: doc/classes/NavigationMeshInstance.xml -#, fuzzy msgid "Notifies when the [NavigationMesh] has changed." -msgstr "å½“åŠ¨ç”»å¼€å§‹æ’æ”¾æ—¶é€šçŸ¥ã€‚" +msgstr "[NavigationMesh] å‘生å˜åŒ–æ—¶å‘出通知。" #: doc/classes/NavigationObstacle.xml msgid "3D obstacle used in navigation for collision avoidance." -msgstr "" +msgstr "在导航ä¸ç”¨äºŽé˜²æ’žçš„ 3D éšœç¢ç‰©ã€‚" #: doc/classes/NavigationObstacle.xml msgid "" @@ -43458,58 +43828,66 @@ msgid "" "as a child of a [Navigation] node, or using [method set_navigation]. " "[NavigationObstacle] is physics safe." msgstr "" +"导航ä¸ç”¨äºŽé˜²æ’žçš„ 3D éšœç¢ç‰©ã€‚éšœç¢ç‰©éœ€è¦å¯¼èˆªæ•°æ®æ‰èƒ½æ£ç¡®å·¥ä½œã€‚å¯ä»¥é€šè¿‡è®©éšœç¢ç‰©" +"æˆä¸º [Navigation] 节点的å项实现,也å¯ä»¥ä½¿ç”¨ [method set_navigation]。" +"[NavigationObstacle] 是物ç†å®‰å…¨çš„。" #: doc/classes/NavigationObstacle.xml -#, fuzzy msgid "" "Returns the [Navigation] node that the obstacle is using for its navigation " "system." -msgstr "返回指定å称的动画节点。" +msgstr "返回该障ç¢ç‰©çš„导航系统所使用的 [Navigation] 节点。" #: doc/classes/NavigationObstacle.xml msgid "" "Sets the [Navigation] node used by the obstacle. Useful when you don't want " "to make the obstacle a child of a [Navigation] node." msgstr "" +"设置障ç¢ç‰©æ‰€ä½¿ç”¨çš„ [Navigation] 节点。å¯ä»¥åœ¨ä½ 䏿ƒ³è®©éšœç¢ç‰©ä½œä¸º [Navigation] " +"节点的å节点时使用。" #: doc/classes/NavigationObstacle.xml doc/classes/NavigationObstacle2D.xml msgid "" "Enables radius estimation algorithm which uses parent's collision shapes to " "determine the obstacle radius." -msgstr "" +msgstr "å¯ç”¨åŠå¾„估算算法,使用父项的碰撞形状确定障ç¢ç‰©çš„åŠå¾„。" #: doc/classes/NavigationObstacle.xml doc/classes/NavigationObstacle2D.xml -#, fuzzy msgid "" "The radius of the agent. Used only if [member estimate_radius] is set to " "[code]false[/code]." msgstr "" -"è®¾ç½®ä¸»æŒ‰é’®çš„åˆ‡æ¢æ¨¡å¼çжæ€ã€‚åªæœ‰å½“ [member toggle_mode] 被设置为 [code]true[/" -"code] æ—¶æ‰èµ·ä½œç”¨ã€‚" +"代ç†çš„åŠå¾„。仅在 [member estimate_radius] 为 [code]false[/code] 时使用。" #: doc/classes/NavigationObstacle2D.xml msgid "2D obstacle used in navigation for collision avoidance." -msgstr "" +msgstr "在导航ä¸ç”¨äºŽé˜²æ’žçš„ 2D éšœç¢ç‰©ã€‚" #: doc/classes/NavigationObstacle2D.xml +#, fuzzy msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" +"导航ä¸ç”¨äºŽé˜²æ’žçš„ 2D éšœç¢ç‰©ã€‚éšœç¢ç‰©éœ€è¦å¯¼èˆªæ•°æ®æ‰èƒ½æ£ç¡®å·¥ä½œã€‚å¯ä»¥é€šè¿‡è®©éšœç¢ç‰©" +"æˆä¸º [Navigation2D] 节点的å项实现,也å¯ä»¥ä½¿ç”¨ [method set_navigation]。" +"[NavigationObstacle] 是物ç†å®‰å…¨çš„。" #: doc/classes/NavigationObstacle2D.xml msgid "" "Returns the [Navigation2D] node that the obstacle is using for its " "navigation system." -msgstr "" +msgstr "返回该障ç¢ç‰©çš„导航系统所使用的 [Navigation2D] 节点。" #: doc/classes/NavigationObstacle2D.xml msgid "" "Sets the [Navigation2D] node used by the obstacle. Useful when you don't " "want to make the obstacle a child of a [Navigation2D] node." msgstr "" +"设置障ç¢ç‰©æ‰€ä½¿ç”¨çš„ [Navigation2D] 节点。å¯ä»¥åœ¨ä½ 䏿ƒ³è®©éšœç¢ç‰©ä½œä¸º " +"[Navigation2D] 节点的å节点时使用。" #: doc/classes/NavigationPolygon.xml msgid "" @@ -43638,9 +44016,8 @@ msgstr "" "make_polygons_from_outlines] æ¥æ›´æ–°å¤šè¾¹å½¢ã€‚" #: doc/classes/NavigationServer.xml -#, fuzzy msgid "Server interface for low-level 3D navigation access." -msgstr "低级音频访问的æœåŠ¡å™¨æŽ¥å£ã€‚" +msgstr "访问底层 3D 导航的æœåŠ¡å™¨æŽ¥å£ã€‚" #: doc/classes/NavigationServer.xml msgid "" @@ -43663,34 +44040,43 @@ msgid "" "phase. This means that you can request any change to the map, using any " "thread, without worrying." msgstr "" +"NavigationServer 是负责所有 3D 导航的æœåŠ¡å™¨ï¼Œå¤„ç†çš„对象有地图(map)ã€åœ°åŒº" +"(region)ã€ä»£ç†ï¼ˆagent)。\n" +"地图是由地区组æˆçš„,地区åˆç”±å¯¼èˆªç½‘æ ¼ç»„æˆã€‚å®ƒä»¬ä¸€åŒæž„æˆäº† 3D 世界ä¸çš„å¯å¯¼èˆªåŒº" +"域。两个地区必须共有一æ¡ç›¸ä¼¼çš„边界(edge)æ‰èƒ½ç›¸è¿žã€‚如果一æ¡è¾¹ç•Œçš„两个顶点" +"(vertex)与å¦ä¸€æ¡è¾¹ç•Œçš„对应顶点的è·ç¦»å°äºŽ [member Navigation." +"edge_connection_margin],则认为这两æ¡è¾¹ç•Œç›¸è¿žã€‚\n" +"è¦ä½¿ç”¨é˜²æ’žç³»ç»Ÿï¼Œå¯ä»¥ä½¿ç”¨ä»£ç†ã€‚ä½ å¯ä»¥è®¾ç½®ä»£ç†çš„ç›®æ ‡é€Ÿåº¦ï¼ŒæœåŠ¡å™¨å°±ä¼šä½¿ç”¨ä¿®æ£åŽ" +"的速度触å‘回调。\n" +"[b]注æ„:[/b]防撞系统会忽略地区。直接使用修æ£åŽçš„速度å¯èƒ½ä¼šå°†ä»£ç†æŽ¨åˆ°å¯å¯¼èˆªåŒº" +"åŸŸä¹‹å¤–ã€‚è¿™æ˜¯é˜²æ’žç³»ç»Ÿçš„ç¼ºé™·ï¼Œæ›´å¤æ‚的情况å¯èƒ½éœ€è¦ç”¨åˆ°ç‰©ç†å¼•擎。\n" +"æœåŠ¡å™¨ä¼šè®°å½•æ‰€æœ‰çš„è°ƒç”¨ï¼Œåœ¨åŒæ¥é˜¶æ®µç»Ÿä¸€æ‰§è¡Œã€‚è¿™æ„味ç€ä½ å¯ä»¥æ”¾å¿ƒå¤§èƒ†åœ°ä»Žä»»ä½•线" +"程ä¸è¯·æ±‚对地图进行任何修改。" #: doc/classes/NavigationServer.xml -#, fuzzy msgid "" "Returns the normal for the point returned by [method map_get_closest_point]." -msgstr "返回碰撞点相交物体形状的法线。" +msgstr "返回 [method map_get_closest_point] 所返回的点的法线。" #: doc/classes/NavigationServer.xml -#, fuzzy msgid "" "Returns the closest point between the navigation surface and the segment." -msgstr "èµ·ç‚¹å’Œç»ˆç‚¹ä¹‹é—´ç‚¹çš„æ ·å¼ã€‚" +msgstr "返回导航表é¢ä¸Žè¯¥çº¿æ®µä¹‹é—´æœ€æŽ¥è¿‘的点。" #: doc/classes/NavigationServer.xml msgid "" "Returns the edge connection margin of the map. This distance is the minimum " "vertex distance needed to connect two edges from different regions." msgstr "" +"返回地图的边界连接边è·ã€‚这是让两个ä¸åŒåœ°åŒºçš„边界相连所需的最å°é¡¶ç‚¹è·ç¦»ã€‚" #: doc/classes/NavigationServer.xml -#, fuzzy msgid "Returns the map's up direction." -msgstr "返回ä½å›¾çš„尺寸。" +msgstr "返回地图的上方å‘。" #: doc/classes/NavigationServer.xml -#, fuzzy msgid "Sets the map up direction." -msgstr "åœæ¢éŸ³é¢‘。" +msgstr "设置地图的上方å‘。" #: doc/classes/NavigationServer.xml msgid "" @@ -43699,16 +44085,17 @@ msgid "" "called in the main thread.\n" "[b]Note:[/b] This function is not thread safe." msgstr "" +"处ç†é˜²æ’žä»£ç†ã€‚\n" +"ç‰©ç†æœåŠ¡å™¨éœ€è¦è¿™ä¸ªå¤„ç†çš„结果,所以必须在主线程ä¸è°ƒç”¨ã€‚\n" +"[b]注æ„:[/b]è¿™ä¸ªå‡½æ•°ä¸æ˜¯çº¿ç¨‹å®‰å…¨çš„。" #: doc/classes/NavigationServer.xml -#, fuzzy msgid "Bakes the navigation mesh." -msgstr "设置æ¤é¡¹çš„å¯¼èˆªç½‘æ ¼ã€‚" +msgstr "çƒ˜ç„™å¯¼èˆªç½‘æ ¼ã€‚" #: doc/classes/NavigationServer.xml -#, fuzzy msgid "Control activation of this server." -msgstr "æ¤èŠ‚ç‚¹çš„å±€éƒ¨å˜æ¢ã€‚" +msgstr "控制这个æœåŠ¡å™¨æ˜¯å¦æ¿€æ´»ã€‚" #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47648,6 +48035,7 @@ msgstr "" "在文件的末尾是所有已使用资æºç±»åž‹çš„统计数æ®ã€‚" #: doc/classes/OS.xml +#, fuzzy msgid "" "Execute the file at the given path with the arguments passed as an array of " "strings. Platform path resolution will take place. The resolved file must " @@ -47666,6 +48054,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -48185,18 +48576,17 @@ msgstr "" msgid "" "Returns the amount of time in milliseconds it took for the boot logo to " "appear." -msgstr "返回å¯åŠ¨æ ‡å¿—å‡ºçŽ°æ‰€èŠ±è´¹çš„æ—¶é—´(以毫秒为å•ä½)。" +msgstr "返回å¯åŠ¨å¾½æ ‡å‡ºçŽ°æ‰€èŠ±è´¹çš„æ—¶é—´ï¼Œå•ä½ä¸ºæ¯«ç§’。" #: doc/classes/OS.xml msgid "Returns the maximum amount of static memory used (only works in debug)." -msgstr "è¿”å›žä½¿ç”¨çš„é™æ€å†…å˜çš„æœ€å¤§æ•°é‡(ä»…åœ¨è°ƒè¯•ä¸æœ‰æ•ˆ)。" +msgstr "è¿”å›žä½¿ç”¨çš„é™æ€å†…å˜çš„æœ€å¤§æ•°é‡ï¼ˆä»…在调试时有效)。" #: doc/classes/OS.xml -#, fuzzy msgid "" "Returns the amount of static memory being used by the program in bytes (only " "works in debug)." -msgstr "è¿”å›žç¨‹åºæ‰€ä½¿ç”¨çš„陿€å†…å˜é‡ï¼Œä»¥å—节为å•ä½ã€‚" +msgstr "è¿”å›žç¨‹åºæ‰€ä½¿ç”¨çš„陿€å†…å˜é‡ï¼Œä»¥å—节为å•ä½ï¼ˆä»…在调试时有效)。" #: doc/classes/OS.xml msgid "" @@ -49970,6 +50360,7 @@ msgid "GPU-based 3D particle emitter." msgstr "基于GPUçš„3Dç²’åå‘射器。" #: doc/classes/Particles.xml +#, fuzzy msgid "" "3D particle node used to create a variety of particle systems and effects. " "[Particles] features an emitter that generates some number of particles at a " @@ -49982,6 +50373,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -50110,6 +50505,7 @@ msgid "GPU-based 2D particle emitter." msgstr "基于GPUçš„2Dç²’åå‘射器。" #: doc/classes/Particles2D.xml +#, fuzzy msgid "" "2D particle node used to create a variety of particle systems and effects. " "[Particles2D] features an emitter that generates some number of particles at " @@ -50122,6 +50518,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -50728,13 +51128,13 @@ msgid "" "points and increase memory consumption, or make a cubic interpolation " "between two points at the cost of (slightly) slower calculations." msgstr "" -"如果[code]为true[/code],则两个缓å˜ç‚¹ä¹‹é—´çš„ä½ç½®å°†è¿›è¡Œä¸‰æ¬¡æ’值,å¦åˆ™å°†çº¿æ€§æ’" +"如果为 [code]true[/code],则两个缓å˜ç‚¹ä¹‹é—´çš„ä½ç½®å°†è¿›è¡Œä¸‰æ¬¡æ’值,å¦åˆ™å°†çº¿æ€§æ’" "值。\n" -"沿ç€[Path2D]çš„[Curve2D]的点在使用å‰è¢«é¢„先计算,以更快的计算速度。然åŽåœ¨ä¸¤ä¸ªç›¸" -"邻的缓å˜ç‚¹ä¹‹é—´è®¡ç®—请求åç§»é‡çš„点。这å¯èƒ½ä¼šå‡ºçŽ°ä¸€ä¸ªé—®é¢˜ï¼Œå¦‚æžœæ›²çº¿åšæ€¥è½¬å¼¯ï¼Œå› " -"为缓å˜ç‚¹å¯èƒ½ä¸è·Ÿéšæ›²çº¿è¶³å¤Ÿè¿‘ã€‚\n" -"æœ‰ä¸¤ç§æ–¹æ³•å¯ä»¥è§£å†³è¿™ä¸ªé—®é¢˜:è¦ä¹ˆå¢žåŠ ç¼“å˜ç‚¹çš„æ•°é‡ï¼Œå¢žåŠ å†…å˜æ¶ˆè€—,è¦ä¹ˆåœ¨ä¸¤ä¸ªç‚¹ä¹‹" -"间进行三次æ’值,但代价是(ç¨å¾®)é™ä½Žè®¡ç®—速度。" +"æ²¿ç€ [Path2D] çš„ [Curve2D] 的点在使用å‰è¢«é¢„先计算,以更快的计算速度。然åŽåœ¨ä¸¤" +"个相邻的缓å˜ç‚¹ä¹‹é—´è®¡ç®—请求åç§»é‡çš„点。这å¯èƒ½ä¼šå‡ºçŽ°ä¸€ä¸ªé—®é¢˜ï¼Œå¦‚æžœæ›²çº¿åšæ€¥è½¬" +"å¼¯ï¼Œå› ä¸ºç¼“å˜ç‚¹å¯èƒ½ä¸è·Ÿéšæ›²çº¿è¶³å¤Ÿè¿‘ã€‚\n" +"æœ‰ä¸¤ç§æ–¹æ³•å¯ä»¥è§£å†³è¿™ä¸ªé—®é¢˜ï¼šè¦ä¹ˆå¢žåŠ ç¼“å˜ç‚¹çš„æ•°é‡ï¼Œå¢žåŠ å†…å˜æ¶ˆè€—,è¦ä¹ˆåœ¨ä¸¤ä¸ªç‚¹" +"之间进行三次æ’值,但代价是(ç¨å¾®ï¼‰é™ä½Žè®¡ç®—速度。" #: doc/classes/PathFollow2D.xml msgid "" @@ -50752,7 +51152,7 @@ msgstr "沿ç€è·¯å¾„çš„è·ç¦»ï¼Œå•ä½ä¸ºåƒç´ 。" msgid "" "If [code]true[/code], this node rotates to follow the path, making its " "descendants rotate." -msgstr "如果[code]为true[/code],则该节点将沿ç€è·¯å¾„旋转,使其åŽä»£èŠ‚ç‚¹æ—‹è½¬ã€‚" +msgstr "如果为 [code]true[/code],则该节点将沿ç€è·¯å¾„旋转,使其åŽä»£èŠ‚ç‚¹æ—‹è½¬ã€‚" #: doc/classes/PathFollow2D.xml msgid "" @@ -52284,11 +52684,11 @@ msgstr "å½“å¯¹è±¡é€€å‡ºå…¶å½¢çŠ¶ä¹‹ä¸€æ—¶ï¼Œç¬¬ä¸€ä¸ªå‚æ•°å’ŒåŒºåŸŸå›žè°ƒå‡½æ•° #: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml msgid "Constant to get the number of objects that are not sleeping." -msgstr "常é‡ï¼Œç”¨æ¥èŽ·å–æœªå¤„于ç¡çœ 状æ€çš„对象的数é‡ã€‚" +msgstr "常é‡ï¼Œç”¨ä»¥èŽ·å–æœªå¤„于ç¡çœ 状æ€çš„对象的数é‡ã€‚" #: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml msgid "Constant to get the number of possible collisions." -msgstr "常数,用以获å–å¯èƒ½çš„碰撞数。" +msgstr "常é‡ï¼Œç”¨ä»¥èŽ·å–å¯èƒ½çš„碰撞数。" #: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml msgid "" @@ -52297,7 +52697,7 @@ msgstr "常é‡ï¼Œç”¨ä»¥èŽ·å–å¯èƒ½å‘生碰撞的空间区域数。" #: doc/classes/Physics2DShapeQueryParameters.xml msgid "Parameters to be sent to a 2D shape physics query." -msgstr "è¦å‘é€åˆ°2Då½¢çŠ¶ç‰©ç†æŸ¥è¯¢çš„傿•°ã€‚" +msgstr "è¦å‘é€åˆ° 2D å½¢çŠ¶ç‰©ç†æŸ¥è¯¢çš„傿•°ã€‚" #: doc/classes/Physics2DShapeQueryParameters.xml msgid "" @@ -52403,7 +52803,7 @@ msgstr "碰撞层和碰撞掩ç 。访问时返回碰撞层。修改时更新碰 #: doc/classes/PhysicsDirectBodyState.xml msgid "Direct access object to a physics body in the [PhysicsServer]." -msgstr "直接访问[PhysicsServer]ä¸çš„物ç†ä½“的对象。" +msgstr "直接访问 [PhysicsServer] ä¸çš„物ç†ä½“的对象。" #: doc/classes/PhysicsDirectBodyState.xml msgid "" @@ -52454,8 +52854,8 @@ msgid "" "This will rotate the body around the vector [code]j[/code] passed as " "parameter." msgstr "" -"æ–½åŠ ä¸€ä¸ªæ‰çŸ©å†²é‡(这将å—到物体质é‡å’Œå½¢çŠ¶çš„å½±å“)ã€‚è¿™å°†å›´ç»•ä½œä¸ºå‚æ•°ä¼ 递的å‘é‡" -"[code]j[/code]旋转主体。" +"æ–½åŠ ä¸€ä¸ªæ‰çŸ©å†²é‡ï¼ˆå°†å—到物体质é‡å’Œå½¢çŠ¶çš„å½±å“ï¼‰ã€‚è¿™å°†å›´ç»•ä½œä¸ºå‚æ•°ä¼ 递的å‘é‡ " +"[code]j[/code] 旋转主体。" #: doc/classes/PhysicsDirectBodyState.xml msgid "Returns the collider object." @@ -52488,15 +52888,15 @@ msgstr "物体的线速度,å•ä½ä¸ºå•使¯ç§’。" #: doc/classes/PhysicsDirectSpaceState.xml msgid "Direct access object to a space in the [PhysicsServer]." -msgstr "直接访问[PhysicsServer]ä¸ç©ºé—´çš„对象。" +msgstr "直接访问 [PhysicsServer] ä¸ç©ºé—´çš„对象。" #: doc/classes/PhysicsDirectSpaceState.xml msgid "" "Direct access object to a space in the [PhysicsServer]. It's used mainly to " "do queries against objects and areas residing in a given space." msgstr "" -"直接访问[PhysicsServer]ä¸ç©ºé—´çš„对象。它主è¦ç”¨äºŽå¯¹é©»ç•™åœ¨ç‰¹å®šç©ºé—´çš„对象和区域进" -"行查询。" +"直接访问 [PhysicsServer] ä¸ç©ºé—´çš„对象。它主è¦ç”¨äºŽå¯¹é©»ç•™åœ¨ç‰¹å®šç©ºé—´çš„对象和区域" +"进行查询。" #: doc/classes/PhysicsDirectSpaceState.xml msgid "" @@ -53028,7 +53428,7 @@ msgstr "铰链上的最大旋转。" #: doc/classes/PhysicsServer.xml msgid "The minimum rotation across the Hinge." -msgstr "ç©¿è¿‡é“°é“¾çš„æœ€å°æ—‹è½¬ã€‚" +msgstr "é“°é“¾ä¸Šçš„æœ€å°æ—‹è½¬ã€‚" #: doc/classes/PhysicsServer.xml msgid "If [code]true[/code], the Hinge has a maximum and a minimum rotation." @@ -53042,13 +53442,13 @@ msgstr "如果[code]true[/code],电机将转动铰链。" msgid "" "The maximum difference between the pivot points on their X axis before " "damping happens." -msgstr "阻尼å‘生å‰X轴上枢轴点之间的最大差异。" +msgstr "阻尼å‘生å‰è½´å¿ƒç‚¹ä¹‹é—´åœ¨ X 轴上的最大差异。" #: doc/classes/PhysicsServer.xml doc/classes/SliderJoint.xml msgid "" "The minimum difference between the pivot points on their X axis before " "damping happens." -msgstr "阻尼å‘生å‰X轴上枢轴点之间的最å°å·®å¼‚。" +msgstr "阻尼å‘生å‰è½´å¿ƒç‚¹ä¹‹é—´åœ¨ X 轴上的最å°å·®å¼‚。" #: doc/classes/PhysicsServer.xml doc/classes/SliderJoint.xml msgid "" @@ -53740,7 +54140,6 @@ msgstr "" "大å°ã€‚使用 [enum File.CompressionMode] 常é‡ä¹‹ä¸€è®¾ç½®åŽ‹ç¼©æ¨¡å¼ã€‚" #: doc/classes/PoolByteArray.xml -#, fuzzy msgid "" "Returns a new [PoolByteArray] with the data decompressed. Set the " "compression mode using one of [enum File.CompressionMode]'s constants. " @@ -53757,15 +54156,15 @@ msgid "" "will allow for unbounded output. If any positive value is passed, and the " "decompression exceeds that amount in bytes, then an error will be returned." msgstr "" -"返回数æ®è§£åŽ‹åŽçš„æ–° [PoolByteArray] 。使用 [enum File.CompressionMode] 的常数" -"之一设置压缩模å¼ã€‚[b]æ¤æ–¹æ³•ä»…æŽ¥å— gzip å’Œdeflate压缩模å¼ã€‚[/b]\n" -"æ¤æ–¹æ³•å¯èƒ½æ¯” [code]decompress[/code] æ…¢ï¼Œå› ä¸ºå®ƒå¯èƒ½éœ€è¦åœ¨è§£åŽ‹æ—¶å¤šæ¬¡é‡æ–°åˆ†é…å…¶" -"è¾“å‡ºç¼“å†²å™¨ï¼Œå› ä¸º [code]decompress[/code] 从一开始就知é“它的输出缓冲器大å°ã€‚\n" +"返回包å«è§£åŽ‹åŽæ•°æ®çš„æ–° [PoolByteArray]。请使用 [enum File.CompressionMode] 常" +"é‡ä¹‹ä¸€è®¾ç½®åŽ‹ç¼©æ¨¡å¼ã€‚[b]è¿™ä¸ªæ–¹æ³•åªæŽ¥å— gzip å’Œ deflate 压缩模å¼ã€‚[/b]\n" +"这个方法å¯èƒ½æ¯” [code]decompress[/code] æ…¢ï¼Œå› ä¸ºåœ¨è§£åŽ‹æ—¶å¯èƒ½éœ€è¦å¤šæ¬¡é‡æ–°åˆ†é…输" +"出缓冲区,而 [code]decompress[/code] 则在一开始就知é“输出缓冲区的大å°ã€‚\n" "\n" -"GZIP 的最大压缩比为 1032:1,这æ„味ç€å°åž‹åŽ‹ç¼©æœ‰æ•ˆè½½è·æžæœ‰å¯èƒ½å‡åŽ‹åˆ°æ½œåœ¨çš„éžå¸¸" -"大输出。为了防æ¢è¿™ç§æƒ…况,您å¯ä»¥æä¾›æœ€å¤§å°ºå¯¸ï¼Œå…许æ¤å‡½æ•°é€šè¿‡ " -"[code]max_output_size[/code] 以å—节进行分é…。通过 -1 å°†å…è®¸æ— é™åˆ¶è¾“出。如果通" -"过任何æ£å€¼ï¼Œå¹¶ä¸”解压超过给定的å—节值,则将返回错误。" +"GZIP 的最大压缩率为 1032:1,这æ„味ç€è¾ƒå°çš„压缩åŽè´Ÿè½½å¾ˆæœ‰å¯èƒ½è§£åŽ‹å‡ºéžå¸¸å·¨å¤§çš„" +"输出。为了防æ¢è¿™ç§æƒ…å†µï¼Œä½ å¯ä»¥é€šè¿‡ [code]max_output_size[/code] æä¾›å…许这个" +"函数分é…的最大å—èŠ‚æ•°ã€‚ä¼ å…¥ -1 则ä¸é™åˆ¶è¾“å‡ºã€‚ä¼ å…¥æ£æ•°ä¸”解压超过该å—节数时,会" +"返回错误。" #: doc/classes/PoolByteArray.xml msgid "" @@ -55431,12 +55830,15 @@ msgid "" msgstr "设置é…置值的顺åºï¼ˆä¿å˜åˆ°é…置文件时会产生影å“)。" #: doc/classes/ProjectSettings.xml +#, fuzzy msgid "" "Sets the value of a setting.\n" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" "设置给定é…置项的值。\n" "[b]示例:[/b]\n" @@ -55887,21 +56289,22 @@ msgid "" "projects (Godot 2), as using member variables is the preferred style from " "Godot 3 onwards." msgstr "" -"如果[code]true[/code],则在脚本编辑器的自动完æˆç»“æžœä¸æ˜¾ç¤ºgetterså’Œsetters。这" -"ä¸ªè®¾ç½®æ˜¯ä¸ºäº†åœ¨ç§»æ¤æ—§é¡¹ç›®(戈多2)æ—¶ä½¿ç”¨ï¼Œå› ä¸ºä½¿ç”¨æˆå‘˜å˜é‡æ˜¯ä»Žæˆˆå¤š3开始的首选风" -"æ ¼ã€‚" +"如果为 [code]true[/code],则在脚本编辑器的自动完æˆç»“æžœä¸æ˜¾ç¤º Getter å’Œ " +"Setterã€‚è¿™ä¸ªè®¾ç½®æ˜¯ä¸ºäº†åœ¨ç§»æ¤æ—§é¡¹ç›®ï¼ˆGodot 2ï¼‰æ—¶ä½¿ç”¨ï¼Œå› ä¸ºä½¿ç”¨æˆå‘˜å˜é‡æ˜¯ä»Ž " +"Godot 3 å¼€å§‹çš„é¦–é€‰é£Žæ ¼ã€‚" #: doc/classes/ProjectSettings.xml msgid "" "If [code]true[/code], enables warnings when a constant is used as a function." -msgstr "如果[code]true[/code],则当常é‡ç”¨ä½œå‡½æ•°æ—¶ä¼šå‘出è¦å‘Šã€‚" +msgstr "如果为 [code]true[/code],则当常é‡ç”¨ä½œå‡½æ•°æ—¶ä¼šå‘出è¦å‘Šã€‚" #: doc/classes/ProjectSettings.xml msgid "" "If [code]true[/code], enables warnings when deprecated keywords such as " "[code]slave[/code] are used." msgstr "" -"如果[code]true[/code],当使用已废弃的关键å—如[code]slave[/code]时,å¯ç”¨è¦å‘Šã€‚" +"如果为 [code]true[/code],当使用已废弃的 [code]slave[/code] ç‰å…³é”®å—时,将å¯" +"用è¦å‘Šã€‚" #: doc/classes/ProjectSettings.xml msgid "" @@ -55909,16 +56312,17 @@ msgid "" "gdscript/warnings/*[/code] settings). If [code]false[/code], disables all " "GDScript warnings." msgstr "" -"如果[code]true[/code],则å¯ç”¨ç‰¹å®šçš„GDScriptè¦å‘Š(请å‚阅[code]debug/gdscript/" -"warnings/*[/code]设置)。如果[code]为false[/code],则ç¦ç”¨æ‰€æœ‰GDScriptè¦å‘Šã€‚" +"如果为 [code]true[/code],则å¯ç”¨ç‰¹å®šçš„ GDScript è¦å‘Šï¼ˆè¯·å‚阅 [code]debug/" +"gdscript/warnings/*[/code] 设置)。如果为 [code]false[/code],则ç¦ç”¨æ‰€æœ‰ " +"GDScript è¦å‘Šã€‚" #: doc/classes/ProjectSettings.xml msgid "" "If [code]true[/code], scripts in the [code]res://addons[/code] folder will " "not generate warnings." msgstr "" -"如果[code]true[/code],则[code]res://addons[/code]文件夹ä¸çš„脚本ä¸ä¼šç”Ÿæˆè¦" -"告。" +"如果为 [code]true[/code],则 [code]res://addons[/code] 文件夹ä¸çš„脚本ä¸ä¼šç”Ÿæˆ" +"è¦å‘Šã€‚" #: doc/classes/ProjectSettings.xml msgid "" @@ -55940,7 +56344,7 @@ msgid "" "If [code]true[/code], enables warnings when a function assigned to a " "variable may yield and return a function state instead of a value." msgstr "" -"如果[code]为true[/code],则当分é…ç»™å˜é‡çš„函数å¯èƒ½äº§ç”Ÿå¹¶è¿”回函数状æ€è€Œä¸æ˜¯å€¼" +"如果为 [code]true[/code],则当分é…ç»™å˜é‡çš„函数å¯èƒ½äº§ç”Ÿå¹¶è¿”回函数状æ€è€Œä¸æ˜¯å€¼" "时,å¯ç”¨è¦å‘Šã€‚" #: doc/classes/ProjectSettings.xml @@ -55961,8 +56365,8 @@ msgid "" "If [code]true[/code], enables warnings when dividing an integer by another " "integer (the decimal part will be discarded)." msgstr "" -"如果[code]为true[/code],则在用一个整数除以å¦ä¸€ä¸ªæ•´æ•°æ—¶å¯ç”¨è¦å‘Š(å°æ•°éƒ¨åˆ†å°†è¢«" -"丢弃)。" +"如果为 [code]true[/code],则在用一个整数除以å¦ä¸€ä¸ªæ•´æ•°æ—¶å¯ç”¨è¦å‘Šï¼ˆå°æ•°éƒ¨åˆ†å°†" +"被丢弃)。" #: doc/classes/ProjectSettings.xml msgid "" @@ -55970,7 +56374,7 @@ msgid "" "to a function that expects an integer (it will be converted and lose " "precision)." msgstr "" -"如果 [code]为true[/code]ï¼Œåˆ™åœ¨å°†æµ®ç‚¹å€¼ä¼ é€’ç»™éœ€è¦æ•´æ•°çš„函数时å¯ç”¨è¦å‘Šï¼ˆå®ƒå°†è¢«" +"如果为 [code]true[/code]ï¼Œåˆ™åœ¨å°†æµ®ç‚¹å€¼ä¼ é€’ç»™éœ€è¦æ•´æ•°çš„函数时å¯ç”¨è¦å‘Šï¼ˆå®ƒå°†è¢«" "转æ¢å¹¶å¤±åŽ»ç²¾åº¦ï¼‰ã€‚" #: doc/classes/ProjectSettings.xml @@ -56427,6 +56831,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -57746,11 +58162,11 @@ msgid "" "NVIDIA GPUs at the cost of performance. This option affects GLES2 and GLES3 " "rendering, but only on desktop platforms." msgstr "" -"一些NVIDIA GPU驱动有bug,对[code]draw_rect[/code]方法产生闪çƒé—®é¢˜ï¼Œç‰¹åˆ«æ˜¯åœ¨" -"[TileMap]ä¸ä½¿ç”¨æ—¶ã€‚详情å‚阅[url=https://github.com/godotengine/godot/" +"一些 NVIDIA GPU 驱动有 bug,对 [code]draw_rect[/code] 方法产生闪çƒé—®é¢˜ï¼Œç‰¹åˆ«" +"是在 [TileMap] ä¸ä½¿ç”¨æ—¶ã€‚详情å‚阅 [url=https://github.com/godotengine/godot/" "issues/9913]GitHub issue 9913[/url]。\n" -"如果[code]为true[/code],该选项将为æ¤ç±»NVIDIA GPUå¯ç”¨ \"安全\" 的代ç 路径,但" -"会牺牲性能。这个选项会影å“GLES2å’ŒGLES3的渲染,但åªåœ¨æ¡Œé¢å¹³å°ä¸Šã€‚" +"如果为 [code]true[/code],该选项将为æ¤ç±» NVIDIA GPU å¯ç”¨â€œå®‰å…¨â€çš„代ç 路径,但" +"ä¼šç‰ºç‰²æ€§èƒ½ã€‚è¿™ä¸ªé€‰é¡¹ä¼šå½±å“ GLES2 å’Œ GLES3 的渲染,但åªåœ¨æ¡Œé¢å¹³å°ä¸Šã€‚" #: doc/classes/ProjectSettings.xml msgid "" @@ -58272,7 +58688,6 @@ msgstr "" "相关的æ¯ä¸€å¸§ï¼Œä»¥æä¾›æœ€ä½³çš„æ•´ä½“性能。" #: doc/classes/ProjectSettings.xml -#, fuzzy msgid "" "The default convention is for portal normals to point outward (face outward) " "from the source room.\n" @@ -58281,10 +58696,10 @@ msgid "" "It will flip named portal meshes (i.e. [code]-portal[/code]) on the initial " "conversion to [Portal] nodes." msgstr "" -"默认的惯例是,portal的法线从æºç©ºé—´å‘外。\n" -"å¦‚æžœä½ åœ¨å»ºé€ å…³å¡æ—¶ä¸å°å¿ƒå°†portalæœå‘了错误的方å‘,这个设置å¯ä»¥è§£å†³è¿™ä¸ªé—®" +"默认的惯例是,入å£çš„æ³•çº¿æŒ‡å‘æºæˆ¿é—´å¤–éƒ¨ï¼ˆé¢æœå¤–)。\n" +"å¦‚æžœä½ åœ¨å»ºé€ å…³å¡æ—¶ä¸å°å¿ƒå°†å…¥å£éƒ½æœå‘了错误的方å‘,这个设置å¯ä»¥è§£å†³è¿™ä¸ªé—®" "题。\n" -"它将在åˆå§‹è½¬æ¢ä¸º[Portal]节点时翻转命åçš„portalç½‘æ ¼ï¼ˆå³[code]-portal[/" +"它将在åˆå§‹è½¬æ¢ä¸º [Portal] 节点时翻转命å的入å£ç½‘æ ¼ï¼ˆå³ [code]-portal[/" "code])。" #: doc/classes/ProjectSettings.xml @@ -58339,16 +58754,15 @@ msgstr "" "时,æ‰åº”该使用该选项。" #: doc/classes/ProjectSettings.xml -#, fuzzy msgid "" "If [code]true[/code], allocates the root [Viewport]'s framebuffer with high " "dynamic range. High dynamic range allows the use of [Color] values greater " "than 1.\n" "[b]Note:[/b] Only available on the GLES3 backend." msgstr "" -"如果 [code]true[/code],则分é…具有高动æ€èŒƒå›´ï¼ˆHDR)的主帧缓冲区。高动æ€èŒƒå›´å…" -"许使用大于 1 çš„ [Color] 值。\n" -"[b]注æ„:[/b] 仅在 GLES3 åŽç«¯å¯ç”¨ã€‚" +"如果为 [code]true[/code]ï¼Œåˆ†é…æ ¹ [Viewport] 的帧缓冲时将使用高动æ€èŒƒå›´ã€‚高动" +"æ€èŒƒå›´å…许使用大于 1 çš„ [Color] 值。\n" +"[b]注æ„:[/b]仅在 GLES3 åŽç«¯ä¸å¯ç”¨ã€‚" #: doc/classes/ProjectSettings.xml msgid "" @@ -58370,6 +58784,13 @@ msgid "" "enable [member rendering/quality/filters/use_debanding] instead.\n" "[b]Note:[/b] Only available on the GLES3 backend." msgstr "" +"如果为 [code]true[/code]ï¼Œåˆ†é…æ ¹ [Viewport] 的帧缓冲时将使用完整浮点数精度" +"(32 ä½ï¼‰è€Œä¸æ˜¯åŠæµ®ç‚¹æ•°ç²¾åº¦ï¼ˆ16 ä½ï¼‰ã€‚ä»…åœ¨åŒæ—¶å¯ç”¨ [member rendering/quality/" +"depth/hdr] 时有效。\n" +"[b]注æ„:[/b]å¯ç”¨è¿™ä¸ªè®¾ç½®ä¸ä¼šæå‡æ¸²æŸ“è´¨é‡ã€‚ä½¿ç”¨å®Œæ•´æµ®ç‚¹æ•°ç²¾åº¦è¾ƒæ…¢ï¼Œä¸€èˆ¬åªæœ‰è¦" +"求更高精度的高级ç€è‰²å™¨éœ€è¦ä½¿ç”¨ã€‚如果是è¦å‡å°‘æ¡å¸¦æ•ˆåº”,请å¯ç”¨ [member " +"rendering/quality/filters/use_debanding]。\n" +"[b]注æ„:[/b]仅在 GLES3 åŽç«¯ä¸å¯ç”¨ã€‚" #: doc/classes/ProjectSettings.xml msgid "" @@ -59721,13 +60142,12 @@ msgid "2D axis-aligned bounding box." msgstr "2D 轴对é½è¾¹ç•Œæ¡†ã€‚" #: doc/classes/Rect2.xml +#, fuzzy msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" "[Rect2] ç”±ä¸€ä¸ªåæ ‡ã€ä¸€ä¸ªå¤§å°å’Œå‡ 个实用函数组æˆã€‚它通常用于快速é‡å 测试。\n" "å®ƒä½¿ç”¨æµ®ç‚¹åæ ‡ã€‚\n" @@ -62671,7 +63091,6 @@ msgid "Groups [Room]s together to allow common functionality." msgstr "å°† [Room] 组åˆåœ¨ä¸€èµ·ä»¥å®žçŽ°é€šç”¨åŠŸèƒ½ã€‚" #: doc/classes/RoomGroup.xml -#, fuzzy msgid "" "Although [Room] behavior can be specified individually, sometimes it is " "faster and more convenient to write functionality for a group of rooms.\n" @@ -62686,14 +63105,14 @@ msgid "" "[code]notification[/code]s as they enter and exit the [b]gameplay area[/b] " "(see [RoomManager] for details)." msgstr "" -"尽管å¯ä»¥å•独指定 [Room] 行为,但有时为一组空间编写功能会更快更方便。\n" -"[RoomGroup] 应作为[b]空间列表[/b](您的 [Room] 的父 [Node])的å项而设置,而 " -"[Room] 应作为 [RoomGroup] çš„å项便¬¡è®¾ç½®ä»¥ä¾¿å°†å®ƒä»¬åˆ†é…ç»™ RoomGroup。\n" +"尽管å¯ä»¥å•独指定 [Room] 行为,但有时为一组房间编写功能会更快更方便。\n" +"[RoomGroup] 应作为[b]空间列表[/b](您的 [Room] 的父 [Node])的å项,而 " +"[Room] 应作为 [RoomGroup] çš„å项便¬¡æ”¾ç½®ä»¥ä¾¿å°†å®ƒä»¬åˆ†é…ç»™ RoomGroup。\n" "例如,[RoomGroup] å¯ç”¨äºŽæŒ‡å®š[b]处于外部[/b]çš„ [Room],并在玩家进入/退出该区域" "时打开或关é—定å‘å…‰ã€å¤©ç©ºæˆ–雨效果。\n" -"当 [code]gameplay_monitor[/code] 开坿—¶ï¼Œ[RoomGroup] 收到[b]游æˆå›žè°ƒ[/b],在" -"他们进入和退出[b]游æˆåŒºåŸŸ[/b]时,以[code]ä¿¡å·[/code]或[code]通知[/code]的形å¼" -"ï¼ˆè¯¦è§ [RoomManager])。" +"当 [code]gameplay_monitor[/code] 开坿—¶ï¼Œ[RoomGroup] å¯ä»¥æ”¶åˆ°[b]游æˆå›žè°ƒ[/" +"b],在他们进入和退出[b]游æˆåŒºåŸŸ[/b]时,以[code]ä¿¡å·[/code]或[code]通知[/code]" +"的形å¼ï¼ˆè¯¦è§ [RoomManager])。" #: doc/classes/RoomGroup.xml msgid "" @@ -62926,9 +63345,9 @@ msgid "" "level. Here you can alter the threshold at which the editor warning appears. " "There are no other side effects." msgstr "" -"转æ¢ç©ºé—´æ—¶ï¼Œå¦‚果检测到空间之间有é‡å ,编辑器会è¦å‘Šæ‚¨ã€‚é‡å ä¼šå¹²æ‰°ç¡®å®šæ‘„åƒæœºå’Œ" -"ç‰©ä½“æ‰€åœ¨çš„ç©ºé—´ã€‚æ ¹æ®æ‚¨çš„levelï¼Œå°‘é‡æ˜¯å¯ä»¥æŽ¥å—的。您å¯ä»¥åœ¨æ¤å¤„更改出现编辑器è¦" -"告的阈值。没有其他副作用。" +"è½¬æ¢æˆ¿é—´æ—¶ï¼Œå¦‚果检测到空间之间有é‡å ,编辑器会è¦å‘Šæ‚¨ã€‚é‡å ä¼šå¹²æ‰°ç¡®å®šæ‘„åƒæœºå’Œ" +"ç‰©ä½“æ‰€åœ¨çš„ç©ºé—´ã€‚æ ¹æ®æ‚¨çš„ levelï¼Œå°‘é‡æ˜¯å¯ä»¥æŽ¥å—的。您å¯ä»¥åœ¨æ¤å¤„更改出现编辑器" +"è¦å‘Šçš„阈值。没有其他副作用。" #: doc/classes/RoomManager.xml msgid "" @@ -62943,16 +63362,15 @@ msgstr "" "[b]注æ„:[/b]使用 [code]Full[/code] PVS æ¨¡å¼æ—¶ä¸ä½¿ç”¨è¯¥å€¼ã€‚" #: doc/classes/RoomManager.xml -#, fuzzy msgid "" "Portal culling normally operates using the current [Camera] / [Camera]s, " "however for debugging purposes within the editor, you can use this setting " "to override this behavior and force it to use a particular camera to get a " "better idea of what the occlusion culling is doing." msgstr "" -"Portal 剔除通常使用当å‰çš„ [Camera] / 多个[Camera] 进行æ“作,但是为了在编辑器" -"ä¸è¿›è¡Œè°ƒè¯•,您å¯ä»¥ä½¿ç”¨æ¤è®¾ç½®æ¥è¦†ç›–æ¤è¡Œä¸ºå¹¶å¼ºåˆ¶å®ƒä½¿ç”¨ç‰¹å®šçš„相机以更好地了解é®" -"挡的内容剔除æ£åœ¨åšã€‚" +"å…¥å£å‰”除通常使用当å‰çš„ [Camera] 或多个 [Camera] 进行æ“作,但是为了在编辑器ä¸" +"进行调试,您å¯ä»¥ä½¿ç”¨æ¤è®¾ç½®æ¥è¦†ç›–æ¤è¡Œä¸ºå¹¶å¼ºåˆ¶å®ƒä½¿ç”¨ç‰¹å®šçš„相机,以更好地了解é®" +"挡剔除的效果。" #: doc/classes/RoomManager.xml msgid "" @@ -63055,8 +63473,8 @@ msgid "" "Use only [Portal]s at runtime to determine visibility. PVS will not be " "generated at [Room]s conversion, and gameplay notifications cannot be used." msgstr "" -"在è¿è¡Œæ—¶ä»…使用 [Portal] æ¥ç¡®å®šå¯è§æ€§ã€‚ [Room]的转æ¢ä¸ä¼šäº§ç”ŸPVSï¼Œæ— æ³•ä½¿ç”¨æ¸¸æˆ" -"通知。" +"在è¿è¡Œæ—¶ä»…使用 [Portal] æ¥ç¡®å®šå¯è§æ€§ã€‚ [Room] 的转æ¢ä¸ä¼šäº§ç”Ÿ PVSï¼Œæ— æ³•ä½¿ç”¨æ¸¸" +"æˆé€šçŸ¥ã€‚" #: doc/classes/RoomManager.xml msgid "" @@ -63075,7 +63493,6 @@ msgid "Editor-only helper for setting up root motion in [AnimationTree]." msgstr "在[AnimationTree]ä¸è®¾ç½®æ ¹è¿åŠ¨çš„ä»…ç¼–è¾‘å™¨å¯ç”¨çš„辅助工具。" #: doc/classes/RootMotionView.xml -#, fuzzy msgid "" "[i]Root motion[/i] refers to an animation technique where a mesh's skeleton " "is used to give impulse to a character. When working with 3D animations, a " @@ -63090,14 +63507,14 @@ msgid "" "[code]extends RootMotionView[/code]. Additionally, it must not be a " "[code]tool[/code] script." msgstr "" -"[i]Root motion[/i] 指的是一ç§åŠ¨ç”»æŠ€æœ¯ï¼Œå…¶ä¸ä½¿ç”¨ç½‘æ ¼çš„éª¨æž¶ä¸ºè§’è‰²æä¾›åŠ¨åŠ›ã€‚åœ¨å¤„" -"ç† 3D åŠ¨ç”»æ—¶ï¼Œä¸€ç§æµè¡Œçš„æŠ€æœ¯æ˜¯åŠ¨ç”»å¸ˆä½¿ç”¨æ ¹éª¨æž¶éª¨éª¼æ¥ä¸ºéª¨æž¶çš„其余部分æä¾›è¿" -"动。这å…许以æ¥éª¤å®žé™…匹é…下方地æ¿çš„æ–¹å¼ä¸ºè§’色设置动画。它还å…许在过场动画期间" -"与对象进行精确交互。å¦è§[AnimationTree]。\n" -"[b]注æ„:[/b] [RootMotionView] 仅在编辑器ä¸å¯è§ã€‚在è¿è¡Œçš„项目ä¸ä¼šè‡ªåЍéšè—,在" -"è¿è¡Œçš„项目ä¸ä¹Ÿä¼šè½¬æ¢ä¸ºæ™®é€šçš„[Node]。这æ„味ç€é™„åŠ åˆ° [RootMotionView] 节点的脚" -"本 [i] å¿…é¡» [/i] 具有 [code]继承节点[/code] è€Œä¸æ˜¯ [code]继承 " -"RootMotionView[/code]。æ¤å¤–,它ä¸èƒ½æ˜¯ [code]@tool[/code] 脚本。" +"[i]æ ¹è¿åЍ[/i](Root Motion)指的是一ç§åŠ¨ç”»æŠ€æœ¯ï¼Œå…¶ä¸ä½¿ç”¨ç½‘æ ¼çš„éª¨æž¶ä¸ºè§’è‰²æä¾›" +"åŠ¨åŠ›ã€‚åœ¨å¤„ç† 3D åŠ¨ç”»æ—¶ï¼Œä¸€ç§æµè¡Œçš„æŠ€æœ¯æ˜¯åŠ¨ç”»å¸ˆä½¿ç”¨æ ¹éª¨æž¶éª¨éª¼æ¥ä¸ºéª¨æž¶çš„其余部" +"分æä¾›è¿åŠ¨ã€‚è¿™å…许以æ¥éª¤å®žé™…匹é…下方地æ¿çš„æ–¹å¼ä¸ºè§’色设置动画。它还å…许在过场" +"动画期间与对象进行精确交互。å¦è§ [AnimationTree]。\n" +"[b]注æ„:[/b][RootMotionView] 仅在编辑器ä¸å¯è§ã€‚在è¿è¡Œçš„项目ä¸ä¼šè‡ªåЍéšè—,在" +"è¿è¡Œçš„项目ä¸ä¹Ÿä¼šè½¬æ¢ä¸ºæ™®é€šçš„ [Node]。这æ„味ç€é™„åŠ åˆ° [RootMotionView] 节点的脚" +"本[i]å¿…é¡»[/i]具写 [code]extends Node[/code] è€Œä¸æ˜¯ [code]extends " +"RootMotionView[/code]。æ¤å¤–,它ä¸èƒ½æ˜¯ [code]tool[/code] 脚本。" #: doc/classes/RootMotionView.xml msgid "$DOCS_URL/tutorials/animation/animation_tree.html#root-motion" @@ -63168,7 +63585,8 @@ msgid "" "Returns the connection flags for the signal at [code]idx[/code]. See [enum " "Object.ConnectFlags] constants." msgstr "" -"返回[code]idx[/code]处的信å·çš„è¿žæŽ¥æ ‡å¿—ã€‚å‚阅[enum Object.ConnectFlags]常数。" +"返回 [code]idx[/code] 处的信å·çš„è¿žæŽ¥æ ‡å¿—ã€‚è¯·å‚阅 [enum Object.ConnectFlags] " +"常é‡ã€‚" #: doc/classes/SceneState.xml msgid "Returns the method connected to the signal at [code]idx[/code]." @@ -64089,6 +64507,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "当用户更改活动脚本时å‘å‡ºã€‚å‚æ•°æ˜¯æ–°æ¿€æ´»çš„ [Script]。" @@ -65042,14 +65466,25 @@ msgid "" "values." msgstr "如果为 [code]true[/code],则滑动æ¡å°†æ˜¾ç¤ºæœ€å°å€¼å’Œæœ€å¤§å€¼çš„刻度。" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +#, fuzzy +msgid "Emitted when dragging is started." +msgstr "滚动开始时å‘出。" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." -msgstr "在3Dä¸ä¸¤ä¸ªç‰©ç†ä½“之间的滑å—。" +msgstr "3D ä¸ï¼Œä¸¤ä¸ª PhysicsBody 之间的滑动æ¡ã€‚" #: doc/classes/SliderJoint.xml msgid "" "Slides across the X axis of the pivot object. See also [Generic6DOFJoint]." -msgstr "在枢轴对象的X轴上滑动。å‚阅[Generic6DOFJoint]。" +msgstr "在轴心对象的 X 轴上滑动。å‚阅 [Generic6DOFJoint]。" #: doc/classes/SliderJoint.xml msgid "" @@ -65083,7 +65518,7 @@ msgstr "应用于所有å—陿—‹è½¬çš„系数。" #: doc/classes/SliderJoint.xml msgid "" "A factor applied to the all rotation across axes orthogonal to the slider." -msgstr "åº”ç”¨äºŽä¸Žæ»‘å—æ£äº¤çš„轴的所有旋转的系数。" +msgstr "åº”ç”¨äºŽä¸Žæ»‘åŠ¨æ¡æ£äº¤çš„轴的所有旋转的系数。" #: doc/classes/SliderJoint.xml msgid "" @@ -65245,33 +65680,34 @@ msgid "" "Rotates the global (world) transformation around axis, a unit [Vector3], by " "specified angle in radians. The rotation axis is in global coordinate system." msgstr "" -"围绕轴(一个å•ä½[Vector3]ï¼‰æ—‹è½¬å…¨å±€ï¼ˆä¸–ç•Œï¼‰å˜æ¢ï¼ŒæŒ‡å®šè§’度(弧度)。旋转轴是在" -"å…¨å±€åæ ‡ç³»ä¸ã€‚" +"å°†å…¨å±€ï¼ˆä¸–ç•Œï¼‰å˜æ¢å›´ç»•æŸä¸ªè½´ï¼ˆå•ä½ [Vector3])旋转指定的弧度。旋转轴使用全局" +"åæ ‡ç³»ã€‚" #: doc/classes/Spatial.xml msgid "" "Scales the global (world) transformation by the given [Vector3] scale " "factors." -msgstr "通过给定的 [Vector3] æ¯”ä¾‹å› åå¯¹å…¨å±€ï¼ˆä¸–ç•Œï¼‰å˜æ¢è¿›è¡Œç¼©æ”¾ã€‚" +msgstr "å°†å…¨å±€ï¼ˆä¸–ç•Œï¼‰å˜æ¢æŒ‰ç…§ç»™å®šçš„ [Vector3] ç¼©æ”¾å› å进行缩放。" #: doc/classes/Spatial.xml msgid "" "Moves the global (world) transformation by [Vector3] offset. The offset is " "in global coordinate system." -msgstr "通过 [Vector3] åç§»é‡ç§»åŠ¨å…¨å±€ï¼ˆä¸–ç•Œï¼‰å˜æ¢ã€‚åç§»é‡æ˜¯åœ¨å…¨å±€åæ ‡ç³»ä¸ã€‚" +msgstr "" +"å°†å…¨å±€ï¼ˆä¸–ç•Œï¼‰å˜æ¢æŒ‰ç…§ [Vector3] åç§»é‡è¿›è¡Œç§»åŠ¨ã€‚åç§»é‡ä½¿ç”¨å…¨å±€åæ ‡ç³»ã€‚" #: doc/classes/Spatial.xml msgid "" "Disables rendering of this node. Changes [member visible] to [code]false[/" "code]." -msgstr "ç¦ç”¨è¯¥èŠ‚ç‚¹çš„æ¸²æŸ“ã€‚å®ƒå°†[member visible]改为[code]false[/code]。" +msgstr "ç¦ç”¨è¯¥èŠ‚ç‚¹çš„æ¸²æŸ“ã€‚ä¼šå°† [member visible] 改为 [code]false[/code]。" #: doc/classes/Spatial.xml msgid "" "Returns whether node notifies about its local transformation changes. " "[Spatial] will not propagate this by default." msgstr "" -"返回节点是å¦é€šçŸ¥å…¶å±€éƒ¨å˜æ¢çš„å˜åŒ–。[Spatial]默认情况下ä¸ä¼šå¯¹æ¤è¿›è¡Œä¼ æ’。" +"返回节点是å¦é€šçŸ¥å…¶å±€éƒ¨å˜æ¢çš„å˜åŒ–。[Spatial] 默认情况下ä¸ä¼šå¯¹æ¤è¿›è¡Œä¼ æ’。" #: doc/classes/Spatial.xml msgid "" @@ -65341,15 +65777,15 @@ msgstr "" #: doc/classes/Spatial.xml msgid "Rotates the local transformation around the X axis by angle in radians." -msgstr "围绕Xè½´æ—‹è½¬å±€éƒ¨å˜æ¢ï¼Œæ—‹è½¬è§’度为弧度。" +msgstr "围绕 X è½´æ—‹è½¬å±€éƒ¨å˜æ¢ï¼Œæ—‹è½¬è§’度为弧度。" #: doc/classes/Spatial.xml msgid "Rotates the local transformation around the Y axis by angle in radians." -msgstr "围绕Yè½´æ—‹è½¬å±€éƒ¨å˜æ¢ï¼Œæ—‹è½¬è§’度为弧度。" +msgstr "围绕 Y è½´æ—‹è½¬å±€éƒ¨å˜æ¢ï¼Œæ—‹è½¬è§’度为弧度。" #: doc/classes/Spatial.xml msgid "Rotates the local transformation around the Z axis by angle in radians." -msgstr "围绕Zè½´æ—‹è½¬å±€éƒ¨å˜æ¢ï¼Œæ—‹è½¬è§’度为弧度。" +msgstr "围绕 Z è½´æ—‹è½¬å±€éƒ¨å˜æ¢ï¼Œæ—‹è½¬è§’度为弧度。" #: doc/classes/Spatial.xml msgid "" @@ -65438,7 +65874,7 @@ msgstr "通过给定的åç§»é‡[Vector3]改å˜èŠ‚ç‚¹åœ¨å±€éƒ¨ç©ºé—´ä¸çš„ä½ç½® #: doc/classes/Spatial.xml msgid "Updates the [SpatialGizmo] of this node." -msgstr "更新该节点的[SpatialGizmo]。" +msgstr "更新该节点的 [SpatialGizmo]。" #: doc/classes/Spatial.xml msgid "" @@ -65603,7 +66039,6 @@ msgstr "" "å¯ä»¥é€šè¿‡å°†ç›¸åº”çš„æˆå‘˜è®¾ç½®ä¸º [code]true[/code] æ¥å¯ç”¨åŠŸèƒ½ã€‚" #: doc/classes/SpatialMaterial.xml -#, fuzzy msgid "" "If [code]true[/code], enables the specified flag. Flags are optional " "behavior that can be turned on and off. Only one flag can be enabled at a " @@ -65612,10 +66047,10 @@ msgid "" "setting the corresponding member to [code]true[/code]. See [enum Flags] " "enumerator for options." msgstr "" -"如果 [code]true[/code],则å¯ç”¨æŒ‡å®šçš„æ ‡å¿—ã€‚æ ‡å¿—æ˜¯å¯ä»¥æ‰“开和关é—çš„å¯é€‰è¡Œä¸ºã€‚使" -"用该函数一次åªèƒ½å¯ç”¨ä¸€ä¸ªæ ‡å¿—,ä¸èƒ½å°†æ ‡å¿—æžšä¸¾å™¨è¿›è¡Œä½æŽ©ç ,以一次å¯ç”¨æˆ–ç¦ç”¨å¤š" -"ä¸ªæ ‡å¿—ã€‚ä¹Ÿå¯ä»¥é€šè¿‡å°†ç›¸åº”æˆå‘˜è®¾ç½®ä¸º [code]true[/code] æ¥å¯ç”¨æ ‡å¿—。有关选项,请" -"å‚阅 [enum Flags] 枚举器。" +"如果为 [code]true[/code],则å¯ç”¨æŒ‡å®šçš„æ ‡å¿—ã€‚æ ‡å¿—æ˜¯å¯ä»¥æ‰“开和关é—çš„å¯é€‰è¡Œä¸ºã€‚" +"使用该函数一次åªèƒ½å¯ç”¨ä¸€ä¸ªæ ‡å¿—,ä¸èƒ½å°†æ ‡å¿—枚举值åƒä½æŽ©ç ä¸€æ ·è¿›è¡Œåˆå¹¶ï¼Œä¸€æ¬¡å¯" +"用或ç¦ç”¨å¤šä¸ªæ ‡å¿—。也å¯ä»¥é€šè¿‡å°†ç›¸åº”æˆå‘˜è®¾ç½®ä¸º [code]true[/code] æ¥å¯ç”¨æ ‡å¿—。有" +"关选项,请å‚阅 [enum Flags] 枚举器。" #: doc/classes/SpatialMaterial.xml msgid "" @@ -65641,6 +66076,8 @@ msgid "" "anisotropy_flowmap]'s alpha channel if a texture is defined there and the " "texture contains an alpha channel." msgstr "" +"å„å‘异性效果的强度。如果 [member anisotropy_flowmap] æ˜¯ä¸€å¼ å¸¦æœ‰ Alpha 通é“çš„" +"纹ç†ï¼Œé‚£ä¹ˆè¿™ä¸ªå€¼ä¼šä¸Žå…¶ Alpha 通é“相乘。" #: doc/classes/SpatialMaterial.xml msgid "" @@ -65654,6 +66091,13 @@ msgid "" "a texture in the FileSystem dock, going to the Import dock, checking the " "[b]Anisotropic[/b] checkbox then clicking [b]Reimport[/b]." msgstr "" +"如果为 [code]true[/code],则å¯ç”¨å„å‘异性。å„å‘异性会改å˜é«˜å…‰ç‚¹çš„形状并将其与" +"切线空间对其。å¯ç”¨äºŽæ‹‰ä¸é“æå’Œæ¯›å‘å射。\n" +"[b]注æ„:[/b]å„å‘异性需è¦ç½‘æ ¼åˆ‡çº¿æ‰èƒ½æ£å¸¸å·¥ä½œã€‚å¦‚æžœç½‘æ ¼ä¸ä¸åŒ…å«åˆ‡çº¿ï¼Œå„å‘异性" +"效果就会看上去有问题。\n" +"[b]注æ„:[/b]æè´¨çš„å„å‘异性ä¸åº”与纹ç†çš„å„å‘异性过滤相混淆。纹ç†å„å‘异性过滤的" +"å¯ç”¨æ–¹æ³•是,在“文件系统â€é¢æ¿ä¸é€‰ä¸çº¹ç†ï¼Œç„¶åŽåœ¨â€œå¯¼å…¥â€é¢æ¿ä¸å‹¾é€‰ " +"[b]Anisotropic[/b] å¤é€‰æ¡†ï¼Œç„¶åŽç‚¹å‡»[b]釿–°å¯¼å…¥[/b]。" #: doc/classes/SpatialMaterial.xml msgid "" @@ -65669,6 +66113,13 @@ msgid "" "will disable the anisotropy effect entirely. The flowmap texture's blue " "channel is ignored." msgstr "" +"用于对切线图进行å移的纹ç†ï¼Œç”¨äºŽå„å‘异性的计算,(如果å˜åœ¨ Alpha 通é“)还å¯ä»¥" +"控制å„å‘异性的效果。Flowmap æ–¹å‘图纹ç†åº”è¯¥æ˜¯ä¸€å¼ æ´¾ç”Ÿå›¾ï¼Œçº¢è‰²é€šé“表示 X 轴上的" +"å˜å½¢ã€ç»¿è‰²é€šé“表示 Y 轴上的å˜å½¢ã€‚å°äºŽ 0.5 的值会æœè´Ÿæ–¹å‘进行å˜å½¢ï¼Œè€Œå¤§äºŽ 0.5 " +"çš„å€¼åˆ™æœæ£æ–¹å‘å˜å½¢ã€‚\n" +"纹ç†çš„ Alpha 通é“如果å˜åœ¨ï¼Œåˆ™ä¼šç”¨äºŽä¸Ž [member anisotropy] 效果的强度相乘。完" +"å…¨ä¸é€æ˜Žçš„åƒç´ ä¼šä¿æŒåŽŸå§‹å¼ºåº¦ï¼Œè€Œå®Œå…¨é€æ˜Žçš„åƒç´ 则会完全ç¦ç”¨å„å‘异性效果。方å‘" +"图纹ç†çš„è“色通é“会被忽略。" #: doc/classes/SpatialMaterial.xml msgid "" @@ -65866,9 +66317,10 @@ msgid "" msgstr "纹ç†ç”¨äºŽæŒ‡å®šç»†èŠ‚çº¹ç†ä¸ŽåŸºç¡€çº¹ç†çš„æ··åˆæ–¹å¼ã€‚" #: doc/classes/SpatialMaterial.xml +#, fuzzy msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -66101,6 +66553,7 @@ msgid "The strength of the normal map's effect." msgstr "法线贴图的效果强度。" #: doc/classes/SpatialMaterial.xml +#, fuzzy msgid "" "Texture used to specify the normal at a given pixel. The " "[code]normal_texture[/code] only uses the red and green channels; the blue " @@ -66112,7 +66565,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -67431,13 +67884,15 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "代表[enum DrawFlags]枚举的大å°ã€‚" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +#, fuzzy +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "AnimatedSprite 的精çµå¸§åº“。" #: doc/classes/SpriteFrames.xml +#, fuzzy msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -67673,14 +68128,14 @@ msgstr "" "@GlobalScope.Error] 错误ç 以åŠä¸€ä¸ªæ•°æ®æ•°ç»„。" #: doc/classes/StreamPeer.xml -#, fuzzy msgid "" "Gets an ASCII string with byte-length [code]bytes[/code] from the stream. If " "[code]bytes[/code] is negative (default) the length will be read from the " "stream using the reverse process of [method put_string]." msgstr "" -"从æµä¸èŽ·å–一个å—节长度为 [code]bytes[/code] çš„å—符串。如果 [code]bytes[/" -"code] 为负(默认),会按照 [method put_string] çš„é€†å‘æ“作从æµä¸è¯»å–长度。" +"从æµä¸èŽ·å–一个å—节长度为 [code]bytes[/code] çš„ ASCII å—符串。如果 " +"[code]bytes[/code] 为负(默认),会按照 [method put_string] çš„é€†å‘æ“作从æµä¸" +"读å–长度。" #: doc/classes/StreamPeer.xml msgid "Gets an unsigned 16-bit value from the stream." @@ -68526,6 +68981,12 @@ msgid "" "print(\", \".join([\"One\", \"Two\", \"Three\", \"Four\"]))\n" "[/codeblock]" msgstr "" +"返回将 [code]parts[/code] 相连åŽå¾—到的 [String]ã€‚å…ƒç´ ä¹‹é—´çš„åˆ†éš”ç¬¦æ˜¯æä¾›è¿™ä¸ªæ–¹" +"法的å—符串。\n" +"示例:\n" +"[codeblock]\n" +"print(\", \".join([\"One\", \"Two\", \"Three\", \"Four\"]))\n" +"[/codeblock]" #: doc/classes/String.xml msgid "" @@ -70001,8 +70462,8 @@ msgid "" "[code]visible[/code] property is set to [code]true[/code] and all others are " "set to [code]false[/code]." msgstr "" -"当剿 ‡ç¾ç´¢å¼•。设置åŽï¼Œæ¤ç´¢å¼•çš„ [Control] 节点的 [code]visible[/code] 属性设置" -"为 [code]true[/code],其他所有设置为 [code]false[/code]。" +"当å‰é€‰é¡¹å¡çš„索引。设置åŽï¼Œæ¤ç´¢å¼•çš„ [Control] 节点的 [code]visible[/code] 属性" +"会被设为 [code]true[/code],其他所有都设置为 [code]false[/code]。" #: doc/classes/TabContainer.xml doc/classes/Tabs.xml msgid "If [code]true[/code], tabs can be rearranged with mouse drag." @@ -72446,7 +72907,6 @@ msgstr "" "å¯ä»¥é€‰æ‹©å¿½ç•¥å›¾å—地图的åŠå移。" #: doc/classes/TileMap.xml -#, fuzzy msgid "" "Sets the tile index for the given cell.\n" "An index of [code]-1[/code] clears the cell.\n" @@ -72467,23 +72927,22 @@ msgid "" " .set_cell(x, y, tile, flip_x, flip_y, transpose, autotile_coord)\n" "[/codeblock]" msgstr "" -"设置由Vector2给出的å•å…ƒæ ¼çš„å›¾å—索引。\n" -"[code]-1[/code]的索引将清除该å•元。\n" -"也å¯ä»¥é€‰æ‹©ç¿»è½¬ã€ç§»ä½ï¼Œæˆ–者指定自动图å—åæ ‡ã€‚自动图å—åæ ‡æŒ‡çš„æ˜¯å图å—的列和" -"行。\n" -"[b]注æ„:[/b] ç”±äºŽæ€§èƒ½åŽŸå› ï¼Œå¯¼èˆªå¤šè¾¹å½¢å’Œç¢°æ’žå½¢çŠ¶ç‰æ•°æ®ä¸ä¼šç«‹å³æ›´æ–°ã€‚\n" -"å¦‚æžœä½ éœ€è¦è¿™äº›è¢«ç«‹å³æ›´æ–°ï¼Œä½ å¯ä»¥è°ƒç”¨[method update_dirty_quadrants]。\n" +"为给定的å•å…ƒæ ¼è®¾ç½®å›¾å—索引。\n" +"索引 [code]-1[/code] 会清除该å•å…ƒæ ¼ã€‚\n" +"也å¯ä»¥å¯¹å›¾å—进行翻转ã€è½¬ç½®ï¼Œæˆ–者指定自动图å—åæ ‡ã€‚自动图å—åæ ‡æŒ‡çš„æ˜¯å图å—çš„" +"列和行。\n" +"[b]注æ„:[/b]ç”±äºŽæ€§èƒ½åŽŸå› ï¼Œå¯¼èˆªå¤šè¾¹å½¢å’Œç¢°æ’žå½¢çŠ¶ç‰æ•°æ®ä¸ä¼šç«‹å³æ›´æ–°ã€‚\n" +"如果需è¦ç«‹å³æ›´æ–°ï¼Œä½ å¯ä»¥è°ƒç”¨ [method update_dirty_quadrants]。\n" "é‡å†™è¯¥æ–¹æ³•会在内部é‡å†™å®ƒï¼Œå…许在放置/ç§»é™¤å›¾å—æ—¶å®žçŽ°è‡ªå®šä¹‰é€»è¾‘ã€‚\n" "[codeblock]\n" "func set_cell(x, y, tile, flip_x=false, flip_y=false, transpose=false, " "autotile_coord=Vector2()):\n" " # åœ¨è¿™é‡Œå†™ä¸‹ä½ çš„è‡ªå®šä¹‰é€»è¾‘ã€‚ \n" -" # 调用默认方法:\n" +" # 调用默认方法:\n" " .set_cell(x, y, tile, flip_x, flip_y, transpose, autotile_coord)\n" "[/codeblock]" #: doc/classes/TileMap.xml -#, fuzzy msgid "" "Sets the tile index for the cell given by a Vector2.\n" "An index of [code]-1[/code] clears the cell.\n" @@ -72495,11 +72954,12 @@ msgid "" "If you need these to be immediately updated, you can call [method " "update_dirty_quadrants]." msgstr "" -"设置给定å•å…ƒæ ¼çš„ç“¦ç‰‡ç´¢å¼•ã€‚\n" -"索引[code]-1[/code]会清除该å•元。\n" -"也å¯ä»¥é€‰æ‹©ç¿»è½¬æˆ–转置图å—。\n" -"[b]注æ„:[/b] ç”±äºŽæ€§èƒ½åŽŸå› ï¼Œå¯¼èˆªå¤šè¾¹å½¢å’Œç¢°æ’žå½¢çŠ¶ç‰æ•°æ®ä¸ä¼šç«‹å³æ›´æ–°ã€‚\n" -"å¦‚æžœä½ éœ€è¦ç«‹å³æ›´æ–°è¿™äº›æ•°æ®ï¼Œå¯ä»¥è°ƒç”¨[method update_dirty_quadrants]。" +"为通过 Vector2 给定的å•å…ƒæ ¼è®¾ç½®å›¾å—索引。\n" +"索引 [code]-1[/code] 会清除该å•å…ƒæ ¼ã€‚\n" +"也å¯ä»¥å¯¹å›¾å—进行翻转ã€è½¬ç½®ï¼Œæˆ–者指定自动图å—åæ ‡ã€‚自动图å—åæ ‡æŒ‡çš„æ˜¯å图å—çš„" +"列和行。\n" +"[b]注æ„:[/b]ç”±äºŽæ€§èƒ½åŽŸå› ï¼Œå¯¼èˆªå¤šè¾¹å½¢å’Œç¢°æ’žå½¢çŠ¶ç‰æ•°æ®ä¸ä¼šç«‹å³æ›´æ–°ã€‚\n" +"å¦‚æžœä½ éœ€è¦ç«‹å³æ›´æ–°è¿™äº›æ•°æ®ï¼Œå¯ä»¥è°ƒç”¨ [method update_dirty_quadrants]。" #: doc/classes/TileMap.xml msgid "Sets the given collision layer bit." @@ -72666,16 +73126,16 @@ msgid "" "option, because displacing textures with the [member cell_tile_origin] " "option or in irregular tiles is not relevant when centering those textures." msgstr "" -"如果[code]为true[/code]ï¼Œåˆ™ä¿æŒä¸ŽGodot 3.1或更早版本的图å—地图的兼容性,å³å½“" -"图å—åŽŸç‚¹æ”¹å˜æ—¶ï¼Œçº¹ç†ä¼šç§»åŠ¨ï¼Œå¦‚æžœçº¹ç†å¤§å°ä¸å‡åŒ€ï¼Œåˆ™ä¼šæ—‹è½¬ã€‚è¿™ç§æ¨¡å¼å¯¹éžåŒè´¨ç‰" -"è·å›¾å—(例如2:1)进行[code]flip_h[/code], [code]flip_v[/code] å’Œ " +"如果为 [code]true[/code]ï¼Œåˆ™ä¿æŒä¸Ž Godot 3.1 或更早版本的图å—地图的兼容性,å³" +"当图å—åŽŸç‚¹æ”¹å˜æ—¶ï¼Œçº¹ç†ä¼šç§»åŠ¨ï¼Œå¦‚æžœçº¹ç†å¤§å°ä¸å‡åŒ€ï¼Œåˆ™ä¼šæ—‹è½¬ã€‚è¿™ç§æ¨¡å¼å¯¹éžåŒè´¨" +"ç‰è·å›¾å—(例如 2:1)进行 [code]flip_h[/code]ã€[code]flip_v[/code]ã€" "[code]transpose[/code] 图嗿“ä½œæ—¶ï¼Œå°†å‡ºçŽ°é—®é¢˜ï¼Œåœ¨è¿™ç§æƒ…况下,纹ç†ä¸èƒ½ä¸Žç¢°æ’žé‡" "åˆï¼Œå› æ¤ä¸æŽ¨è用于ç‰è·æˆ–éžæ–¹å½¢å›¾å—。\n" -"如果[code]false[/code],在进行[code]flip_h[/code]ã€[code]flip_v[/code]æ“作" -"时,如果ä¸ä½¿ç”¨åç§»é‡ï¼Œçº¹ç†ä¸ä¼šç§»åŠ¨ï¼Œåœ¨æ”¹å˜å›¾å—原点时也是如æ¤ã€‚\n" -"兼容性模å¼å¯¹[member centered_textures]选项ä¸èµ·ä½œç”¨ï¼Œå› 为用[member " -"cell_tile_origin]选项或ä¸è§„则图å—ä¸çš„纹ç†è¿›è¡Œæ›¿æ¢æ—¶ï¼Œä¸Žè¿™äº›çº¹ç†çš„å±…ä¸é¡¹æ²¡æœ‰å…³" -"系。" +"如果为 [code]false[/code],则在进行 [code]flip_h[/code]ã€[code]flip_v[/code] " +"æ“作时,如果ä¸ä½¿ç”¨åç§»é‡ï¼Œçº¹ç†ä¸ä¼šç§»åŠ¨ï¼Œåœ¨æ”¹å˜å›¾å—原点时也是如æ¤ã€‚\n" +"兼容性模å¼å¯¹ [member centered_textures] 选项ä¸èµ·ä½œç”¨ï¼Œå› 为用 [member " +"cell_tile_origin] 选项或ä¸è§„则图å—ä¸çš„纹ç†è¿›è¡Œæ›¿æ¢æ—¶ï¼Œä¸Žè¿™äº›çº¹ç†çš„å±…ä¸é¡¹æ²¡æœ‰" +"关系。" #: doc/classes/TileMap.xml msgid "The TileMap orientation mode. See [enum Mode] for possible values." @@ -75172,6 +75632,7 @@ msgid "Smoothly animates a node's properties over time." msgstr "ä½¿èŠ‚ç‚¹çš„å±žæ€§éšæ—¶é—´å¹³æ»‘地å˜åŒ–。" #: doc/classes/Tween.xml +#, fuzzy msgid "" "Tweens are useful for animations requiring a numerical property to be " "interpolated over a range of values. The name [i]tween[/i] comes from [i]in-" @@ -75205,7 +75666,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" "需è¦è®©æ•°å€¼å±žæ€§åœ¨ä¸€å®šèŒƒå›´å†…åšæ’值的动画å¯ä»¥ä½¿ç”¨ Tween。[i]Tween[/i] 这个åå—æ¥" "自动画技术 [i]in-betweening[/i]ï¼ˆè¡¥é—´åŠ¨ç”»ï¼‰ï¼šä½ æŒ‡å®š[i]关键帧[/i],而计算机则" @@ -75468,9 +75931,9 @@ msgid "" "code] for half of the normal speed. A value of [code]0[/code] pauses the " "animation, but see also [method set_active] or [method stop_all] for this." msgstr "" -"补间的速度乘数。例如,设置为[code]1.0[/code]为æ£å¸¸é€Ÿåº¦ï¼Œ[code]2.0[/code]为æ£" -"常速度的2å€ï¼Œæˆ–者[code]0.5[/code]为æ£å¸¸é€Ÿåº¦çš„一åŠã€‚值为[code]0[/code]时,动画" -"会暂åœï¼Œå¦è¯·å‚阅[method set_active]或[method stop_all]。" +"补间的速度乘数。例如,设置为 [code]1.0[/code] 为æ£å¸¸é€Ÿåº¦ï¼Œ[code]2.0[/code] 为" +"æ£å¸¸é€Ÿåº¦çš„ 2 å€ï¼Œæˆ–者 [code]0.5[/code] 为æ£å¸¸é€Ÿåº¦çš„一åŠã€‚值为 [code]0[/code] " +"时,动画会暂åœï¼Œå¦è¯·å‚阅 [method set_active] 或 [method stop_all]。" #: doc/classes/Tween.xml msgid "If [code]true[/code], the tween loops." @@ -76692,8 +77155,17 @@ msgstr "" "通过é™åˆ¶å…¶é•¿åº¦ä¸º [code]length[/code],返回具有最大长度的å‘é‡ã€‚" #: doc/classes/Vector2.xml -msgid "Returns the cross product of this vector and [code]with[/code]." -msgstr "返回æ¤å‘é‡ä¸Ž[code]with[/code]çš„å‰ç§¯ã€‚" +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." +msgstr "" #: doc/classes/Vector2.xml msgid "" @@ -76801,11 +77273,12 @@ msgstr "" "code]。[code]weight[/code]的范围是0.0到1.0,表示æ’值的数é‡ã€‚" #: doc/classes/Vector2.xml doc/classes/Vector3.xml -#, fuzzy msgid "" "Returns a new vector moved toward [code]to[/code] by the fixed [code]delta[/" "code] amount. Will not go past the final value." -msgstr "å‘[code]to[/code]移动固定的[code]delta[/code]é‡ã€‚" +msgstr "" +"è¿”å›žå‘ [code]to[/code] 移动固定的 [code]delta[/code] é‡åŽçš„æ–°å‘é‡ã€‚ä¸ä¼šè¶…过最" +"终值。" #: doc/classes/Vector2.xml doc/classes/Vector3.xml msgid "" @@ -76830,16 +77303,16 @@ msgstr "" "çš„å‘é‡ã€‚" #: doc/classes/Vector2.xml doc/classes/Vector3.xml -#, fuzzy msgid "Returns this vector projected onto the vector [code]b[/code]." -msgstr "返回投射到å‘é‡[code]b[/code]çš„å‘é‡ã€‚" +msgstr "返回投射到å‘é‡ [code]b[/code] çš„å‘é‡ã€‚" #: doc/classes/Vector2.xml -#, fuzzy msgid "" "Returns the vector reflected (i.e. mirrored, or symmetric) over a line " "defined by the given direction vector [code]n[/code]." -msgstr "返回从给定法线定义的平é¢åå°„çš„å‘é‡ã€‚" +msgstr "" +"返回ç»è¿‡ç”±ç»™å®šçš„æ–¹å‘å‘é‡ [code]n[/code] 定义的线åå°„åŽçš„(å³é•œåƒæˆ–对称)å‘" +"é‡ã€‚" #: doc/classes/Vector2.xml msgid "" @@ -76848,7 +77321,6 @@ msgid "" msgstr "返回旋转了[code]phi[/code]弧度的å‘é‡ã€‚å‚阅[method @GDScript.deg2rad]。" #: doc/classes/Vector2.xml doc/classes/Vector3.xml -#, fuzzy msgid "" "Returns a new vector with all components rounded to the nearest integer, " "with halfway cases rounded away from zero." @@ -76856,13 +77328,13 @@ msgstr "" "返回所有分é‡éƒ½è¢«å››èˆäº”入为最接近的整数的å‘é‡ï¼Œä¸é—´æƒ…况å‘远离零的方å‘èˆå…¥ã€‚" #: doc/classes/Vector2.xml doc/classes/Vector3.xml -#, fuzzy msgid "" "Returns a new vector with each component set to one or negative one, " "depending on the signs of the components. If a component is zero, it returns " "positive one." msgstr "" -"æ ¹æ®åˆ†é‡çš„符å·ï¼Œè¿”回æ¯ä¸ªåˆ†é‡è®¾ç½®ä¸º 1 或负1çš„å‘é‡ã€‚如果分é‡ä¸ºé›¶ï¼Œåˆ™è¿”回æ£1。" +"æ ¹æ®åˆ†é‡çš„符å·ï¼Œè¿”回æ¯ä¸ªåˆ†é‡è®¾ç½®ä¸º 1 或负 1 çš„å‘é‡ã€‚如果分é‡ä¸ºé›¶ï¼Œåˆ™è¿”å›žæ£ " +"1。" #: doc/classes/Vector2.xml doc/classes/Vector3.xml msgid "" @@ -76974,16 +77446,15 @@ msgid "Returns the cross product of this vector and [code]b[/code]." msgstr "返回æ¤å‘é‡ä¸Ž [code]b[/code] çš„å‰ç§¯ã€‚" #: doc/classes/Vector3.xml -#, fuzzy msgid "" "Performs a cubic interpolation between this vector and [code]b[/code] using " "[code]pre_a[/code] and [code]post_b[/code] as handles, and returns the " "result at position [code]weight[/code]. [code]weight[/code] is on the range " "of 0.0 to 1.0, representing the amount of interpolation." msgstr "" -"用[code]pre_a[/code]å’Œ[code]post_b[/code]ä½œä¸ºå¥æŸ„,在这个å‘é‡å’Œ[code]b[/code]" -"之间进行三次æ’值,并在[code]weight[/code]ä½ç½®è¿”回结果。[code]weight[/code]çš„" -"范围是0.0到1.0,表示æ’值的é‡ã€‚" +"用 [code]pre_a[/code] å’Œ [code]post_b[/code] ä½œä¸ºå¥æŸ„,在这个å‘é‡å’Œ [code]b[/" +"code] 之间进行三次æ’值,并在 [code]weight[/code] ä½ç½®è¿”回结果。[code]weight[/" +"code] 的范围是 0.0 到 1.0,表示æ’值的é‡ã€‚" #: doc/classes/Vector3.xml msgid "Returns the distance between this vector and [code]b[/code]." @@ -77909,7 +78380,6 @@ msgid "" msgstr "如果[code]true[/code],视窗上的GUI控件将完美地放置åƒç´ 。" #: doc/classes/Viewport.xml -#, fuzzy msgid "" "If [code]true[/code], the viewport rendering will receive benefits from High " "Dynamic Range algorithm. High Dynamic Range allows the viewport to receive " @@ -77920,11 +78390,12 @@ msgid "" "[constant USAGE_3D_NO_EFFECTS], since HDR is not supported for 2D.\n" "[b]Note:[/b] Only available on the GLES3 backend." msgstr "" -"如果[code]true[/code],视窗的渲染将获得高动æ€èŒƒå›´ç®—法的收益。高动æ€èŒƒå›´å…许视" -"窗接收0-1范围以外的数值。在Godotä¸HDR使用16比特,这æ„味ç€å®ƒä¸èƒ½å˜å‚¨æµ®ç‚¹æ•°çš„å…¨" -"部范围。\n" -"[b]注æ„:[/b] 需è¦å°† [member usage]设置为[constant USAGE_3D]或[constant " -"USAGE_3D_NO_EFFECTS],2D䏿”¯æŒHDR。" +"如果为 [code]true[/code],视窗的渲染将获益于高动æ€èŒƒå›´ç®—法。高动æ€èŒƒå›´å…许视" +"窗接收 0-1 范围以外的数值。在 Godot ä¸ HDR 默认使用åŠç²¾åº¦æµ®ç‚¹æ•°ï¼ˆ16 ä½ï¼‰ã€‚è¦" +"使用全精度浮点数(32 ä½ï¼‰ï¼Œè¯·å¯ç”¨ [member use_32_bpc_depth]。\n" +"[b]注æ„:[/b]需è¦å°† [member usage] 设置为 [constant USAGE_3D] 或 [constant " +"USAGE_3D_NO_EFFECTS]ï¼Œå› ä¸º HDR 䏿”¯æŒ 2D。\n" +"[b]注æ„:[/b]仅在 GLES3 åŽç«¯ä¸å¯ç”¨ã€‚" #: doc/classes/Viewport.xml msgid "" @@ -78074,6 +78545,12 @@ msgid "" "enable [member debanding] instead.\n" "[b]Note:[/b] Only available on the GLES3 backend." msgstr "" +"如果为 [code]true[/code],分é…该视窗的帧缓冲时将使用完整浮点数精度(32 ä½ï¼‰è€Œ" +"䏿˜¯åŠæµ®ç‚¹æ•°ç²¾åº¦ï¼ˆ16 ä½ï¼‰ã€‚ä»…åœ¨åŒæ—¶å¯ç”¨ [member hdr] 时有效。\n" +"[b]注æ„:[/b]å¯ç”¨è¿™ä¸ªè®¾ç½®ä¸ä¼šæå‡æ¸²æŸ“è´¨é‡ã€‚ä½¿ç”¨å®Œæ•´æµ®ç‚¹æ•°ç²¾åº¦è¾ƒæ…¢ï¼Œä¸€èˆ¬åªæœ‰è¦" +"求更高精度的高级ç€è‰²å™¨éœ€è¦ä½¿ç”¨ã€‚如果是è¦å‡å°‘æ¡å¸¦æ•ˆåº”,请å¯ç”¨ [member " +"debanding]。\n" +"[b]注æ„:[/b]仅在 GLES3 åŽç«¯ä¸å¯ç”¨ã€‚" #: doc/classes/Viewport.xml msgid "The custom [World] which can be used as 3D environment source." @@ -78189,7 +78666,7 @@ msgstr "表示 [enum RenderInfo] 枚举的大å°ã€‚" #: doc/classes/Viewport.xml msgid "Objects are displayed normally." -msgstr "对象显示æ£å¸¸ã€‚" +msgstr "对象æ£å¸¸æ˜¾ç¤ºã€‚" #: doc/classes/Viewport.xml msgid "Objects are displayed without light information." @@ -78664,7 +79141,7 @@ msgstr "" #: modules/visual_script/doc_classes/VisualScript.xml msgid "A script implemented in the Visual Script programming environment." -msgstr "一个在å¯è§†åŒ–脚本编程环境ä¸å®žçŽ°çš„è„šæœ¬ã€‚" +msgstr "在 Visual Script 编程环境ä¸å®žçŽ°çš„è„šæœ¬ã€‚" #: modules/visual_script/doc_classes/VisualScript.xml msgid "" @@ -78682,36 +79159,35 @@ msgstr "" "您最有å¯èƒ½é€šè¿‡ Visual Script 编辑器或在为其编写æ’件时使用æ¤ç±»ã€‚" #: modules/visual_script/doc_classes/VisualScript.xml -#, fuzzy msgid "$DOCS_URL/tutorials/scripting/visual_script/index.html" -msgstr "$DOCS_URL/getting_started/scripting/visual_script/index.html" +msgstr "$DOCS_URL/tutorials/scripting/visual_script/index.html" #: modules/visual_script/doc_classes/VisualScript.xml msgid "Add a custom signal with the specified name to the VisualScript." -msgstr "在å¯è§†åŒ–è„šæœ¬ä¸æ·»åŠ æŒ‡å®šå称的自定义信å·ã€‚" +msgstr "在 VisualScript 䏿·»åŠ æŒ‡å®šå称的自定义信å·ã€‚" #: modules/visual_script/doc_classes/VisualScript.xml msgid "Add a function with the specified name to the VisualScript." -msgstr "在å¯è§†åŒ–è„šæœ¬ä¸æ·»åŠ æŒ‡å®šå称的函数。" +msgstr "在 VisualScript 䏿·»åŠ æŒ‡å®šå称的函数。" #: modules/visual_script/doc_classes/VisualScript.xml msgid "Add a node to a function of the VisualScript." -msgstr "å‘å¯è§†åŒ–è„šæœ¬çš„å‡½æ•°æ·»åŠ èŠ‚ç‚¹ã€‚" +msgstr "å‘ VisualScript çš„å‡½æ•°æ·»åŠ èŠ‚ç‚¹ã€‚" #: modules/visual_script/doc_classes/VisualScript.xml msgid "" "Add a variable to the VisualScript, optionally giving it a default value or " "marking it as exported." -msgstr "在å¯è§†åŒ–è„šæœ¬ä¸æ·»åŠ ä¸€ä¸ªå˜é‡ï¼Œå¯é€‰æ‹©ç»™å®ƒä¸€ä¸ªé»˜è®¤å€¼æˆ–å°†å…¶æ ‡è®°ä¸ºå¯¼å‡ºã€‚" +msgstr "在 VisualScript 䏿·»åŠ ä¸€ä¸ªå˜é‡ï¼Œå¯é€‰æ‹©ç»™å®ƒä¸€ä¸ªé»˜è®¤å€¼æˆ–å°†å…¶æ ‡è®°ä¸ºå¯¼å‡ºã€‚" #: modules/visual_script/doc_classes/VisualScript.xml msgid "" "Add an argument to a custom signal added with [method add_custom_signal]." -msgstr "为用[method add_custom_signal]æ·»åŠ çš„è‡ªå®šä¹‰ä¿¡å·æ·»åŠ ä¸€ä¸ªå‚æ•°ã€‚" +msgstr "为用 [method add_custom_signal] æ·»åŠ çš„è‡ªå®šä¹‰ä¿¡å·æ·»åŠ ä¸€ä¸ªå‚æ•°ã€‚" #: modules/visual_script/doc_classes/VisualScript.xml msgid "Get the count of a custom signal's arguments." -msgstr "获å–自定义信å·çš„傿•°è®¡æ•°ã€‚" +msgstr "获å–自定义信å·çš„傿•°ä¸ªæ•°ã€‚" #: modules/visual_script/doc_classes/VisualScript.xml msgid "Get the name of a custom signal's argument." @@ -78753,7 +79229,7 @@ msgstr "æ–开之å‰ç”¨[method data_connect]连接的两个数æ®ç«¯å£ã€‚" #: modules/visual_script/doc_classes/VisualScript.xml msgid "Returns the id of a function's entry point node." -msgstr "返回函数入å£ç‚¹èŠ‚ç‚¹çš„ID。" +msgstr "返回函数入å£ç‚¹èŠ‚ç‚¹çš„ ID。" #: modules/visual_script/doc_classes/VisualScript.xml msgid "Returns the position of the center of the screen for a given function." @@ -78850,7 +79326,7 @@ msgstr "" msgid "" "Disconnect two sequence ports previously connected with [method " "sequence_connect]." -msgstr "æ–开之å‰ç”¨[method sequence_connect]连接的两个åºåˆ—端å£ã€‚" +msgstr "æ–开之å‰ç”¨ [method sequence_connect] 连接的两个åºåˆ—端å£ã€‚" #: modules/visual_script/doc_classes/VisualScript.xml msgid "Position the center of the screen for a function." @@ -78883,13 +79359,13 @@ msgstr "å½“èŠ‚ç‚¹ç«¯å£æ›´æ”¹æ—¶è§¦å‘。" #: modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml msgid "A Visual Script node representing a constant from the base types." -msgstr "一个å¯è§†åŒ–脚本节点,表示基本类型ä¸çš„一个常é‡ã€‚" +msgstr "一个 Visual Script 节点,表示基本类型ä¸çš„一个常é‡ã€‚" #: modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml msgid "" "A Visual Script node representing a constant from base types, such as " "[constant Vector3.AXIS_X]." -msgstr "表示基本类型常é‡çš„å¯è§†åŒ–脚本节点,如[constant Vector3.AXIS_X]。" +msgstr "表示基本类型常é‡çš„ Visual Script 节点,如 [constant Vector3.AXIS_X]。" #: modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml msgid "The type to get the constant from." @@ -78901,7 +79377,7 @@ msgstr "è¦è¿”回的常é‡çš„å称。" #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "A Visual Script node used to call built-in functions." -msgstr "用于调用内置函数的å¯è§†åŒ–脚本节点。" +msgstr "用于调用内置函数的 Visual Script 节点。" #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "" @@ -79123,7 +79599,7 @@ msgstr "将输入从分è´éŸ³é‡è½¬æ¢ä¸ºçº¿æ€§éŸ³é‡ã€‚" #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "Return the greater of the two numbers, also known as their maximum." -msgstr "返回两个数å—ä¸è¾ƒå¤§çš„一个,也称为它们的最大值。" +msgstr "返回两个数å—ä¸è¾ƒå¤§çš„一个,也被称为它们的最大值。" #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "Return the lesser of the two numbers, also known as their minimum." @@ -79234,7 +79710,7 @@ msgstr "" #: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml msgid "Represents the size of the [enum BuiltinFunc] enum." -msgstr "表示[enum BuiltinFunc]枚举的大å°ã€‚" +msgstr "表示 [enum BuiltinFunc] 枚举的大å°ã€‚" #: modules/visual_script/doc_classes/VisualScriptClassConstant.xml msgid "Gets a constant from a given class." @@ -79249,12 +79725,12 @@ msgid "" "[b]Output Ports:[/b]\n" "- Data (variant): [code]value[/code]" msgstr "" -"该节点从指定类ä¸è¿”回常é‡ï¼Œä¾‹å¦‚[constant TYPE_INT]。关于å¯ç”¨çš„常é‡ï¼Œè¯·å‚阅指定" -"类的文档。\n" -"[b]Input Ports:[/b]\n" -"none\n" -"[b]Output Ports:[/b]\n" -"- Data (variant): [code]value[/code]" +"该节点从指定类ä¸è¿”回常é‡ï¼Œä¾‹å¦‚ [constant TYPE_INT]。关于å¯ç”¨çš„常é‡ï¼Œè¯·å‚阅指" +"定类的文档。\n" +"[b]输入端å£ï¼š[/b]\n" +"æ— \n" +"[b]输出端å£ï¼š[/b]\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]value[/code]" #: modules/visual_script/doc_classes/VisualScriptClassConstant.xml msgid "The constant's parent class." @@ -79267,7 +79743,7 @@ msgstr "è¦è¿”回的常é‡ã€‚å¯ç”¨çš„常é‡å‚阅给定的类。" #: modules/visual_script/doc_classes/VisualScriptComment.xml msgid "A Visual Script node used to annotate the script." -msgstr "用于注释脚本的å¯è§†åŒ–脚本节点。" +msgstr "用于注释脚本的 Visual Script 节点。" #: modules/visual_script/doc_classes/VisualScriptComment.xml msgid "" @@ -79275,7 +79751,7 @@ msgid "" "may be documented.\n" "Comment nodes can be resized so they encompass a group of nodes." msgstr "" -"å¯è§†åŒ–脚本节点,用于显示脚本ä¸çš„æ³¨é‡Šï¼Œä»¥ä¾¿è®°å½•代ç 。\n" +"Visual Script 节点,用于显示脚本ä¸çš„æ³¨é‡Šï¼Œä»¥ä¾¿ä¸ºä»£ç æä¾›æ–‡æ¡£ã€‚\n" "注释节点å¯ä»¥è°ƒæ•´å¤§å°ï¼Œä»¥ä¾¿åŒ…å«ä¸€ç»„节点。" #: modules/visual_script/doc_classes/VisualScriptComment.xml @@ -79292,19 +79768,19 @@ msgstr "æ³¨é‡ŠèŠ‚ç‚¹çš„æ ‡é¢˜ã€‚" #: modules/visual_script/doc_classes/VisualScriptComposeArray.xml msgid "A Visual Script Node used to create array from a list of items." -msgstr "å¯è§†åŒ–脚本节点,用于从项目列表ä¸åˆ›å»ºæ•°ç»„。" +msgstr "Visual Script 节点,用于从项目列表ä¸åˆ›å»ºæ•°ç»„。" #: modules/visual_script/doc_classes/VisualScriptComposeArray.xml msgid "" "A Visual Script Node used to compose array from the list of elements " "provided with custom in-graph UI hard coded in the VisualScript Editor." msgstr "" -"å¯è§†åŒ–脚本节点,用于从å¯è§†åŒ–脚本编辑器ä¸ç¡¬ç¼–ç 的自定义图åƒå†…ç”¨æˆ·ç•Œé¢æä¾›çš„å…ƒ" -"ç´ åˆ—è¡¨ä¸ç»„æˆæ•°ç»„。" +"Visual Script 节点,用于从å¯è§†åŒ–脚本编辑器ä¸ç¡¬ç¼–ç 的自定义图åƒå†…ç”¨æˆ·ç•Œé¢æä¾›" +"çš„å…ƒç´ åˆ—è¡¨ä¸ç»„æˆæ•°ç»„。" #: modules/visual_script/doc_classes/VisualScriptCondition.xml msgid "A Visual Script node which branches the flow." -msgstr "å¯è§†åŒ–脚本节点,它是æµç¨‹çš„分支。" +msgstr "Visual Script 节点,它是æµç¨‹çš„分支。" #: modules/visual_script/doc_classes/VisualScriptCondition.xml msgid "" @@ -79320,16 +79796,16 @@ msgid "" "- Sequence: [code]false[/code]\n" "- Sequence: [code]done[/code]" msgstr "" -"å¯è§†åŒ–脚本节点,检查一个[bool]输入端å£ã€‚如果[code]true[/code],它将通过 " -"\"true\" åºåˆ—端å£é€€å‡ºã€‚如果[code]false[/code],它将通过 \"false\" åºåˆ—端å£é€€" -"å‡ºã€‚åœ¨é€€å‡ºè¿™ä¸¤ç§æƒ…况åŽï¼Œå®ƒé€šè¿‡ \"done\" 端å£é€€å‡ºã€‚åºåˆ—端å£å¯ä»¥ä¸è¿žæŽ¥ã€‚\n" -"[b]Input Ports:[/b]\n" -"- Sequence: [code]if (cond) is[/code]\n" -"- Data (boolean): [code]cond[/code]\n" -"[b]Output Ports:[/b]\n" -"- Sequence: [code]true[/code]\n" -"- Sequence: [code]false[/code]\n" -"- Sequence: [code]done[/code]" +"Visual Script 节点,检查 [bool] 输入端å£ã€‚如果为 [code]true[/code],它将通" +"过“trueâ€åºåˆ—端å£é€€å‡ºã€‚如果为 [code]false[/code],它将通过“falseâ€åºåˆ—端å£é€€" +"å‡ºã€‚åœ¨é€€å‡ºè¿™ä¸¤ç§æƒ…况åŽï¼Œå®ƒé€šè¿‡â€œdoneâ€ç«¯å£é€€å‡ºã€‚åºåˆ—端å£å¯ä»¥ä¸è¿žæŽ¥ã€‚\n" +"[b]输入端å£ï¼š[/b]\n" +"- åºåˆ—:[code]if (cond) is[/code]\n" +"- æ•°æ®ï¼ˆå¸ƒå°”):[code]cond[/code]\n" +"[b]输出端å£ï¼š[/b]\n" +"- åºåˆ—:[code]true[/code]\n" +"- åºåˆ—:[code]false[/code]\n" +"- åºåˆ—:[code]done[/code]" #: modules/visual_script/doc_classes/VisualScriptConstant.xml msgid "Gets a contant's value." @@ -79344,10 +79820,10 @@ msgid "" "- Data (variant): [code]get[/code]" msgstr "" "该节点返回常é‡çš„值。\n" -"[b]Input Ports:[/b]\n" -"none\n" -"[b]Output Ports:[/b]\n" -"- Data (variant): [code]get[/code]" +"[b]输入端å£ï¼š[/b]\n" +"æ— \n" +"[b]输出端å£ï¼š[/b]\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]get[/code]" #: modules/visual_script/doc_classes/VisualScriptConstant.xml msgid "The constant's type." @@ -79359,21 +79835,21 @@ msgstr "常é‡çš„值。" #: modules/visual_script/doc_classes/VisualScriptConstructor.xml msgid "A Visual Script node which calls a base type constructor." -msgstr "å¯è§†åŒ–è„šæœ¬èŠ‚ç‚¹ï¼Œè°ƒç”¨ä¸€ä¸ªåŸºæœ¬ç±»åž‹çš„æž„é€ å‡½æ•°ã€‚" +msgstr "Visual Script èŠ‚ç‚¹ï¼Œè°ƒç”¨ä¸€ä¸ªåŸºæœ¬ç±»åž‹çš„æž„é€ å‡½æ•°ã€‚" #: modules/visual_script/doc_classes/VisualScriptConstructor.xml msgid "" "A Visual Script node which calls a base type constructor. It can be used for " "type conversion as well." -msgstr "å¯è§†åŒ–è„šæœ¬èŠ‚ç‚¹ï¼Œè°ƒç”¨ä¸€ä¸ªåŸºæœ¬ç±»åž‹çš„æž„é€ å‡½æ•°ã€‚å®ƒä¹Ÿå¯ä»¥ç”¨äºŽç±»åž‹è½¬æ¢ã€‚" +msgstr "Visual Script èŠ‚ç‚¹ï¼Œè°ƒç”¨ä¸€ä¸ªåŸºæœ¬ç±»åž‹çš„æž„é€ å‡½æ•°ã€‚å®ƒä¹Ÿå¯ä»¥ç”¨äºŽç±»åž‹è½¬æ¢ã€‚" #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "A scripted Visual Script node." -msgstr "有脚本的å¯è§†åŒ–脚本节点。" +msgstr "有脚本的 Visual Script 节点。" #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "A custom Visual Script node which can be scripted in powerful ways." -msgstr "自定义的å¯è§†åŒ–脚本节点,å¯ä»¥ç”¨å¼ºå¤§çš„æ–¹å¼è¿›è¡Œè„šæœ¬ç¼–å†™ã€‚" +msgstr "自定义的 Visual Script 节点,å¯ä»¥ç”¨å¼ºå¤§çš„æ–¹å¼è¿›è¡Œè„šæœ¬ç¼–å†™ã€‚" #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "Return the node's title." @@ -79408,11 +79884,11 @@ msgstr "返回指定输入端å£çš„类型。å‚阅[enum Variant.Type]值。" #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "Return the amount of output [b]sequence[/b] ports." -msgstr "返回输出[b]sequence[/b]åºåˆ—端å£çš„æ•°é‡ã€‚" +msgstr "返回输出[b]åºåˆ—[/b]端å£çš„æ•°é‡ã€‚" #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "Return the specified [b]sequence[/b] output's name." -msgstr "返回指定的[b]sequence[/b]åºåˆ—输出的å称。" +msgstr "返回指定的[b]åºåˆ—[/b]输出的å称。" #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "Return the amount of output value ports." @@ -79443,8 +79919,8 @@ msgid "" "[b]sequence[/b] port (if there is none, on the place that is usually taken " "by it)." msgstr "" -"返回自定义节点的文本,就在输入[b]sequence[/b]åºåˆ—ç«¯å£æ—边显示,如果没有,则在" -"通常被它å 用的ä½ç½®ã€‚" +"返回自定义节点的文本,就在输入[b]åºåˆ—[/b]ç«¯å£æ—边显示,如果没有,则在通常被它" +"å 用的ä½ç½®ã€‚" #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "" @@ -79454,7 +79930,7 @@ msgstr "返回自定义节点的è¿è¡Œå†…å˜çš„大å°ã€‚更多细节å‚阅 [meth #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "Return whether the custom node has an input [b]sequence[/b] port." -msgstr "è¿”å›žè‡ªå®šä¹‰èŠ‚ç‚¹æ˜¯å¦æœ‰è¾“å…¥[b]sequence[/b]åºåˆ—端å£ã€‚" +msgstr "è¿”å›žè‡ªå®šä¹‰èŠ‚ç‚¹æ˜¯å¦æœ‰è¾“å…¥[b]åºåˆ—[/b]端å£ã€‚" #: modules/visual_script/doc_classes/VisualScriptCustomNode.xml msgid "" @@ -79536,7 +80012,7 @@ msgstr "" #: modules/visual_script/doc_classes/VisualScriptDeconstruct.xml msgid "" "A Visual Script node which deconstructs a base type instance into its parts." -msgstr "å¯è§†åŒ–脚本节点,它将一个基本类型的实例解构为其å„个部分。" +msgstr "Visual Script 节点,它将一个基本类型的实例解构为其å„个部分。" #: modules/visual_script/doc_classes/VisualScriptDeconstruct.xml msgid "The type to deconstruct." @@ -79547,20 +80023,20 @@ msgid "" "Add a custom Visual Script node to the editor. It'll be placed under " "\"Custom Nodes\" with the [code]category[/code] as the parameter." msgstr "" -"åœ¨ç¼–è¾‘å™¨ä¸æ·»åŠ è‡ªå®šä¹‰å¯è§†åŒ–脚本节点。它放在 \"自定义节点\" 下,以" -"[code]category[/code]ä½œä¸ºå‚æ•°ã€‚" +"åœ¨ç¼–è¾‘å™¨ä¸æ·»åŠ è‡ªå®šä¹‰ Visual Script 节点。它放在“自定义节点â€ä¸‹ï¼Œä»¥ " +"[code]category[/code] ä½œä¸ºå‚æ•°ã€‚" #: modules/visual_script/doc_classes/VisualScriptEditor.xml msgid "" "Remove a custom Visual Script node from the editor. Custom nodes already " "placed on scripts won't be removed." msgstr "" -"从编辑器ä¸åˆ 除一个自定义å¯è§†åŒ–è„šæœ¬èŠ‚ç‚¹ã€‚å·²ç»æ”¾åœ¨è„šæœ¬ä¸Šçš„è‡ªå®šä¹‰èŠ‚ç‚¹ä¸ä¼šè¢«åˆ " -"除。" +"从编辑器ä¸åˆ 除一个自定义 Visual Script èŠ‚ç‚¹ã€‚å·²ç»æ”¾åœ¨è„šæœ¬ä¸Šçš„è‡ªå®šä¹‰èŠ‚ç‚¹ä¸ä¼šè¢«" +"åˆ é™¤ã€‚" #: modules/visual_script/doc_classes/VisualScriptEditor.xml msgid "Emitted when a custom Visual Script node is added or removed." -msgstr "å½“æ·»åŠ æˆ–åˆ é™¤ä¸€ä¸ªè‡ªå®šä¹‰å¯è§†åŒ–脚本节点时触å‘。" +msgstr "å½“æ·»åŠ æˆ–åˆ é™¤ä¸€ä¸ªè‡ªå®šä¹‰ Visual Script 节点时触å‘。" #: modules/visual_script/doc_classes/VisualScriptEmitSignal.xml msgid "Emits a specified signal." @@ -79575,10 +80051,10 @@ msgid "" "- Sequence" msgstr "" "当它被执行时å‘出一个指定的信å·ã€‚\n" -"[b]Input Ports:[/b]\n" -"- Sequence: [code]emit[/code]\n" -"[b]Output Ports:[/b]\n" -"- Sequence" +"[b]输入端å£ï¼š[/b]\n" +"- åºåˆ—:[code]emit[/code]\n" +"[b]输出端å£ï¼š[/b]\n" +"- åºåˆ—" #: modules/visual_script/doc_classes/VisualScriptEmitSignal.xml msgid "The signal to emit." @@ -79586,7 +80062,7 @@ msgstr "触å‘的信å·ã€‚" #: modules/visual_script/doc_classes/VisualScriptEngineSingleton.xml msgid "A Visual Script node returning a singleton from [@GlobalScope]." -msgstr "从 [@GlobalScope] 返回å•例的å¯è§†åŒ–脚本节点。" +msgstr "从 [@GlobalScope] 返回å•例的 Visual Script 节点。" #: modules/visual_script/doc_classes/VisualScriptEngineSingleton.xml msgid "The singleton's name." @@ -79594,7 +80070,7 @@ msgstr "å•例的å称。" #: modules/visual_script/doc_classes/VisualScriptExpression.xml msgid "A Visual Script node that can execute a custom expression." -msgstr "å¯ä»¥æ‰§è¡Œè‡ªå®šä¹‰è¡¨è¾¾å¼çš„å¯è§†åŒ–脚本节点。" +msgstr "å¯ä»¥æ‰§è¡Œè‡ªå®šä¹‰è¡¨è¾¾å¼çš„ Visual Script 节点。" #: modules/visual_script/doc_classes/VisualScriptExpression.xml msgid "" @@ -79602,12 +80078,12 @@ msgid "" "provided for the input and the expression result can be retrieved from the " "output." msgstr "" -"å¯ä»¥æ‰§è¡Œè‡ªå®šä¹‰è¡¨è¾¾å¼çš„å¯è§†åŒ–脚本节点。å¯ä»¥ä¸ºè¾“å…¥æä¾›å€¼ï¼Œå¹¶ä¸”å¯ä»¥ä»Žè¾“å‡ºä¸æ£€ç´¢" -"表达å¼ç»“果。" +"å¯ä»¥æ‰§è¡Œè‡ªå®šä¹‰è¡¨è¾¾å¼çš„ Visual Script 节点。å¯ä»¥ä¸ºè¾“å…¥æä¾›å€¼ï¼Œå¹¶ä¸”å¯ä»¥ä»Žè¾“出ä¸" +"检索表达å¼ç»“果。" #: modules/visual_script/doc_classes/VisualScriptFunction.xml msgid "A Visual Script node representing a function." -msgstr "一个Visual Script节点,表示一个函数。" +msgstr "表示函数的 Visual Script 节点。" #: modules/visual_script/doc_classes/VisualScriptFunction.xml msgid "" @@ -79620,7 +80096,7 @@ msgstr "" #: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml msgid "A Visual Script node for calling a function." -msgstr "用于调用函数的å¯è§†åŒ–脚本节点。" +msgstr "用于调用函数的 Visual Script 节点。" #: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml msgid "" @@ -79748,7 +80224,7 @@ msgstr "该方法将被远程调用,用于给定的对ç‰ä½“ï¼Œä½¿ç”¨ä¸€ä¸ªä¸ #: modules/visual_script/doc_classes/VisualScriptFunctionState.xml msgid "A Visual Script node representing a function state." -msgstr "一个Visual Script节点,表示函数状æ€ã€‚" +msgstr "表示函数状æ€çš„ Visual Script 节点。" #: modules/visual_script/doc_classes/VisualScriptFunctionState.xml msgid "" @@ -79784,7 +80260,7 @@ msgstr "è¦ä½¿ç”¨çš„常é‡ã€‚" #: modules/visual_script/doc_classes/VisualScriptIndexGet.xml msgid "A Visual Script node for getting a value from an array or a dictionary." -msgstr "一个Visual Script节点,用于从数组或å—å…¸ä¸èŽ·å–值。" +msgstr "用于从数组或å—å…¸ä¸å–值的 Visual Script 节点。" #: modules/visual_script/doc_classes/VisualScriptIndexGet.xml msgid "" @@ -79794,7 +80270,7 @@ msgstr "[VisualScriptIndexGet]将返回å˜å‚¨åœ¨æŒ‡å®šç´¢å¼•下的数组或å—å… #: modules/visual_script/doc_classes/VisualScriptIndexSet.xml msgid "A Visual Script node for setting a value in an array or a dictionary." -msgstr "一个Visual Script节点,用于设置数组或å—å…¸ä¸çš„值。" +msgstr "ç”¨äºŽå‘æ•°ç»„或å—å…¸ä¸è®¾å€¼çš„ Visual Script 节点。" #: modules/visual_script/doc_classes/VisualScriptIndexSet.xml msgid "" @@ -79805,7 +80281,7 @@ msgstr "" #: modules/visual_script/doc_classes/VisualScriptInputAction.xml msgid "A Visual Script node returning a state of an action." -msgstr "返回动作状æ€çš„å¯è§†åŒ–脚本节点。" +msgstr "返回动作状æ€çš„ Visual Script 节点。" #: modules/visual_script/doc_classes/VisualScriptInputAction.xml msgid "" @@ -79856,17 +80332,17 @@ msgid "" msgstr "" "这个节点在给定的输入ä¸é€é¡¹è¿›è¡Œã€‚输入å¯ä»¥æ˜¯ä»»ä½•åºåˆ—æ•°æ®ç±»åž‹ï¼Œå¦‚[Array]或" "[String]。当æ¯ä¸ªé¡¹è¢«å¤„ç†å®ŒåŽï¼Œæ‰§è¡Œä¼ 出[code]exit[/code] åºåˆ—端å£ã€‚\n" -"[b]Input Ports:[/b]\n" -"- Sequence: [code]for (elem) in (input)[/code]\n" -"- Data (variant): [code]input[/code]\n" -"[b]Output Ports:[/b]\n" -"- Sequence: [code]each[/code]\n" -"- Sequence: [code]exit[/code]\n" -"- Data (variant): [code]elem[/code]" +"[b]输入端å£ï¼š[/b]\n" +"- åºåˆ—:[code]for (elem) in (input)[/code]\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]input[/code]\n" +"[b]输出端å£ï¼š[/b]\n" +"- åºåˆ—:[code]each[/code]\n" +"- åºåˆ—:[code]exit[/code]\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]elem[/code]" #: modules/visual_script/doc_classes/VisualScriptLists.xml msgid "A Visual Script virtual class for in-graph editable nodes." -msgstr "图内å¯ç¼–辑节点的å¯è§†åŒ–脚本虚拟类。" +msgstr "图内å¯ç¼–辑节点的 Visual Script 虚类。" #: modules/visual_script/doc_classes/VisualScriptLists.xml msgid "" @@ -79920,11 +80396,11 @@ msgid "" "[b]Output Ports:[/b]\n" "- Data (variant): [code]get[/code]" msgstr "" -"返回局部å˜é‡çš„值。必须æä¾› \"Var Name\",并æä¾›å¯é€‰ç±»åž‹ã€‚\n" -"[b]Input Ports:[/b]\n" -"none\n" -"[b]Output Ports:[/b]\n" -"- Data (variant): [code]get[/code]" +"返回局部å˜é‡çš„值。必须æä¾›å˜é‡å称“Var Nameâ€ï¼Œå¹¶æä¾›å¯é€‰ç±»åž‹ã€‚\n" +"[b]输入端å£ï¼š[/b]\n" +"æ— \n" +"[b]输出端å£ï¼š[/b]\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]get[/code]" #: modules/visual_script/doc_classes/VisualScriptLocalVar.xml #: modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml @@ -79952,12 +80428,12 @@ msgid "" "- Data (variant): [code]get[/code]" msgstr "" "将一个局部å˜é‡çš„值更改为给定的输入值。新的值也会在输出端æä¾›æ•°æ®ç«¯å£ã€‚\n" -"[b]Input Ports:[/b]\n" -"- Sequence\n" -"- Data (variant): [code]set[/code]\n" -"[b]Output Ports:[/b]\n" -"- Sequence\n" -"- Data (variant): [code]get[/code]" +"[b]输入端å£ï¼š[/b]\n" +"- åºåˆ—\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]set[/code]\n" +"[b]输出端å£ï¼š[/b]\n" +"- åºåˆ—\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]get[/code]" #: modules/visual_script/doc_classes/VisualScriptMathConstant.xml msgid "Commonly used mathematical constants." @@ -79971,11 +80447,11 @@ msgid "" "[b]Output Ports:[/b]\n" "- Data (variant): [code]get[/code]" msgstr "" -"在输出数æ®ç«¯å£ä¸Šæä¾›å¸¸è§çš„æ•°å¦å¸¸é‡ï¼Œå¦‚Piç‰ã€‚\n" -"[b]Input Ports:[/b]\n" -"none\n" -"[b]Output Ports:[/b]\n" -"- Data (variant): [code]get[/code]" +"在输出数æ®ç«¯å£ä¸Šæä¾› Pi ç‰å¸¸è§çš„æ•°å¦å¸¸é‡ã€‚\n" +"[b]输入端å£ï¼š[/b]\n" +"æ— \n" +"[b]输出端å£ï¼š[/b]\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]get[/code]" #: modules/visual_script/doc_classes/VisualScriptMathConstant.xml msgid "The math constant." @@ -80039,7 +80515,7 @@ msgstr "返回给定端å£çš„é»˜è®¤å€¼ã€‚å½“æ²¡æœ‰ä»»ä½•ä¸œè¥¿è¿žæŽ¥åˆ°è¯¥ç«¯å£ #: modules/visual_script/doc_classes/VisualScriptNode.xml msgid "Returns the [VisualScript] instance the node is bound to." -msgstr "返回该节点所绑定的[VisualScript]实例。" +msgstr "返回该节点所绑定的 [VisualScript] 实例。" #: modules/visual_script/doc_classes/VisualScriptNode.xml msgid "" @@ -80068,10 +80544,10 @@ msgid "" "- Data (variant): [code]result[/code]" msgstr "" "[b]输入端å£ï¼š[/b]\n" -"- æ•°æ®ï¼ˆvariant):[code]A[/code]\n" -"- æ•°æ®ï¼ˆvariant):[code]B[/code]\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]A[/code]\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]B[/code]\n" "[b]输出端å£ï¼š[/b]\n" -"- æ•°æ®ï¼ˆvariant):[code]result[/code]" +"- æ•°æ®ï¼ˆå˜ä½“):[code]result[/code]" #: modules/visual_script/doc_classes/VisualScriptOperator.xml msgid "" @@ -80097,11 +80573,11 @@ msgid "" "[b]Output Ports:[/b]\n" "- Data (object): [code]res[/code]" msgstr "" -"创建新的[Resource]æˆ–ä»Žæ–‡ä»¶ç³»ç»ŸåŠ è½½ä¸€ä¸ªã€‚\n" -"[b]Input Ports:[/b]\n" -"none\n" -"[b]Output Ports:[/b]\n" -"- Data (object): [code]res[/code]" +"创建新的 [Resource] æˆ–ä»Žæ–‡ä»¶ç³»ç»ŸåŠ è½½ã€‚\n" +"[b]输入端å£ï¼š[/b]\n" +"æ— \n" +"[b]输出端å£ï¼š[/b]\n" +"- æ•°æ®ï¼ˆå¯¹è±¡ï¼‰ï¼š[code]res[/code]" #: modules/visual_script/doc_classes/VisualScriptPreload.xml msgid "The [Resource] to load." @@ -80191,7 +80667,7 @@ msgstr "该属性将从 GDScript åŸºæœ¬ç±»åž‹ä¸æ£€ç´¢ï¼Œä¾‹å¦‚ [Vector2]。" #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml msgid "A Visual Script node that sets a property of an [Object]." -msgstr "一个Visual Script节点,用于设置[Object]的属性。" +msgstr "用于设置对象 [Object] 的属性的 Visual Script 节点。" #: modules/visual_script/doc_classes/VisualScriptPropertySet.xml msgid "" @@ -80320,15 +80796,15 @@ msgid "" msgstr "" "结æŸä¸€ä¸ªå‡½æ•°çš„æ‰§è¡Œå¹¶å°†æŽ§åˆ¶æƒè¿”回给调用函数。å¯é€‰ï¼Œå®ƒå¯ä»¥è¿”回一个[Variant]" "值。\n" -"[b]Input Ports:[/b]\n" -"- Sequence\n" -"- Data (variant): [code]result[/code] (optional)\n" -"[b]Output Ports:[/b]\n" -"none" +"[b]输入端å£ï¼š[/b]\n" +"- åºåˆ—\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]result[/code](å¯é€‰ï¼‰\n" +"[b]输出端å£ï¼š[/b]\n" +"æ— " #: modules/visual_script/doc_classes/VisualScriptReturn.xml msgid "If [code]true[/code], the [code]return[/code] input port is available." -msgstr "如果[code]true[/code],则[code]return[/code]输入端å£å¯ç”¨ã€‚" +msgstr "如果为 [code]true[/code],则 [code]return[/code] 输入端å£å¯ç”¨ã€‚" #: modules/visual_script/doc_classes/VisualScriptReturn.xml msgid "The return value's data type." @@ -80347,10 +80823,10 @@ msgid "" "- Data: [code]node[/code] (obj)" msgstr "" "对节点的直接引用。\n" -"[b]Input Ports:[/b]\n" -"none\n" -"[b]Output Ports:[/b]\n" -"- Data: [code]node[/code] (obj)" +"[b]输入端å£ï¼š[/b]\n" +"æ— \n" +"[b]输出端å£ï¼š[/b]\n" +"- æ•°æ®ï¼š[code]node[/code](obj)" #: modules/visual_script/doc_classes/VisualScriptSceneNode.xml msgid "The node's path in the scene tree." @@ -80375,12 +80851,12 @@ msgid "" "- Data (variant): [code]out[/code]" msgstr "" "æ ¹æ®ä¸€ä¸ªå¸ƒå°”æ¡ä»¶åœ¨ä¸¤ä¸ªè¾“入值之间进行选择。\n" -"[b]Input Ports:[/b]\n" +"[b]输入端å£ï¼š[/b]\n" "- Data (boolean): [code]cond[/code]\n" -"- Data (variant): [code]a[/code]\n" -"- Data (variant): [code]b[/code]\n" -"[b]Output Ports:[/b]\n" -"- Data (variant): [code]out[/code]" +"- æ•°æ®ï¼ˆå˜ä½“):[code]a[/code]\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]b[/code]\n" +"[b]输出端å£ï¼š[/b]\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]out[/code]" #: modules/visual_script/doc_classes/VisualScriptSelect.xml msgid "The input variables' type." @@ -80398,11 +80874,11 @@ msgid "" "[b]Output Ports:[/b]\n" "- Data (object): [code]instance[/code]" msgstr "" -"æä¾›å¯¹è¿è¡Œå¯è§†åŒ–脚本的节点的引用。\n" -"[b]Input Ports:[/b]\n" -"none\n" -"[b]Output Ports:[/b]\n" -"- Data (object): [code]instance[/code]" +"æä¾›å¯¹è¿è¡Œ Visual Script 的节点的引用。\n" +"[b]输入端å£ï¼š[/b]\n" +"æ— \n" +"[b]输出端å£ï¼š[/b]\n" +"- æ•°æ®ï¼ˆå¯¹è±¡ï¼‰ï¼š[code]instance[/code]" #: modules/visual_script/doc_classes/VisualScriptSequence.xml msgid "Executes a series of Sequence ports." @@ -80421,11 +80897,11 @@ msgid "" msgstr "" "通过一系列的一个或多个输出åºåˆ—端å£è¿›è¡Œæ¥è¿›ã€‚[code]current[/code]当剿•°æ®ç«¯å£" "è¾“å‡ºå½“å‰æ‰§è¡Œçš„项。\n" -"[b]Input Ports:[/b]\n" -"- Sequence: [code]in order[/code]\n" -"[b]Output Ports:[/b]\n" -"- Sequence: [code]1[/code]\n" -"- Sequence: [code]2 - n[/code] (optional)\n" +"[b]输入端å£ï¼š[/b]\n" +"- åºåˆ—:[code]in order[/code]\n" +"[b]输出端å£ï¼š[/b]\n" +"- åºåˆ—:[code]1[/code]\n" +"- åºåˆ—:[code]2 - n[/code] (optional)\n" "- Data (int): [code]current[/code]" #: modules/visual_script/doc_classes/VisualScriptSequence.xml @@ -80470,19 +80946,19 @@ msgid "" msgstr "" "æ ¹æ®è¾“入值æ¥åˆ†æ”¯æµç¨‹ã€‚在属性检查器ä¸ä½¿ç”¨[b]Case Count[/b]æ¥è®¾ç½®åˆ†æ”¯çš„æ•°é‡å’Œæ¯" "个比较的å¯é€‰ç±»åž‹ã€‚\n" -"[b]Input Ports:[/b]\n" -"- Sequence: [code]'input' is[/code]\n" -"- Data (variant): [code]=[/code]\n" -"- Data (variant): [code]=[/code] (optional)\n" -"- Data (variant): [code]input[/code]\n" -"[b]Output Ports:[/b]\n" -"- Sequence\n" -"- Sequence (optional)\n" -"- Sequence: [code]done[/code]" +"[b]输入端å£ï¼š[/b]\n" +"- åºåˆ—:[code]'input' is[/code]\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]=[/code]\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]=[/code](å¯é€‰ï¼‰\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]input[/code]\n" +"[b]输出端å£ï¼š[/b]\n" +"- åºåˆ—\n" +"- åºåˆ—(å¯é€‰ï¼‰\n" +"- åºåˆ—:[code]done[/code]" #: modules/visual_script/doc_classes/VisualScriptTypeCast.xml msgid "A Visual Script node that casts the given value to another type." -msgstr "一个Visual Script节点,将给定的值转æ¢ä¸ºå¦ä¸€ç§ç±»åž‹ã€‚" +msgstr "将给定的值转æ¢ä¸ºå¦ä¸€ç§ç±»åž‹çš„ Visual Script 节点。" #: modules/visual_script/doc_classes/VisualScriptTypeCast.xml msgid "" @@ -80513,11 +80989,11 @@ msgid "" "[b]Output Ports:[/b]\n" "- Data (variant): [code]value[/code]" msgstr "" -"返回å˜é‡çš„值。必须æä¾› \"Var Name\",并有一个å¯é€‰çš„类型。\n" -"[b]Input Ports:[/b]\n" -"none\n" -"[b]Output Ports:[/b]\n" -"- Data (variant): [code]value[/code]" +"返回å˜é‡çš„值。必须æä¾›å˜é‡å称“Var Nameâ€ï¼Œå¹¶æœ‰ä¸€ä¸ªå¯é€‰çš„类型。\n" +"[b]输入端å£ï¼š[/b]\n" +"æ— \n" +"[b]输出端å£ï¼š[/b]\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]value[/code]" #: modules/visual_script/doc_classes/VisualScriptVariableGet.xml #: modules/visual_script/doc_classes/VisualScriptVariableSet.xml @@ -80538,11 +81014,11 @@ msgid "" "- Sequence" msgstr "" "å°†å˜é‡çš„值更改为给定的输入。\n" -"[b]Input Ports:[/b]\n" -"- Sequence\n" -"- Data (variant): [code]set[/code]\n" -"[b]Output Ports:[/b]\n" -"- Sequence" +"[b]输入端å£ï¼š[/b]\n" +"- åºåˆ—\n" +"- æ•°æ®ï¼ˆå˜ä½“):[code]set[/code]\n" +"[b]输出端å£ï¼š[/b]\n" +"- åºåˆ—" #: modules/visual_script/doc_classes/VisualScriptWhile.xml msgid "Conditional loop." @@ -80561,12 +81037,12 @@ msgid "" msgstr "" "当一个æ¡ä»¶ä¸º[code]true[/code]æ—¶è¿›è¡Œå¾ªçŽ¯ã€‚å½“å¾ªçŽ¯ç»“æŸæ—¶ï¼Œæ‰§è¡Œç»§ç»ä»Ž[code]exit[/" "code]åºåˆ—端å£å‡ºæ¥ã€‚\n" -"[b]Input Ports:[/b]\n" -"- Sequence: [code]while(cond)[/code]\n" +"[b]输入端å£ï¼š[/b]\n" +"- åºåˆ—:[code]while(cond)[/code]\n" "- Data (bool): [code]cond[/code]\n" -"[b]Output Ports:[/b]\n" -"- Sequence: [code]repeat[/code]\n" -"- Sequence: [code]exit[/code]" +"[b]输出端å£ï¼š[/b]\n" +"- åºåˆ—:[code]repeat[/code]\n" +"- åºåˆ—:[code]exit[/code]" #: modules/visual_script/doc_classes/VisualScriptYield.xml msgid "A Visual Script node used to pause a function execution." @@ -83189,7 +83665,7 @@ msgstr "设置应更新视窗的时间。请å‚阅 [enum ViewportUpdateMode] 。 msgid "" "Sets the viewport's 2D/3D mode. See [enum ViewportUsage] constants for " "options." -msgstr "设置视窗的2D/3D模å¼ã€‚选项è§[enum ViewportUsage]视窗使用常数。" +msgstr "设置视窗的 2D/3D 模å¼ã€‚é€‰é¡¹è§ [enum ViewportUsage] 常é‡ã€‚" #: doc/classes/VisualServer.xml msgid "" @@ -83346,39 +83822,39 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "Shader is a 3D shader." -msgstr "ç€è‰²å™¨æ˜¯ä¸€ä¸ª 3D ç€è‰²å™¨ã€‚" +msgstr "ç€è‰²å™¨æ˜¯ 3D ç€è‰²å™¨ã€‚" #: doc/classes/VisualServer.xml msgid "Shader is a 2D shader." -msgstr "ç€è‰²å™¨æ˜¯ä¸€ä¸ª 2D ç€è‰²å™¨ã€‚" +msgstr "ç€è‰²å™¨æ˜¯ 2D ç€è‰²å™¨ã€‚" #: doc/classes/VisualServer.xml msgid "Shader is a particle shader." -msgstr "ç€è‰²å™¨æ˜¯ä¸€ä¸ªç²’åç€è‰²å™¨ã€‚" +msgstr "ç€è‰²å™¨æ˜¯ç²’åç€è‰²å™¨ã€‚" #: doc/classes/VisualServer.xml msgid "Represents the size of the [enum ShaderMode] enum." -msgstr "代表[enum ShaderMode]枚举的大å°ã€‚" +msgstr "代表 [enum ShaderMode] 枚举的大å°ã€‚" #: doc/classes/VisualServer.xml msgid "Array is a vertex array." -msgstr "数组是一个顶点数组。" +msgstr "数组是顶点数组。" #: doc/classes/VisualServer.xml msgid "Array is a normal array." -msgstr "数组是普通数组。" +msgstr "数组是法线数组。" #: doc/classes/VisualServer.xml msgid "Array is a tangent array." -msgstr "数组是一个切线数组。" +msgstr "数组是切线数组。" #: doc/classes/VisualServer.xml msgid "Array is a color array." -msgstr "数组是一个颜色数组。" +msgstr "数组是颜色数组。" #: doc/classes/VisualServer.xml msgid "Array is an UV coordinates array." -msgstr "数组是一个 UV åæ ‡æ•°ç»„。" +msgstr "数组是 UV åæ ‡æ•°ç»„。" #: doc/classes/VisualServer.xml msgid "Array is an UV coordinates array for the second UV coordinates." @@ -83402,7 +83878,7 @@ msgstr "ç”¨äºŽæ ‡è®°é¡¶ç‚¹æ•°ç»„çš„æ ‡å¿—ã€‚" #: doc/classes/VisualServer.xml msgid "Flag used to mark a normal array." -msgstr "ç”¨äºŽæ ‡è®°æ£å¸¸æ•°ç»„çš„æ ‡å¿—ã€‚" +msgstr "ç”¨äºŽæ ‡è®°æ³•çº¿æ•°ç»„çš„æ ‡å¿—ã€‚" #: doc/classes/VisualServer.xml msgid "Flag used to mark a tangent array." @@ -84338,9 +84814,8 @@ msgstr "在ç€è‰²å™¨è¯è¨€ä¸è¢«è½¬æ¢æˆ[code]uniform bool[/code]。" #: doc/classes/VisualShaderNodeScalarUniform.xml #: doc/classes/VisualShaderNodeTransformUniform.xml #: doc/classes/VisualShaderNodeVec3Uniform.xml -#, fuzzy msgid "A default value to be assigned within the shader." -msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸ä½¿ç”¨çš„è²æ¶…尔效果。" +msgstr "该ç€è‰²å™¨å†…部分é…的默认值。" #: doc/classes/VisualShaderNodeBooleanUniform.xml #: doc/classes/VisualShaderNodeColorUniform.xml @@ -84348,7 +84823,7 @@ msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸ä½¿ç”¨çš„è²æ¶…尔效果。" #: doc/classes/VisualShaderNodeTransformUniform.xml #: doc/classes/VisualShaderNodeVec3Uniform.xml msgid "Enables usage of the [member default_value]." -msgstr "" +msgstr "å¯ç”¨ [member default_value]。" #: doc/classes/VisualShaderNodeColorConstant.xml msgid "A [Color] constant to be used within the visual shader graph." @@ -84788,7 +85263,7 @@ msgid "" "Virtual class to define custom [VisualShaderNode]s for use in the Visual " "Shader Editor." msgstr "" -"用于定义自定义[VisualShaderNode]的虚拟类,以便在å¯è§†åŒ–ç€è‰²å™¨ç¼–辑器ä¸ä½¿ç”¨ã€‚" +"用于定义自定义 [VisualShaderNode] 的虚类,以便在å¯è§†åŒ–ç€è‰²å™¨ç¼–辑器ä¸ä½¿ç”¨ã€‚" #: doc/classes/VisualShaderNodeCustom.xml msgid "" @@ -85394,29 +85869,35 @@ msgstr "" msgid "" "A hint applied to the uniform, which controls the values it can take when " "set through the inspector." -msgstr "" +msgstr "对 uniform 应用的æç¤ºï¼ŒæŽ§åˆ¶é€šè¿‡æ£€æŸ¥å™¨æ‰€èƒ½è®¾ç½®çš„值。" #: doc/classes/VisualShaderNodeScalarUniform.xml msgid "" "Minimum value for range hints. Used if [member hint] is set to [constant " "HINT_RANGE] or [constant HINT_RANGE_STEP]." msgstr "" +"范围æç¤ºçš„æœ€å°å€¼ã€‚会在 [member hint] 为 [constant HINT_RANGE] 或 [constant " +"HINT_RANGE_STEP] 时使用。" #: doc/classes/VisualShaderNodeScalarUniform.xml msgid "" "Maximum value for range hints. Used if [member hint] is set to [constant " "HINT_RANGE] or [constant HINT_RANGE_STEP]." msgstr "" +"范围æç¤ºçš„æœ€å¤§å€¼ã€‚会在 [member hint] 为 [constant HINT_RANGE] 或 [constant " +"HINT_RANGE_STEP] 时使用。" #: doc/classes/VisualShaderNodeScalarUniform.xml msgid "" "Step (increment) value for the range hint with step. Used if [member hint] " "is set to [constant HINT_RANGE_STEP]." msgstr "" +"带æ¥é•¿ï¼ˆå¢žé‡ï¼‰çš„范围æç¤ºçš„æ¥é•¿å€¼ã€‚ä¼šåœ¨ [member hint] 为 [constant " +"HINT_RANGE_STEP] 时使用。" #: doc/classes/VisualShaderNodeScalarUniform.xml msgid "No hint used." -msgstr "" +msgstr "ä¸ä½¿ç”¨æç¤ºã€‚" #: doc/classes/VisualShaderNodeScalarUniform.xml msgid "" @@ -85424,6 +85905,8 @@ msgid "" "[member min] and [member max]. Translated to [code]hint_range(min, max)[/" "code] in shader code." msgstr "" +"æ ‡é‡å€¼çš„范围æç¤ºï¼Œä¼šå°†å¯èƒ½çš„输入é™åˆ¶åœ¨ [member min] å’Œ [member max] 之间。会" +"被翻译为ç€è‰²å™¨ä»£ç ä¸çš„ [code]hint_range(min, max)[/code]。" #: doc/classes/VisualShaderNodeScalarUniform.xml msgid "" @@ -85431,11 +85914,13 @@ msgid "" "between [member min] and [member max], with a step (increment) of [member " "step]). Translated to [code]hint_range(min, max, step)[/code] in shader code." msgstr "" +"æ ‡é‡å€¼çš„范围æç¤ºï¼Œå¸¦æ¥é•¿ï¼Œä¼šå°†å¯èƒ½çš„输入é™åˆ¶åœ¨ [member min] å’Œ [member max] " +"之间,æ¥é•¿ï¼ˆå¢žé‡ï¼‰ä¸º [member step]。会被翻译为ç€è‰²å™¨ä»£ç ä¸çš„ " +"[code]hint_range(min, max, step)[/code]。" #: doc/classes/VisualShaderNodeScalarUniform.xml -#, fuzzy msgid "Represents the size of the [enum Hint] enum." -msgstr "表示[enum Monitor] enum的大å°ã€‚" +msgstr "表示 [enum Hint] 枚举的大å°ã€‚" #: doc/classes/VisualShaderNodeSwitch.xml msgid "A boolean/vector function for use within the visual shader graph." @@ -86036,7 +86521,7 @@ msgid "" "Returns the vector that points in the direction of reflection. [code]a[/" "code] is incident vector and [code]b[/code] is the normal vector." msgstr "" -"返回指å‘åå°„æ–¹å‘çš„å‘é‡ã€‚[code]a[/code]是入射å‘é‡ï¼Œ[code]b[/code]是法å‘é‡ã€‚" +"返回指å‘åå°„æ–¹å‘çš„å‘é‡ã€‚[code]a[/code] 是入射å‘é‡ï¼Œ[code]b[/code] 是法å‘é‡ã€‚" #: doc/classes/VisualShaderNodeVectorOp.xml msgid "" diff --git a/doc/translations/zh_TW.po b/doc/translations/zh_TW.po index 3db6f2c82d..b07e7c7cc7 100644 --- a/doc/translations/zh_TW.po +++ b/doc/translations/zh_TW.po @@ -2850,7 +2850,12 @@ msgid "Gamepad button 22." msgstr "" #: doc/classes/@GlobalScope.xml -msgid "Represents the maximum number of joystick buttons supported." +msgid "" +"The maximum number of game controller buttons supported by the engine. The " +"actual limit may be lower on specific platforms:\n" +"- Android: Up to 36 buttons.\n" +"- Linux: Up to 80 buttons.\n" +"- Windows and macOS: Up to 128 buttons." msgstr "" #: doc/classes/@GlobalScope.xml @@ -3844,8 +3849,6 @@ msgid "" "typically used for fast overlap tests.\n" "It uses floating-point coordinates. The 2D counterpart to [AABB] is " "[Rect2].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get an AABB with a positive size.\n" "[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses " "integer coordinates." msgstr "" @@ -9449,15 +9452,17 @@ msgid "Represents the size of the [enum FFT_Size] enum." msgstr "" #: doc/classes/AudioEffectRecord.xml -msgid "Audio effect used for recording sound from a microphone." +msgid "Audio effect used for recording the sound from an audio bus." msgstr "" #: doc/classes/AudioEffectRecord.xml msgid "" -"Allows the user to record sound from a microphone. It sets and gets the " -"format in which the audio file will be recorded (8-bit, 16-bit, or " -"compressed). It checks whether or not the recording is active, and if it is, " -"records the sound. It then returns the recorded sample." +"Allows the user to record the sound from an audio bus. This can include all " +"audio output by Godot when used on the \"Master\" audio bus.\n" +"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n" +"It sets and gets the format in which the audio file will be recorded (8-bit, " +"16-bit, or compressed). It checks whether or not the recording is active, " +"and if it is, records the sound. It then returns the recorded sample." msgstr "" #: doc/classes/AudioEffectRecord.xml @@ -15572,9 +15577,8 @@ msgstr "" msgid "" "Creates a local override for a theme [Color] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_color].\n" +"the control.\n" +"See also [method get_color], [method remove_color_override].\n" "[b]Example of overriding a label's color and resetting it later:[/b]\n" "[codeblock]\n" "# Given the child Label node \"MyLabel\", override its font color with a " @@ -15590,17 +15594,18 @@ msgstr "" msgid "" "Creates a local override for a theme constant with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override cannot be removed, but it can be overridden with " -"the corresponding default value.\n" -"See also [method get_constant]." +"the control.\n" +"See also [method get_constant], [method remove_constant_override]." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [Font] with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_font_override] instead.\n" "See also [method get_font]." msgstr "" @@ -15608,8 +15613,10 @@ msgstr "" msgid "" "Creates a local override for a theme icon with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value.\n" +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_icon_override] instead.\n" "See also [method get_icon]." msgstr "" @@ -15617,16 +15624,20 @@ msgstr "" msgid "" "Creates a local override for a theme shader with the specified [code]name[/" "code]. Local overrides always take precedence when fetching theme items for " -"the control. An override can be removed by assigning it a [code]null[/code] " -"value." +"the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_shader_override] instead." msgstr "" #: doc/classes/Control.xml msgid "" "Creates a local override for a theme [StyleBox] with the specified " "[code]name[/code]. Local overrides always take precedence when fetching " -"theme items for the control. An override can be removed by assigning it a " -"[code]null[/code] value.\n" +"theme items for the control.\n" +"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] " +"value. This behavior is deprecated and will be removed in 4.0, use [method " +"remove_stylebox_override] instead.\n" "See also [method get_stylebox].\n" "[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n" "[codeblock]\n" @@ -15985,6 +15996,39 @@ msgid "" msgstr "" #: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [Color] with the given [code]name[/code]." +msgstr "計算兩個å‘é‡çš„外ç©ã€‚" + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a constant with the given [code]name[/code]." +msgstr "計算兩個å‘é‡çš„外ç©ã€‚" + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a [Font] with the given [code]name[/code]." +msgstr "計算兩個å‘é‡çš„外ç©ã€‚" + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for an icon with the given [code]name[/code]." +msgstr "計算兩個å‘é‡çš„外ç©ã€‚" + +#: doc/classes/Control.xml +#, fuzzy +msgid "Removes a theme override for a shader with the given [code]name[/code]." +msgstr "計算兩個å‘é‡çš„外ç©ã€‚" + +#: doc/classes/Control.xml +#, fuzzy +msgid "" +"Removes a theme override for a [StyleBox] with the given [code]name[/code]." +msgstr "計算兩個å‘é‡çš„外ç©ã€‚" + +#: doc/classes/Control.xml msgid "" "Sets the anchor identified by [code]margin[/code] constant from [enum " "Margin] enum to value [code]anchor[/code]. A setter method for [member " @@ -16471,7 +16515,15 @@ msgid "" "its [member mouse_filter] lets the event reach it.\n" "[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a " "child [Control] node, even if the mouse cursor is still inside the parent's " -"[code]Rect[/code] area." +"[code]Rect[/code] area.\n" +"If you want to check whether the mouse truly left the area, ignoring any top " +"nodes, you can use code like this:\n" +"[codeblock]\n" +"func _on_mouse_exited():\n" +" if not Rect2(Vector2(), rect_size)." +"has_point(get_local_mouse_position()):\n" +" # Not hovering over area.\n" +"[/codeblock]" msgstr "" #: doc/classes/Control.xml @@ -22259,111 +22311,247 @@ msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Version Control System (VCS) interface which reads and writes to the local " +"Version Control System (VCS) interface, which reads and writes to the local " "VCS in use." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Used by the editor to display VCS extracted information in the editor. The " -"implementation of this API is included in VCS addons, which are essentially " -"GDNative plugins that need to be put into the project folder. These VCS " -"addons are scripts which are attached (on demand) to the object instance of " -"[code]EditorVCSInterface[/code]. All the functions listed below, instead of " -"performing the task themselves, they call the internally defined functions " -"in the VCS addons to provide a plug-n-play experience." +"Defines the API that the editor uses to extract information from the " +"underlying VCS. The implementation of this API is included in VCS plugins, " +"which are scripts that inherit [EditorVCSInterface] and are attached (on " +"demand) to the singleton instance of [EditorVCSInterface]. Instead of " +"performing the task themselves, all the virtual functions listed below are " +"calling the internally overridden functions in the VCS plugins to provide a " +"plug-n-play experience. A custom VCS plugin is supposed to inherit from " +"[EditorVCSInterface] and override these virtual functions." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Checks out a [code]branch_name[/code] in the VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Commits the currently staged changes and applies the commit [code]msg[/code] " +"to the resulting commit." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Creates a new branch named [code]branch_name[/code] in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Creates a version commit if the addon is initialized, else returns without " -"doing anything. Uses the files which have been staged previously, with the " -"commit message set to a value as provided as in the argument." +"Creates a new remote destination with name [code]remote_name[/code] and " +"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an " +"SSH remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Discards the changes made in file present at [code]file_path[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns an [Array] of [Dictionary] objects containing the diff output from " -"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] " -"object. The diff contents also consist of some contextual lines which " -"provide context to the observed line change in the file.\n" -"Each [Dictionary] object has the line diff contents under the keys:\n" -"- [code]\"content\"[/code] to store a [String] containing the line contents\n" -"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/" -"code] in case the content is a line addition but it stores a [code]\"-\"[/" -"code] in case of deletion and an empty string in the case the line content " -"is neither an addition nor a deletion.\n" -"- [code]\"new_line_number\"[/code] to store an integer containing the new " -"line number of the line content.\n" -"- [code]\"line_count\"[/code] to store an integer containing the number of " -"lines in the line content.\n" -"- [code]\"old_line_number\"[/code] to store an integer containing the old " -"line number of the line content.\n" -"- [code]\"offset\"[/code] to store the offset of the line change since the " -"first contextual line content." +"Fetches new changes from the remote, but doesn't write changes to the " +"current working directory. Equivalent to [code]git fetch[/code]." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns a [Dictionary] containing the path of the detected file change " -"mapped to an integer signifying what kind of change the corresponding file " -"has experienced.\n" -"The following integer values are being used to signify that the detected " -"file is:\n" -"- [code]0[/code]: New to the VCS working directory\n" -"- [code]1[/code]: Modified\n" -"- [code]2[/code]: Renamed\n" -"- [code]3[/code]: Deleted\n" -"- [code]4[/code]: Typechanged" +"Gets an instance of an [Array] of [String]s containing available branch " +"names in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml -msgid "Returns the project name of the VCS working directory." +msgid "Gets the current branch name defined in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns the name of the VCS if the VCS has been initialized, else return an " -"empty string." +"Returns an [Array] of [Dictionary] items (see [method create_diff_file], " +"[method create_diff_hunk], [method create_diff_line], [method " +"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), " +"each containing information about a diff. If [code]identifier[/code] is a " +"file path, returns a file diff, and if it is a commit identifier, then " +"returns a commit diff." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Initializes the VCS addon if not already. Uses the argument value as the " -"path to the working directory of the project. Creates the initial commit if " -"required. Returns [code]true[/code] if no failure occurs, else returns " -"[code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), " +"each containing a line diff between a file at [code]file_path[/code] and the " +"[code]text[/code] which is passed in." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the addon is ready to respond to function " -"calls, else returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_status_file]), " +"each containing the status data of every modified file in the project folder." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Returns [code]true[/code] if the VCS addon has been initialized, else " -"returns [code]false[/code]." +"Returns an [Array] of [Dictionary] items (see [method create_commit]), each " +"containing the data for a past commit." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Shuts down the VCS addon to allow cleanup code to run on call. Returns " -"[code]true[/code] is no failure occurs, else returns [code]false[/code]." +"Returns an [Array] of [String]s, each containing the name of a remote " +"configured in the VCS." msgstr "" #: doc/classes/EditorVCSInterface.xml +#, fuzzy +msgid "Returns the name of the underlying VCS provider." +msgstr "å›žå‚³åƒæ•¸çš„æ£å¼¦å€¼ã€‚" + +#: doc/classes/EditorVCSInterface.xml msgid "" -"Stages the file which should be committed when [method EditorVCSInterface." -"commit] is called. Argument should contain the absolute path." +"Initializes the VCS plugin when called from the editor. Returns whether or " +"not the plugin was successfully initialized. A VCS project is initialized at " +"[code]project_path[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pulls changes from the remote. This can give rise to merge conflicts." msgstr "" #: doc/classes/EditorVCSInterface.xml msgid "" -"Unstages the file which was staged previously to be committed, so that it is " -"no longer committed when [method EditorVCSInterface.commit] is called. " -"Argument should contain the absolute path." +"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] " +"is set to true, a force push will override the change history already " +"present on the remote." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a branch from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Remove a remote from the local VCS." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Set user credentials in the underlying VCS. [code]username[/code] and " +"[code]password[/code] are used only during HTTPS authentication unless not " +"already mentioned in the remote URL. [code]ssh_public_key_path[/code], " +"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only " +"used during SSH authentication." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Shuts down VCS plugin instance. Called when the user either closes the " +"editor or shuts down the VCS plugin through the editor UI." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Stages the file present at [code]file_path[/code] to the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Unstages the file present at [code]file_path[/code] from the staged area to " +"the unstaged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]diff_hunks[/code] into a " +"[code]diff_file[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to add an array of [code]line_diffs[/code] into a " +"[code]diff_hunk[/code]." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a commit [Dictionary] item. [code]msg[/code] is " +"the commit message of the commit. [code]author[/code] is a human-readable " +"string containing the author's details, e.g. the email and name configured " +"in the VCS. [code]id[/code] is the identifier of the commit, in whichever " +"format your VCS may provide an identifier to commits. [code]date[/code] is " +"directly added to the commit item and displayed in the editor, and hence, it " +"shall be a well-formatted, human-readable date string." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing old and new " +"diff file paths." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing diff hunk " +"data. [code]old_start[/code] is the starting line number in old file. " +"[code]new_start[/code] is the starting line number in new file. " +"[code]old_lines[/code] is the number of lines in the old file. " +"[code]new_lines[/code] is the number of lines in the new file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] for storing a line diff. " +"[code]new_line_no[/code] is the line number in the new file (can be " +"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the " +"line number in the old file (can be [code]-1[/code] if the line is added). " +"[code]content[/code] is the diff text. [code]content[/code] is the diff " +"text. [code]status[/code] is a single character string which stores the line " +"origin." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "" +"Helper function to create a [code]Dictionary[/code] used by editor to read " +"the status of a file." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "Pops up an error message in the edior." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A new file has been added." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been modified." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been renamed." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been deleted." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "An earlier added file has been typechanged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is left unmerged." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A commit is encountered from the commit area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the staged area." +msgstr "" + +#: doc/classes/EditorVCSInterface.xml +msgid "A file is encountered from the unstaged area." msgstr "" #: doc/classes/EncodedObjectAsID.xml @@ -23810,9 +23998,14 @@ msgstr "" #: doc/classes/FileDialog.xml msgid "" -"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be " -"of the form [code]\"filename.extension ; Description\"[/code]. For example, " -"[code]\"*.png ; PNG Images\"[/code]." +"Adds [code]filter[/code] to the list of filters, which restricts what files " +"can be picked.\n" +"A [code]filter[/code] should be of the form [code]\"filename.extension ; " +"Description\"[/code], where filename and extension can be [code]*[/code] to " +"match any string. Filters starting with [code].[/code] (i.e. empty " +"filenames) are not allowed.\n" +"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project." +"godot ; Godot Project\"[/code]." msgstr "" #: doc/classes/FileDialog.xml @@ -23869,7 +24062,9 @@ msgstr "" msgid "" "The available file type filters. For example, this shows only [code].png[/" "code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*." -"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]." +"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types " +"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; " +"Supported Images\"[/code] will show both PNG and JPEG files when selected." msgstr "" #: doc/classes/FileDialog.xml @@ -25599,6 +25794,95 @@ msgstr "" msgid "The number of color samples that will be obtained from the [Gradient]." msgstr "" +#: doc/classes/GradientTexture2D.xml +msgid "Gradient-filled 2D texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture uses a [Gradient] to fill the texture data in 2D space. The " +"gradient is filled according to the specified [member fill] and [member " +"repeat] types using colors obtained from the gradient. The texture does not " +"necessarily represent an exact copy of the gradient, but instead an " +"interpolation of samples obtained from the gradient at fixed steps (see " +"[member width] and [member height])." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill type, one of the [enum Fill] values. The texture is filled " +"by interpolating colors starting from [member fill_from] to [member fill_to] " +"offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The initial offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The final offset used to fill the texture specified in UV coordinates." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +#, fuzzy +msgid "The [Gradient] used to fill the texture." +msgstr "å›žå‚³åƒæ•¸çš„æ£å¼¦å€¼ã€‚" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of vertical color samples that will be obtained from the " +"[Gradient], which also represents the texture's height." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient repeat type, one of the [enum Repeat] values. The texture is " +"filled starting from [member fill_from] to [member fill_to] offsets by " +"default, but the gradient fill can be repeated to cover the entire texture." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"If [code]true[/code], the generated texture will support high dynamic range " +"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work " +"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/" +"code], the generated texture will use low dynamic range; overbright colors " +"will be clamped ([constant Image.FORMAT_RGBA8] format)." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The number of horizontal color samples that will be obtained from the " +"[Gradient], which also represents the texture's width." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a straight line." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "The colors are linearly interpolated in a circular pattern." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The gradient fill is restricted to the range defined by [member fill_from] " +"to [member fill_to] offsets." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, repeating the same pattern in both directions." +msgstr "" + +#: doc/classes/GradientTexture2D.xml +msgid "" +"The texture is filled starting from [member fill_from] to [member fill_to] " +"offsets, mirroring the pattern in both directions." +msgstr "" + #: doc/classes/GraphEdit.xml msgid "" "GraphEdit is an area capable of showing various GraphNodes. It manages " @@ -29615,7 +29899,7 @@ msgstr "" #: doc/classes/InputEventMIDI.xml msgid "" "Returns a value indicating the type of message for this MIDI signal. This is " -"a member of the MidiMessageList enum.\n" +"a member of the [enum @GlobalScope.MidiMessageList] enum.\n" "For MIDI messages between 0x80 and 0xEF, only the left half of the bits are " "returned as this value, as the other part is the channel (ex: 0x94 becomes " "0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n" @@ -33512,7 +33796,7 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns specified edge associated with given face.\n" -"Edge argument must 2 or less because a face only has three edges." +"Edge argument must be either 0, 1, or 2 because a face only has three edges." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33526,7 +33810,8 @@ msgstr "" #: doc/classes/MeshDataTool.xml msgid "" "Returns the specified vertex of the given face.\n" -"Vertex argument must be 2 or less because faces contain three vertices." +"Vertex argument must be either 0, 1, or 2 because faces contain three " +"vertices." msgstr "" #: doc/classes/MeshDataTool.xml @@ -33750,7 +34035,7 @@ msgstr "" #: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml msgid "" "The normal map that will be used if using the default [CanvasItemMaterial].\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -34740,7 +35025,7 @@ msgid "" "set_target_location] in order for this to be accurate." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Returns the reachable final location in global coordinates. This can change " "if the navigation path is altered in any way. Because of this, it would be " @@ -34809,9 +35094,9 @@ msgid "" "path." msgstr "" -#: doc/classes/NavigationAgent.xml +#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" -"Sends the given velocity to the collision avoidance algorithm. It will " +"Sends the passed in velocity to the collision avoidance algorithm. It will " "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" @@ -34902,12 +35187,6 @@ msgid "" msgstr "" #: doc/classes/NavigationAgent2D.xml -msgid "" -"Returns the reachable final location in global coordinates. This can change " -"if the navigation path is altered in any way." -msgstr "" - -#: doc/classes/NavigationAgent2D.xml #, fuzzy msgid "" "Returns which index the agent is currently on in the navigation path's " @@ -34933,13 +35212,6 @@ msgid "" "to make the agent a child of a [Navigation2D] node." msgstr "" -#: doc/classes/NavigationAgent2D.xml -msgid "" -"Sends the passed in velocity to the collision avoidance algorithm. It will " -"adjust the velocity to avoid collisions. Once the adjustment to the velocity " -"is complete, it will emit the [signal velocity_computed] signal." -msgstr "" - #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." msgstr "" @@ -35289,7 +35561,7 @@ msgid "" "2D obstacle used in navigation for collision avoidance. The obstacle needs " "navigation data to work correctly. This can be done by having the obstacle " "as a child of a [Navigation2D] node, or using [method set_navigation]. " -"[NavigationObstacle] is physics safe." +"[NavigationObstacle2D] is physics safe." msgstr "" #: doc/classes/NavigationObstacle2D.xml @@ -38442,6 +38714,9 @@ msgid "" "If [code]blocking[/code] is [code]false[/code], the Godot thread will " "continue while the new process runs. It is not possible to retrieve the " "shell output in non-blocking mode, so [code]output[/code] will be empty.\n" +"On Windows, if [code]open_console[/code] is [code]true[/code] and process is " +"console app, new terminal window will be opened, it's ignored on other " +"platforms.\n" "The return value also depends on the blocking mode. When blocking, the " "method will return an exit code of the process. When non-blocking, the " "method returns a process ID, which you can use to monitor the process (and " @@ -40191,6 +40466,10 @@ msgid "" "to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choosing [b]Convert to " "CPUParticles[/b].\n" +"[b]Note:[/b] On macOS, [Particles] rendering is much slower than " +"[CPUParticles] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 3D editor viewport then choose [b]Generate Visibility " @@ -40311,6 +40590,10 @@ msgid "" "[Particles2D] to [CPUParticles2D] by selecting the node, clicking the " "[b]Particles[/b] menu at the top of the 2D editor viewport then choosing " "[b]Convert to CPUParticles2D[/b].\n" +"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than " +"[CPUParticles2D] due to transform feedback being implemented on the CPU " +"instead of the GPU. Consider using [CPUParticles2D] instead when targeting " +"macOS.\n" "[b]Note:[/b] After working on a Particles node, remember to update its " "[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu " "at the top of the 2D editor viewport then choose [b]Generate Visibility " @@ -44778,7 +45061,9 @@ msgid "" "[b]Example:[/b]\n" "[codeblock]\n" "ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n" -"[/codeblock]" +"[/codeblock]\n" +"This can also be used to erase custom project settings. To do this change " +"the setting value to [code]null[/code]." msgstr "" #: doc/classes/ProjectSettings.xml @@ -45541,6 +45826,18 @@ msgstr "" #: doc/classes/ProjectSettings.xml msgid "" +"Load the previously opened VCS plugin when the editor starts up. This is set " +"to [code]true[/code] whenever a new VCS plugin is initialized." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" +"Last loaded VCS plugin name. Used to autoload the plugin when the editor " +"starts up." +msgstr "" + +#: doc/classes/ProjectSettings.xml +msgid "" "Default value for [member ScrollContainer.scroll_deadzone], which will be " "used for all [ScrollContainer]s unless overridden." msgstr "" @@ -48139,9 +48436,7 @@ msgid "" "[Rect2] consists of a position, a size, and several utility functions. It is " "typically used for fast overlap tests.\n" "It uses floating-point coordinates.\n" -"The 3D counterpart to [Rect2] is [AABB].\n" -"Negative values for [member size] are not supported and will not work for " -"most methods. Use [method abs] to get a Rect2 with a positive size." +"The 3D counterpart to [Rect2] is [AABB]." msgstr "" #: doc/classes/Rect2.xml @@ -51487,6 +51782,12 @@ msgstr "" #: doc/classes/ScriptEditor.xml msgid "" +"Reload all currently opened scripts from disk in case the file contents are " +"newer." +msgstr "" + +#: doc/classes/ScriptEditor.xml +msgid "" "Emitted when user changed active script. Argument is a freshly activated " "[Script]." msgstr "" @@ -52254,6 +52555,16 @@ msgid "" "values." msgstr "" +#: doc/classes/Slider.xml +msgid "" +"Emitted when dragging stops. If [code]value_changed[/code] is true, [member " +"Range.value] is different from the value when you started the dragging." +msgstr "" + +#: doc/classes/Slider.xml +msgid "Emitted when dragging is started." +msgstr "" + #: doc/classes/SliderJoint.xml msgid "Slider between two PhysicsBodies in 3D." msgstr "" @@ -52960,7 +53271,7 @@ msgstr "" #: doc/classes/SpatialMaterial.xml msgid "" "Texture that specifies the per-pixel normal of the detail overlay.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -53158,7 +53469,7 @@ msgid "" "you can use [method SurfaceTool.generate_normals] and [method SurfaceTool." "generate_tangents] to automatically generate normals and tangents " "respectively.\n" -"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. " +"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. " "See [url=http://wiki.polycount.com/wiki/" "Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for " "a comparison of normal map coordinates expected by popular engines." @@ -54293,13 +54604,13 @@ msgid "Represents the size of the [enum DrawFlags] enum." msgstr "" #: doc/classes/SpriteFrames.xml -msgid "Sprite frame library for AnimatedSprite." +msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D." msgstr "" #: doc/classes/SpriteFrames.xml msgid "" -"Sprite frame library for [AnimatedSprite]. Contains frames and animation " -"data for playback.\n" +"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. " +"Contains frames and animation data for playback.\n" "[b]Note:[/b] You can associate a set of normal maps by creating additional " "[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, " "having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/" @@ -60764,7 +61075,9 @@ msgid "" "TransitionType] constants with [constant EASE_IN_OUT], and use the one that " "looks best.\n" "[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/" -"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]" +"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n" +"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested " +"operation cannot be completed." msgstr "" #: doc/classes/Tween.xml @@ -61869,9 +62182,17 @@ msgid "" msgstr "" #: doc/classes/Vector2.xml -#, fuzzy -msgid "Returns the cross product of this vector and [code]with[/code]." -msgstr "計算兩個å‘é‡çš„外ç©ã€‚" +msgid "" +"Returns the 2D analog of the cross product for this vector and [code]with[/" +"code].\n" +"This is the signed area of the parallelogram formed by the two vectors. If " +"the second vector is clockwise from the first vector, then the cross product " +"is the positive area. If counter-clockwise, the cross product is the " +"negative area.\n" +"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method " +"embeds the 2D vectors in the XY plane of 3D space and uses their cross " +"product's Z component as the analog." +msgstr "" #: doc/classes/Vector2.xml msgid "" diff --git a/drivers/gles3/rasterizer_array.h b/drivers/gles3/rasterizer_array.h deleted file mode 100644 index 9762e78d54..0000000000 --- a/drivers/gles3/rasterizer_array.h +++ /dev/null @@ -1,421 +0,0 @@ -/*************************************************************************/ -/* rasterizer_array.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef RASTERIZER_ARRAY_H -#define RASTERIZER_ARRAY_H - -/** - * Fast single-threaded growable array for POD types. - * For use in render drivers, not for general use. - * TO BE REPLACED by local_vector. - */ - -#include "core/os/memory.h" -#include <string.h> - -#include "core/templates/local_vector.h" -#include "core/templates/vector.h" - -// very simple non-growable array, that keeps track of the size of a 'unit' -// which can be cast to whatever vertex format FVF required, and is initially -// created with enough memory to hold the biggest FVF. -// This allows multiple FVFs to use the same array. -class RasterizerUnitArrayGLES3 { -public: - RasterizerUnitArrayGLES3() { - _list = nullptr; - free(); - } - ~RasterizerUnitArrayGLES3() { free(); } - - uint8_t *get_unit(unsigned int ui) { return &_list[ui * _unit_size_bytes]; } - const uint8_t *get_unit(unsigned int ui) const { return &_list[ui * _unit_size_bytes]; } - - int size() const { return _size; } - int max_size() const { return _max_size; } - - void free() { - if (_list) { - memdelete_arr(_list); - _list = 0; - } - _size = 0; - _max_size = 0; - _max_size_bytes = 0; - _unit_size_bytes = 0; - } - - void create(int p_max_size_units, int p_max_unit_size_bytes) { - free(); - - _max_unit_size_bytes = p_max_unit_size_bytes; - _max_size = p_max_size_units; - _max_size_bytes = p_max_size_units * p_max_unit_size_bytes; - - if (_max_size_bytes) { - _list = memnew_arr(uint8_t, _max_size_bytes); - } - } - - void prepare(int p_unit_size_bytes) { - _unit_size_bytes = p_unit_size_bytes; - _size = 0; - } - - // several items at a time - uint8_t *request(int p_num_items = 1) { - int old_size = _size; - _size += p_num_items; - - if (_size <= _max_size) { - return get_unit(old_size); - } - - // revert - _size = old_size; - return nullptr; - } - -private: - uint8_t *_list; - int _size; // in units - int _max_size; // in units - int _max_size_bytes; - int _unit_size_bytes; - int _max_unit_size_bytes; -}; - -template <class T> -class RasterizerArray { -public: - RasterizerArray() { - _list = 0; - _size = 0; - _max_size = 0; - } - ~RasterizerArray() { free(); } - - T &operator[](unsigned int ui) { return _list[ui]; } - const T &operator[](unsigned int ui) const { return _list[ui]; } - - void free() { - if (_list) { - memdelete_arr(_list); - _list = 0; - } - _size = 0; - _max_size = 0; - } - - void create(int p_size) { - free(); - if (p_size) { - _list = memnew_arr(T, p_size); - } - _size = 0; - _max_size = p_size; - } - - void reset() { _size = 0; } - - T *request_with_grow() { - T *p = request(); - if (!p) { - grow(); - return request_with_grow(); - } - return p; - } - - // none of that inefficient pass by value stuff here, thanks - T *request() { - if (_size < _max_size) { - return &_list[_size++]; - } - return 0; - } - - // several items at a time - T *request(int p_num_items) { - int old_size = _size; - _size += p_num_items; - - if (_size <= _max_size) { - return &_list[old_size]; - } - - // revert - _size = old_size; - return 0; - } - - int size() const { return _size; } - int max_size() const { return _max_size; } - const T *get_data() const { return _list; } - - bool copy_from(const RasterizerArray<T> &o) { - // no resizing done here, it should be done manually - if (o.size() > _max_size) - return false; - - // pod types only please! - memcpy(_list, o.get_data(), o.size() * sizeof(T)); - _size = o.size(); - return true; - } - - // if you want this to be cheap, call reset before grow, - // to ensure there is no data to copy - void grow() { - unsigned int new_max_size = _max_size * 2; - if (!new_max_size) - new_max_size = 1; - - T *new_list = memnew_arr(T, new_max_size); - - // copy .. pod types only - if (_list) { - memcpy(new_list, _list, _size * sizeof(T)); - } - - unsigned int new_size = size(); - free(); - _list = new_list; - _size = new_size; - _max_size = new_max_size; - } - -private: - T *_list; - int _size; - int _max_size; -}; - -template <class T> -class RasterizerArray_non_pod { -public: - RasterizerArray_non_pod() { - _size = 0; - } - - const T &operator[](unsigned int ui) const { return _list[ui]; } - - void create(int p_size) { - _list.resize(p_size); - _size = 0; - } - void reset() { _size = 0; } - - void push_back(const T &val) { - while (true) { - if (_size < max_size()) { - _list.set(_size, val); - _size++; - return; - } - - grow(); - } - } - - int size() const { return _size; } - int max_size() const { return _list.size(); } - -private: - void grow() { - unsigned int new_max_size = _list.size() * 2; - if (!new_max_size) - new_max_size = 1; - _list.resize(new_max_size); - } - - Vector<T> _list; - int _size; -}; - -// very simple non-growable array, that keeps track of the size of a 'unit' -// which can be cast to whatever vertex format FVF required, and is initially -// created with enough memory to hold the biggest FVF. -// This allows multiple FVFs to use the same array. -class RasterizerUnitArray { -public: - RasterizerUnitArray() { - _list = nullptr; - free(); - } - ~RasterizerUnitArray() { free(); } - - uint8_t *get_unit(unsigned int ui) { return &_list[ui * _unit_size_bytes]; } - const uint8_t *get_unit(unsigned int ui) const { return &_list[ui * _unit_size_bytes]; } - - int size() const { return _size; } - int max_size() const { return _max_size; } - int get_unit_size_bytes() const { return _unit_size_bytes; } - - void free() { - if (_list) { - memdelete_arr(_list); - _list = 0; - } - _size = 0; - _max_size = 0; - _max_size_bytes = 0; - _unit_size_bytes = 0; - } - - void create(int p_max_size_units, int p_max_unit_size_bytes) { - free(); - - _max_unit_size_bytes = p_max_unit_size_bytes; - _max_size = p_max_size_units; - _max_size_bytes = p_max_size_units * p_max_unit_size_bytes; - - if (_max_size_bytes) { - _list = memnew_arr(uint8_t, _max_size_bytes); - } - } - - void prepare(int p_unit_size_bytes) { - _unit_size_bytes = p_unit_size_bytes; - _size = 0; - } - - // several items at a time - uint8_t *request(int p_num_items = 1) { - int old_size = _size; - _size += p_num_items; - - if (_size <= _max_size) { - return get_unit(old_size); - } - - // revert - _size = old_size; - return nullptr; - } - -private: - uint8_t *_list; - int _size; // in units - int _max_size; // in units - int _max_size_bytes; - int _unit_size_bytes; - int _max_unit_size_bytes; -}; - -template <class T, bool force_trivial = false> -class RasterizerPooledList { - LocalVector<T, uint32_t, force_trivial> list; - LocalVector<uint32_t, uint32_t, true> freelist; - - // not all list members are necessarily used - int _used_size; - -public: - RasterizerPooledList() { - _used_size = 0; - } - - int estimate_memory_use() const { - return (list.size() * sizeof(T)) + (freelist.size() * sizeof(uint32_t)); - } - - const T &operator[](uint32_t p_index) const { - return list[p_index]; - } - T &operator[](uint32_t p_index) { - return list[p_index]; - } - - int size() const { return _used_size; } - - // returns the list id of the allocated item - uint32_t alloc() { - uint32_t id = 0; - _used_size++; - - if (freelist.size()) { - // pop from freelist - int new_size = freelist.size() - 1; - id = freelist[new_size]; - freelist.resize(new_size); - return id; - // return &list[r_id]; - } - - id = list.size(); - list.resize(id + 1); - return id; - // return &list[r_id]; - } - void free(const uint32_t &p_id) { - // should not be on free list already - CRASH_COND(p_id >= list.size()); - freelist.push_back(p_id); - _used_size--; - } -}; - -template <class T, bool force_trivial = false> -class RasterizerPooledIndirectList { -public: - const T &operator[](uint32_t p_index) const { - return *_list[p_index]; - } - T &operator[](uint32_t p_index) { - return *_list[p_index]; - } - - uint32_t alloc() { - uint32_t id = _list.alloc(); - _list[id] = memnew(T); - return id; - } - void free(const uint32_t &p_id) { - CRASH_COND(!_list[p_id]); - memdelete_notnull(_list[p_id]); - _list[p_id] = nullptr; - _list.free(p_id); - } - - ~RasterizerPooledIndirectList() { - // autodelete - for (int n = 0; n < _list.size(); n++) { - if (_list[n]) { - memdelete_notnull(_list[n]); - } - } - } - -private: - RasterizerPooledList<T *, true> _list; -}; - -#endif // RASTERIZER_ARRAY_H diff --git a/drivers/gles3/rasterizer_asserts.h b/drivers/gles3/rasterizer_asserts.h deleted file mode 100644 index b39357bffd..0000000000 --- a/drivers/gles3/rasterizer_asserts.h +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************/ -/* rasterizer_asserts.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef RASTERIZER_ASSERTS_H -#define RASTERIZER_ASSERTS_H - -// For flow control checking, we want an easy way to apply asserts that occur in debug development builds only. -// This is enforced by outputting a warning which will fail CI checks if the define is set in a PR. -#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED) -// only uncomment this define for error checking in development, not in the main repository -// as these checks will slow things down in debug builds. -//#define RASTERIZER_EXTRA_CHECKS -#endif - -#ifdef RASTERIZER_EXTRA_CHECKS -#ifndef _MSC_VER -#warning do not define RASTERIZER_EXTRA_CHECKS in main repository builds -#endif -#define RAST_DEV_DEBUG_ASSERT(a) CRASH_COND(!(a)) -#else -#define RAST_DEV_DEBUG_ASSERT(a) -#endif - -// Also very useful, an assert check that only occurs in debug tools builds -#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED) -#define RAST_DEBUG_ASSERT(a) CRASH_COND(!(a)) -#else -#define RAST_DEBUG_ASSERT(a) -#endif - -// Thin wrapper around ERR_FAIL_COND to allow us to make it debug only -#ifdef DEBUG_ENABLED -#define RAST_FAIL_COND(m_cond) ERR_FAIL_COND(m_cond) -#else -#define RAST_FAIL_COND(m_cond) \ - if (m_cond) { \ - } -#endif - -#endif // RASTERIZER_ASSERTS_H diff --git a/drivers/gles3/rasterizer_canvas_base_gles3.cpp b/drivers/gles3/rasterizer_canvas_base_gles3.cpp deleted file mode 100644 index 899e89cbce..0000000000 --- a/drivers/gles3/rasterizer_canvas_base_gles3.cpp +++ /dev/null @@ -1,1354 +0,0 @@ -/*************************************************************************/ -/* rasterizer_canvas_base_gles3.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "rasterizer_canvas_base_gles3.h" -#ifdef GLES3_BACKEND_ENABLED - -#include "core/os/os.h" -#include "drivers/gles3/rasterizer_asserts.h" -#include "rasterizer_scene_gles3.h" - -#include "core/config/project_settings.h" -#include "servers/rendering/rendering_server_default.h" - -#ifndef GLES_OVER_GL -#define glClearDepth glClearDepthf -#endif - -static _FORCE_INLINE_ void store_transform3d(const Transform3D &p_mtx, float *p_array) { - p_array[0] = p_mtx.basis.elements[0][0]; - p_array[1] = p_mtx.basis.elements[1][0]; - p_array[2] = p_mtx.basis.elements[2][0]; - p_array[3] = 0; - p_array[4] = p_mtx.basis.elements[0][1]; - p_array[5] = p_mtx.basis.elements[1][1]; - p_array[6] = p_mtx.basis.elements[2][1]; - p_array[7] = 0; - p_array[8] = p_mtx.basis.elements[0][2]; - p_array[9] = p_mtx.basis.elements[1][2]; - p_array[10] = p_mtx.basis.elements[2][2]; - p_array[11] = 0; - p_array[12] = p_mtx.origin.x; - p_array[13] = p_mtx.origin.y; - p_array[14] = p_mtx.origin.z; - p_array[15] = 1; -} - -RID RasterizerCanvasBaseGLES3::light_internal_create() { - return RID(); -} - -void RasterizerCanvasBaseGLES3::light_internal_update(RID p_rid, Light *p_light) { -} - -void RasterizerCanvasBaseGLES3::light_internal_free(RID p_rid) { -} - -RID RasterizerCanvasBaseGLES3::light_create() { - return RID(); -} - -void RasterizerCanvasBaseGLES3::light_set_texture(RID p_rid, RID p_texture) { -} - -void RasterizerCanvasBaseGLES3::light_set_use_shadow(RID p_rid, bool p_enable) { -} - -void RasterizerCanvasBaseGLES3::light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) { -} - -void RasterizerCanvasBaseGLES3::light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) { -} - -void RasterizerCanvasBaseGLES3::render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) { -} - -RID RasterizerCanvasBaseGLES3::occluder_polygon_create() { - return RID(); -} - -void RasterizerCanvasBaseGLES3::occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) { -} - -void RasterizerCanvasBaseGLES3::occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) { -} - -void RasterizerCanvasBaseGLES3::set_shadow_texture_size(int p_size) { -} - -bool RasterizerCanvasBaseGLES3::free(RID p_rid) { - return true; -} - -void RasterizerCanvasBaseGLES3::update() { -} - -void RasterizerCanvasBaseGLES3::canvas_begin() { - state.using_transparent_rt = false; - - // always start with light_angle unset - state.using_light_angle = false; - state.using_large_vertex = false; - state.using_modulate = false; - - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_LIGHT_ANGLE, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_MODULATE, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_LARGE_VERTEX, false); - state.canvas_shader.bind(); - - int viewport_x, viewport_y, viewport_width, viewport_height; - - if (storage->frame.current_rt) { - storage->bind_framebuffer(storage->frame.current_rt->fbo); - state.using_transparent_rt = storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]; - - if (storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) { - // set Viewport and Scissor when rendering directly to screen - viewport_width = storage->_dims.rt_width; - viewport_height = storage->_dims.rt_height; - viewport_x = storage->frame.current_rt->x; - // FTODO - // viewport_y = OS::get_singleton()->get_window_size().height - viewport_height - storage->frame.current_rt->y; - viewport_y = storage->frame.current_rt->y; - - // viewport_x = 0; - // viewport_y = 0; - - glScissor(viewport_x, viewport_y, viewport_width, viewport_height); - glViewport(viewport_x, viewport_y, viewport_width, viewport_height); - glEnable(GL_SCISSOR_TEST); - } - } - - // FTODO .. this was commented out to try and get the clear color correct - //#ifdef GODOT3 - // OLD METHOD .. now done by render target rather than frame -#if 0 - if (storage->frame.clear_request) { - glClearColor(storage->frame.clear_request_color.r, - storage->frame.clear_request_color.g, - storage->frame.clear_request_color.b, - state.using_transparent_rt ? storage->frame.clear_request_color.a : 1.0); - glClear(GL_COLOR_BUFFER_BIT); - storage->frame.clear_request = false; - } -#endif - - // NEW METHOD - if (storage->frame.current_rt && storage->frame.current_rt->clear_requested) { - const Color &col = storage->frame.current_rt->clear_color; - glClearColor(col.r, col.g, col.b, col.a); - - // clear EVERYTHING. - // not clearing everything can be devastating on tiled renderers especially, - // because if anything is preserved, often the whole frame buffer needs to be preserved. - // Not sure if GL_ACCUM_BUFFER_BIT is needed or supported in GLES. - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - storage->frame.current_rt->clear_requested = false; - } - - //#endif - - /* - if (storage->frame.current_rt) { - glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); - glColorMask(1, 1, 1, 1); - } - */ - - reset_canvas(); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); - - glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1); - glDisableVertexAttribArray(RS::ARRAY_COLOR); - - // set up default uniforms - - Transform3D canvas_transform; - - if (storage->frame.current_rt) { - float csy = 1.0; - // FTODO - // if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_VFLIP]) { - // csy = -1.0; - // } - canvas_transform.translate(-(storage->frame.current_rt->width / 2.0f), -(storage->frame.current_rt->height / 2.0f), 0.0f); - canvas_transform.scale(Vector3(2.0f / storage->frame.current_rt->width, csy * -2.0f / storage->frame.current_rt->height, 1.0f)); - } else { - // FTODO - // Vector2 ssize = OS::get_singleton()->get_window_size(); - Vector2 ssize; - ssize.x = storage->_dims.win_width; - ssize.y = storage->_dims.win_height; - - canvas_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); - canvas_transform.scale(Vector3(2.0f / ssize.width, -2.0f / ssize.height, 1.0f)); - } - - state.uniforms.projection_matrix = canvas_transform; - - state.uniforms.final_modulate = Color(1, 1, 1, 1); - - state.uniforms.modelview_matrix = Transform2D(); - state.uniforms.extra_matrix = Transform2D(); - - _set_uniforms(); - _bind_quad_buffer(); - - glBindBufferBase(GL_UNIFORM_BUFFER, 0, state.canvas_item_ubo); - glBindVertexArray(data.canvas_quad_array); -} - -void RasterizerCanvasBaseGLES3::canvas_end() { - glBindBuffer(GL_ARRAY_BUFFER, 0); - - if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) { - //reset viewport to full window size - // int viewport_width = OS::get_singleton()->get_window_size().width; - // int viewport_height = OS::get_singleton()->get_window_size().height; - int viewport_width = storage->_dims.win_width; - int viewport_height = storage->_dims.win_height; - glViewport(0, 0, viewport_width, viewport_height); - glScissor(0, 0, viewport_width, viewport_height); - } - - state.using_texture_rect = false; - state.using_skeleton = false; - state.using_ninepatch = false; - state.using_transparent_rt = false; -} - -void RasterizerCanvasBaseGLES3::draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src) { - state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(p_rect.position.x, p_rect.position.y, p_rect.size.x, p_rect.size.y)); - state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(p_src.position.x, p_src.position.y, p_src.size.x, p_src.size.y)); - _bind_quad_buffer(); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); -} - -void RasterizerCanvasBaseGLES3::_set_texture_rect_mode(bool p_texture_rect, bool p_light_angle, bool p_modulate, bool p_large_vertex) { - // always set this directly (this could be state checked) - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_TEXTURE_RECT, p_texture_rect); - - if (state.using_light_angle != p_light_angle) { - state.using_light_angle = p_light_angle; - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_LIGHT_ANGLE, p_light_angle); - } - - if (state.using_modulate != p_modulate) { - state.using_modulate = p_modulate; - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_MODULATE, p_modulate); - } - - if (state.using_large_vertex != p_large_vertex) { - state.using_large_vertex = p_large_vertex; - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_LARGE_VERTEX, p_large_vertex); - } -} - -RasterizerStorageGLES3::Texture *RasterizerCanvasBaseGLES3::_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map) { - RasterizerStorageGLES3::Texture *tex_return = NULL; - - if (p_texture.is_valid()) { - RasterizerStorageGLES3::Texture *texture = storage->texture_owner.get_or_null(p_texture); - - if (!texture) { - state.current_tex = RID(); - state.current_tex_ptr = NULL; - - glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1); - glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); - - } else { - if (texture->redraw_if_visible) { - RenderingServerDefault::redraw_request(); - } - - texture = texture->get_ptr(); - - if (texture->render_target) { - texture->render_target->used_in_frame = true; - } - - glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1); - glBindTexture(GL_TEXTURE_2D, texture->tex_id); - - state.current_tex = p_texture; - state.current_tex_ptr = texture; - - // new for Godot 4. Set the texture min mag filter and repeat per item - // we use a wrapper to avoid noop GL state changes - texture->GLSetFilter(GL_TEXTURE_2D, state.current_filter); - - tex_return = texture; - } - } else { - state.current_tex = RID(); - state.current_tex_ptr = NULL; - - glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1); - glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); - } - - if (p_normal_map == state.current_normal) { - //do none - state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, state.current_normal.is_valid()); - - } else if (p_normal_map.is_valid()) { - RasterizerStorageGLES3::Texture *normal_map = storage->texture_owner.get_or_null(p_normal_map); - - if (!normal_map) { - state.current_normal = RID(); - glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2); - glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex); - state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, false); - - } else { - if (normal_map->redraw_if_visible) { //check before proxy, because this is usually used with proxies - RenderingServerDefault::redraw_request(); - } - - normal_map = normal_map->get_ptr(); - - glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2); - glBindTexture(GL_TEXTURE_2D, normal_map->tex_id); - state.current_normal = p_normal_map; - state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, true); - } - - } else { - state.current_normal = RID(); - glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2); - glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex); - state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, false); - } - - return tex_return; -} - -/* -void RasterizerCanvasBaseGLES3::draw_window_margins(int *black_margin, RID *black_image) { - return; - - // FTODO - int window_w = storage->_dims.rt_width; - int window_h = storage->_dims.rt_height; - //Vector2 window_size = Vector2(window_w, window_h); - - // int window_h = window_size.height; - // int window_w = window_size.width; - - // glBindFramebuffer(GL_FRAMEBUFFER, storage->system_fbo); - // glViewport(0, 0, window_size.width, window_size.height); - - canvas_begin(); - - if (black_image[SIDE_LEFT].is_valid()) { - _bind_canvas_texture(black_image[SIDE_LEFT], RID()); - Size2 sz(storage->texture_get_width(black_image[SIDE_LEFT]), storage->texture_get_height(black_image[SIDE_LEFT])); - draw_generic_textured_rect(Rect2(0, 0, black_margin[SIDE_LEFT], window_h), - Rect2(0, 0, (float)black_margin[SIDE_LEFT] / sz.x, (float)(window_h) / sz.y)); - } else if (black_margin[SIDE_LEFT]) { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex); - - draw_generic_textured_rect(Rect2(0, 0, black_margin[SIDE_LEFT], window_h), Rect2(0, 0, 1, 1)); - } - - if (black_image[SIDE_RIGHT].is_valid()) { - _bind_canvas_texture(black_image[SIDE_RIGHT], RID()); - Size2 sz(storage->texture_get_width(black_image[SIDE_RIGHT]), storage->texture_get_height(black_image[SIDE_RIGHT])); - draw_generic_textured_rect(Rect2(window_w - black_margin[SIDE_RIGHT], 0, black_margin[SIDE_RIGHT], window_h), - Rect2(0, 0, (float)black_margin[SIDE_RIGHT] / sz.x, (float)window_h / sz.y)); - } else if (black_margin[SIDE_RIGHT]) { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex); - - draw_generic_textured_rect(Rect2(window_w - black_margin[SIDE_RIGHT], 0, black_margin[SIDE_RIGHT], window_h), Rect2(0, 0, 1, 1)); - } - - if (black_image[SIDE_TOP].is_valid()) { - _bind_canvas_texture(black_image[SIDE_TOP], RID()); - - Size2 sz(storage->texture_get_width(black_image[SIDE_TOP]), storage->texture_get_height(black_image[SIDE_TOP])); - draw_generic_textured_rect(Rect2(0, 0, window_w, black_margin[SIDE_TOP]), - Rect2(0, 0, (float)window_w / sz.x, (float)black_margin[SIDE_TOP] / sz.y)); - - } else if (black_margin[SIDE_TOP]) { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex); - - draw_generic_textured_rect(Rect2(0, 0, window_w, black_margin[SIDE_TOP]), Rect2(0, 0, 1, 1)); - } - - if (black_image[SIDE_BOTTOM].is_valid()) { - _bind_canvas_texture(black_image[SIDE_BOTTOM], RID()); - - Size2 sz(storage->texture_get_width(black_image[SIDE_BOTTOM]), storage->texture_get_height(black_image[SIDE_BOTTOM])); - draw_generic_textured_rect(Rect2(0, window_h - black_margin[SIDE_BOTTOM], window_w, black_margin[SIDE_BOTTOM]), - Rect2(0, 0, (float)window_w / sz.x, (float)black_margin[SIDE_BOTTOM] / sz.y)); - - } else if (black_margin[SIDE_BOTTOM]) { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex); - - draw_generic_textured_rect(Rect2(0, window_h - black_margin[SIDE_BOTTOM], window_w, black_margin[SIDE_BOTTOM]), Rect2(0, 0, 1, 1)); - } - - canvas_end(); -} -*/ - -void RasterizerCanvasBaseGLES3::_bind_quad_buffer() { - glBindVertexArray(data.canvas_quad_array); -} - -void RasterizerCanvasBaseGLES3::_set_uniforms() { - state.canvas_shader.set_uniform(CanvasShaderGLES3::PROJECTION_MATRIX, state.uniforms.projection_matrix); - state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix); - state.canvas_shader.set_uniform(CanvasShaderGLES3::EXTRA_MATRIX, state.uniforms.extra_matrix); - - state.canvas_shader.set_uniform(CanvasShaderGLES3::FINAL_MODULATE, state.uniforms.final_modulate); - - state.canvas_shader.set_uniform(CanvasShaderGLES3::TIME, storage->frame.time[0]); - - if (storage->frame.current_rt) { - Vector2 screen_pixel_size; - screen_pixel_size.x = 1.0 / storage->frame.current_rt->width; - screen_pixel_size.y = 1.0 / storage->frame.current_rt->height; - - state.canvas_shader.set_uniform(CanvasShaderGLES3::SCREEN_PIXEL_SIZE, screen_pixel_size); - } - - if (state.using_skeleton) { - state.canvas_shader.set_uniform(CanvasShaderGLES3::SKELETON_TRANSFORM, state.skeleton_transform); - state.canvas_shader.set_uniform(CanvasShaderGLES3::SKELETON_TRANSFORM_INVERSE, state.skeleton_transform_inverse); - state.canvas_shader.set_uniform(CanvasShaderGLES3::SKELETON_TEXTURE_SIZE, state.skeleton_texture_size); - } - - if (state.using_light) { - Light *light = state.using_light; - state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_MATRIX, light->light_shader_xform); - Transform2D basis_inverse = light->light_shader_xform.affine_inverse().orthonormalized(); - basis_inverse.elements[2] = Vector2(); - state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_MATRIX_INVERSE, basis_inverse); - state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_LOCAL_MATRIX, light->xform_cache.affine_inverse()); - state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_COLOR, light->color * light->energy); - // state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_POS, light->light_shader_pos); - // FTODO - state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_POS, light->light_shader_xform.elements[2]); - state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_HEIGHT, light->height); - - // FTODO - //state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_OUTSIDE_ALPHA, light->mode == RS::CANVAS_LIGHT_MODE_MASK ? 1.0 : 0.0); - state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_OUTSIDE_ALPHA, 0.0f); - - if (state.using_shadow) { - // FTODO -#if 0 - RasterizerStorageGLES3::CanvasLightShadow *cls = storage->canvas_light_shadow_owner.get(light->shadow_buffer); - glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 5); - glBindTexture(GL_TEXTURE_2D, cls->distance); - state.canvas_shader.set_uniform(CanvasShaderGLES3::SHADOW_MATRIX, light->shadow_matrix_cache); - state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_SHADOW_COLOR, light->shadow_color); - - state.canvas_shader.set_uniform(CanvasShaderGLES3::SHADOWPIXEL_SIZE, (1.0 / light->shadow_buffer_size) * (1.0 + light->shadow_smooth)); - if (light->radius_cache == 0) { - state.canvas_shader.set_uniform(CanvasShaderGLES3::SHADOW_GRADIENT, 0.0); - } else { - state.canvas_shader.set_uniform(CanvasShaderGLES3::SHADOW_GRADIENT, light->shadow_gradient_length / (light->radius_cache * 1.1)); - } - state.canvas_shader.set_uniform(CanvasShaderGLES3::SHADOW_DISTANCE_MULT, light->radius_cache * 1.1); -#endif - } - } -} - -void RasterizerCanvasBaseGLES3::reset_canvas() { - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_DITHER); - glEnable(GL_BLEND); - - if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) { - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } else { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - - // bind the back buffer to a texture so shaders can use it. - // It should probably use texture unit -3 (as OpenGL does as well) but currently that's buggy. - // keeping this for now as there's nothing else that uses texture unit 2 - // TODO ^ - if (storage->frame.current_rt) { - // glActiveTexture(GL_TEXTURE0 + 2); - // glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->copy_screen_effect.color); - } - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -} - -void RasterizerCanvasBaseGLES3::canvas_debug_viewport_shadows(Light *p_lights_with_shadow) { -} - -void RasterizerCanvasBaseGLES3::_copy_texscreen(const Rect2 &p_rect) { - state.canvas_texscreen_used = true; - - _copy_screen(p_rect); - - // back to canvas, force rebind - state.using_texture_rect = false; - state.canvas_shader.bind(); - _bind_canvas_texture(state.current_tex, state.current_normal); - _set_uniforms(); -} - -void RasterizerCanvasBaseGLES3::_draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor, const float *p_weights, const int *p_bones) { - glBindVertexArray(data.polygon_buffer_pointer_array); - glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); - - uint32_t buffer_ofs = 0; - uint32_t buffer_ofs_after = buffer_ofs + (sizeof(Vector2) * p_vertex_count); -#ifdef DEBUG_ENABLED - ERR_FAIL_COND(buffer_ofs_after > data.polygon_buffer_size); -#endif - - storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, sizeof(Vector2) * p_vertex_count, p_vertices, GL_ARRAY_BUFFER, _buffer_upload_usage_flag, true); - - glEnableVertexAttribArray(RS::ARRAY_VERTEX); - glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL); - buffer_ofs = buffer_ofs_after; - - if (p_singlecolor) { - glDisableVertexAttribArray(RS::ARRAY_COLOR); - Color m = *p_colors; - glVertexAttrib4f(RS::ARRAY_COLOR, m.r, m.g, m.b, m.a); - } else if (!p_colors) { - glDisableVertexAttribArray(RS::ARRAY_COLOR); - glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1); - } else { - RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors, buffer_ofs_after)); - glEnableVertexAttribArray(RS::ARRAY_COLOR); - glVertexAttribPointer(RS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); - buffer_ofs = buffer_ofs_after; - } - - if (p_uvs) { - RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs, buffer_ofs_after)); - glEnableVertexAttribArray(RS::ARRAY_TEX_UV); - glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); - buffer_ofs = buffer_ofs_after; - } else { - glDisableVertexAttribArray(RS::ARRAY_TEX_UV); - } - - if (p_weights && p_bones) { - RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(float) * 4 * p_vertex_count, p_weights, buffer_ofs_after)); - glEnableVertexAttribArray(RS::ARRAY_WEIGHTS); - glVertexAttribPointer(RS::ARRAY_WEIGHTS, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4, CAST_INT_TO_UCHAR_PTR(buffer_ofs)); - buffer_ofs = buffer_ofs_after; - - RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(int) * 4 * p_vertex_count, p_bones, buffer_ofs_after)); - glEnableVertexAttribArray(RS::ARRAY_BONES); - glVertexAttribPointer(RS::ARRAY_BONES, 4, GL_UNSIGNED_INT, GL_FALSE, sizeof(int) * 4, CAST_INT_TO_UCHAR_PTR(buffer_ofs)); - buffer_ofs = buffer_ofs_after; - - } else { - glDisableVertexAttribArray(RS::ARRAY_WEIGHTS); - glDisableVertexAttribArray(RS::ARRAY_BONES); - } - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer); - - if (storage->config.support_32_bits_indices) { //should check for -#ifdef DEBUG_ENABLED - ERR_FAIL_COND((sizeof(int) * p_index_count) > data.polygon_index_buffer_size); -#endif - storage->buffer_orphan_and_upload(data.polygon_index_buffer_size, 0, sizeof(int) * p_index_count, p_indices, GL_ELEMENT_ARRAY_BUFFER, _buffer_upload_usage_flag, true); - - glDrawElements(GL_TRIANGLES, p_index_count, GL_UNSIGNED_INT, 0); - storage->info.render._2d_draw_call_count++; - } else { -#ifdef DEBUG_ENABLED - ERR_FAIL_COND((sizeof(uint16_t) * p_index_count) > data.polygon_index_buffer_size); -#endif - uint16_t *index16 = (uint16_t *)alloca(sizeof(uint16_t) * p_index_count); - for (int i = 0; i < p_index_count; i++) { - index16[i] = uint16_t(p_indices[i]); - } - storage->buffer_orphan_and_upload(data.polygon_index_buffer_size, 0, sizeof(uint16_t) * p_index_count, index16, GL_ELEMENT_ARRAY_BUFFER, _buffer_upload_usage_flag, true); - glDrawElements(GL_TRIANGLES, p_index_count, GL_UNSIGNED_SHORT, 0); - storage->info.render._2d_draw_call_count++; - } - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -} - -void RasterizerCanvasBaseGLES3::_draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) { - glBindVertexArray(data.polygon_buffer_pointer_array); - glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); - - uint32_t buffer_ofs = 0; - uint32_t buffer_ofs_after = buffer_ofs + (sizeof(Vector2) * p_vertex_count); -#ifdef DEBUG_ENABLED - ERR_FAIL_COND(buffer_ofs_after > data.polygon_buffer_size); -#endif - storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, sizeof(Vector2) * p_vertex_count, p_vertices, GL_ARRAY_BUFFER, _buffer_upload_usage_flag, true); - - glEnableVertexAttribArray(RS::ARRAY_VERTEX); - glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL); - buffer_ofs = buffer_ofs_after; - - if (p_singlecolor) { - glDisableVertexAttribArray(RS::ARRAY_COLOR); - Color m = *p_colors; - glVertexAttrib4f(RS::ARRAY_COLOR, m.r, m.g, m.b, m.a); - } else if (!p_colors) { - glDisableVertexAttribArray(RS::ARRAY_COLOR); - glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1); - } else { - RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors, buffer_ofs_after)); - glEnableVertexAttribArray(RS::ARRAY_COLOR); - glVertexAttribPointer(RS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); - buffer_ofs = buffer_ofs_after; - } - - if (p_uvs) { - RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs, buffer_ofs_after)); - glEnableVertexAttribArray(RS::ARRAY_TEX_UV); - glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); - buffer_ofs = buffer_ofs_after; - } else { - glDisableVertexAttribArray(RS::ARRAY_TEX_UV); - } - - glDrawArrays(p_primitive, 0, p_vertex_count); - storage->info.render._2d_draw_call_count++; - - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -void RasterizerCanvasBaseGLES3::_draw_generic_indices(GLuint p_primitive, const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) { - glBindVertexArray(data.polygon_buffer_pointer_array); - glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); - - uint32_t buffer_ofs = 0; - uint32_t buffer_ofs_after = buffer_ofs + (sizeof(Vector2) * p_vertex_count); -#ifdef DEBUG_ENABLED - ERR_FAIL_COND(buffer_ofs_after > data.polygon_buffer_size); -#endif - storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, sizeof(Vector2) * p_vertex_count, p_vertices, GL_ARRAY_BUFFER, _buffer_upload_usage_flag, true); - - glEnableVertexAttribArray(RS::ARRAY_VERTEX); - glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL); - buffer_ofs = buffer_ofs_after; - - if (p_singlecolor) { - glDisableVertexAttribArray(RS::ARRAY_COLOR); - Color m = *p_colors; - glVertexAttrib4f(RS::ARRAY_COLOR, m.r, m.g, m.b, m.a); - } else if (!p_colors) { - glDisableVertexAttribArray(RS::ARRAY_COLOR); - glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1); - } else { - RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors, buffer_ofs_after)); - glEnableVertexAttribArray(RS::ARRAY_COLOR); - glVertexAttribPointer(RS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); - buffer_ofs = buffer_ofs_after; - } - - if (p_uvs) { - RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs, buffer_ofs_after)); - glEnableVertexAttribArray(RS::ARRAY_TEX_UV); - glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); - buffer_ofs = buffer_ofs_after; - } else { - glDisableVertexAttribArray(RS::ARRAY_TEX_UV); - } - -#ifdef RASTERIZER_EXTRA_CHECKS - // very slow, do not enable in normal use - for (int n = 0; n < p_index_count; n++) { - RAST_DEV_DEBUG_ASSERT(p_indices[n] < p_vertex_count); - } -#endif - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer); - - if (storage->config.support_32_bits_indices) { //should check for -#ifdef DEBUG_ENABLED - ERR_FAIL_COND((sizeof(int) * p_index_count) > data.polygon_index_buffer_size); -#endif - storage->buffer_orphan_and_upload(data.polygon_index_buffer_size, 0, sizeof(int) * p_index_count, p_indices, GL_ELEMENT_ARRAY_BUFFER, _buffer_upload_usage_flag, true); - glDrawElements(p_primitive, p_index_count, GL_UNSIGNED_INT, 0); - storage->info.render._2d_draw_call_count++; - } else { -#ifdef DEBUG_ENABLED - ERR_FAIL_COND((sizeof(uint16_t) * p_index_count) > data.polygon_index_buffer_size); -#endif - uint16_t *index16 = (uint16_t *)alloca(sizeof(uint16_t) * p_index_count); - for (int i = 0; i < p_index_count; i++) { - index16[i] = uint16_t(p_indices[i]); - } - storage->buffer_orphan_and_upload(data.polygon_index_buffer_size, 0, sizeof(uint16_t) * p_index_count, index16, GL_ELEMENT_ARRAY_BUFFER, _buffer_upload_usage_flag, true); - glDrawElements(p_primitive, p_index_count, GL_UNSIGNED_SHORT, 0); - storage->info.render._2d_draw_call_count++; - } - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -} - -void RasterizerCanvasBaseGLES3::_legacy_draw_poly_triangles(Item::CommandPolygon *p_poly, RasterizerStorageGLES3::Material *p_material) { - // return; - - const PolyData &pd = _polydata[p_poly->polygon.polygon_id]; - - _set_texture_rect_mode(false); - - if (state.canvas_shader.bind()) { - _set_uniforms(); - state.canvas_shader.use_material((void *)p_material); - } - - // FTODO - //RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(polygon->texture, polygon->normal_map); - RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(p_poly->texture, RID()); - - if (texture) { - Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height); - state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); - } - - _draw_polygon(pd.indices.ptr(), pd.indices.size(), pd.points.size(), pd.points.ptr(), pd.uvs.ptr(), pd.colors.ptr(), pd.colors.size() == 1, nullptr, nullptr); - -// _draw_polygon(polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1, polygon->weights.ptr(), polygon->bones.ptr()); -#ifdef GLES_OVER_GL -#if 0 - if (polygon->antialiased) { - glEnable(GL_LINE_SMOOTH); - if (polygon->antialiasing_use_indices) { - _draw_generic_indices(GL_LINE_STRIP, polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1); - } else { - _draw_generic(GL_LINE_LOOP, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1); - } - glDisable(GL_LINE_SMOOTH); - } -#endif -#endif -} - -void RasterizerCanvasBaseGLES3::_legacy_draw_primitive(Item::CommandPrimitive *p_pr, RasterizerStorageGLES3::Material *p_material) { - // return; - - if (p_pr->point_count != 4) - return; // not sure if supported - - _set_texture_rect_mode(false); - - if (state.canvas_shader.bind()) { - _set_uniforms(); - state.canvas_shader.use_material((void *)p_material); - } - - _bind_canvas_texture(RID(), RID()); - - glDisableVertexAttribArray(RS::ARRAY_COLOR); - glVertexAttrib4fv(RS::ARRAY_COLOR, p_pr->colors[0].components); - - state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix); - - _draw_gui_primitive(p_pr->point_count, p_pr->points, NULL, NULL); -} - -void RasterizerCanvasBaseGLES3::_legacy_draw_line(Item::CommandPrimitive *p_pr, RasterizerStorageGLES3::Material *p_material) { - _set_texture_rect_mode(false); - - if (state.canvas_shader.bind()) { - _set_uniforms(); - state.canvas_shader.use_material((void *)p_material); - } - - _bind_canvas_texture(RID(), RID()); - - glDisableVertexAttribArray(RS::ARRAY_COLOR); - glVertexAttrib4fv(RS::ARRAY_COLOR, p_pr->colors[0].components); - - state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix); - -#ifdef GLES_OVER_GL -// if (line->antialiased) -// glEnable(GL_LINE_SMOOTH); -#endif - _draw_gui_primitive(2, p_pr->points, NULL, NULL); - -#ifdef GLES_OVER_GL -// if (line->antialiased) -// glDisable(GL_LINE_SMOOTH); -#endif -} - -void RasterizerCanvasBaseGLES3::_draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs, const float *p_light_angles) { - static const GLenum prim[5] = { GL_POINTS, GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN }; - - int version = 0; - int color_offset = 0; - int uv_offset = 0; - int light_angle_offset = 0; - int stride = 2; - - if (p_colors) { - version |= 1; - color_offset = stride; - stride += 4; - } - - if (p_uvs) { - version |= 2; - uv_offset = stride; - stride += 2; - } - - if (p_light_angles) { //light_angles - version |= 4; - light_angle_offset = stride; - stride += 1; - } - - RAST_DEV_DEBUG_ASSERT(p_points <= 4); - float buffer_data[(2 + 2 + 4 + 1) * 4]; - - for (int i = 0; i < p_points; i++) { - buffer_data[stride * i + 0] = p_vertices[i].x; - buffer_data[stride * i + 1] = p_vertices[i].y; - } - - if (p_colors) { - for (int i = 0; i < p_points; i++) { - buffer_data[stride * i + color_offset + 0] = p_colors[i].r; - buffer_data[stride * i + color_offset + 1] = p_colors[i].g; - buffer_data[stride * i + color_offset + 2] = p_colors[i].b; - buffer_data[stride * i + color_offset + 3] = p_colors[i].a; - } - } - - if (p_uvs) { - for (int i = 0; i < p_points; i++) { - buffer_data[stride * i + uv_offset + 0] = p_uvs[i].x; - buffer_data[stride * i + uv_offset + 1] = p_uvs[i].y; - } - } - - if (p_light_angles) { - for (int i = 0; i < p_points; i++) { - buffer_data[stride * i + light_angle_offset + 0] = p_light_angles[i]; - } - } - - glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); - storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, p_points * stride * 4 * sizeof(float), buffer_data, GL_ARRAY_BUFFER, _buffer_upload_usage_flag, true); - - glBindVertexArray(data.polygon_buffer_quad_arrays[version]); - - glDrawArrays(prim[p_points], 0, p_points); - storage->info.render._2d_draw_call_count++; - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -void RasterizerCanvasBaseGLES3::_copy_screen(const Rect2 &p_rect) { - if (storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) { - ERR_PRINT_ONCE("Cannot use screen texture copying in render target set to render direct to screen."); - return; - } - - ERR_FAIL_COND_MSG(storage->frame.current_rt->copy_screen_effect.color == 0, "Can't use screen texture copying in a render target configured without copy buffers."); - - glDisable(GL_BLEND); - - Vector2 wh(storage->frame.current_rt->width, storage->frame.current_rt->height); - - Color copy_section(p_rect.position.x / wh.x, p_rect.position.y / wh.y, p_rect.size.x / wh.x, p_rect.size.y / wh.y); - - if (p_rect != Rect2()) { - storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_COPY_SECTION, true); - } - - storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_NO_ALPHA, !state.using_transparent_rt); - - storage->bind_framebuffer(storage->frame.current_rt->copy_screen_effect.fbo); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color); - - storage->shaders.copy.bind(); - storage->shaders.copy.set_uniform(CopyShaderGLES3::COPY_SECTION, copy_section); - - const Vector2 vertpos[4] = { - Vector2(-1, -1), - Vector2(-1, 1), - Vector2(1, 1), - Vector2(1, -1), - }; - - const Vector2 uvpos[4] = { - Vector2(0, 0), - Vector2(0, 1), - Vector2(1, 1), - Vector2(1, 0) - }; - - const int indexpos[6] = { - 0, 1, 2, - 2, 3, 0 - }; - - _draw_polygon(indexpos, 6, 4, vertpos, uvpos, NULL, false); - - storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_COPY_SECTION, false); - storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_NO_ALPHA, false); - - storage->bind_framebuffer(storage->frame.current_rt->fbo); - glEnable(GL_BLEND); -} - -void RasterizerCanvasBaseGLES3::canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache) { -#if 0 - RasterizerStorageGLES3::CanvasLightShadow *cls = storage->canvas_light_shadow_owner.get(p_buffer); - ERR_FAIL_COND(!cls); - - glDisable(GL_BLEND); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_DITHER); - glDisable(GL_CULL_FACE); - glDepthFunc(GL_LEQUAL); - glEnable(GL_DEPTH_TEST); - glDepthMask(true); - - glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo); - - state.canvas_shadow_shader.set_conditional(CanvasShadowShaderGLES3::USE_RGBA_SHADOWS, storage->config.use_rgba_2d_shadows); - state.canvas_shadow_shader.bind(); - - glViewport(0, 0, cls->size, cls->height); - glClearDepth(1.0f); - glClearColor(1, 1, 1, 1); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - RS::CanvasOccluderPolygonCullMode cull = RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; - - for (int i = 0; i < 4; i++) { - //make sure it remains orthogonal, makes easy to read angle later - - Transform3D light; - light.origin[0] = p_light_xform[2][0]; - light.origin[1] = p_light_xform[2][1]; - light.basis[0][0] = p_light_xform[0][0]; - light.basis[0][1] = p_light_xform[1][0]; - light.basis[1][0] = p_light_xform[0][1]; - light.basis[1][1] = p_light_xform[1][1]; - - //light.basis.scale(Vector3(to_light.elements[0].length(),to_light.elements[1].length(),1)); - - //p_near=1; - CameraMatrix projection; - { - real_t fov = 90; - real_t nearp = p_near; - real_t farp = p_far; - real_t aspect = 1.0; - - real_t ymax = nearp * Math::tan(Math::deg2rad(fov * 0.5)); - real_t ymin = -ymax; - real_t xmin = ymin * aspect; - real_t xmax = ymax * aspect; - - projection.set_frustum(xmin, xmax, ymin, ymax, nearp, farp); - } - - Vector3 cam_target = Basis(Vector3(0, 0, Math_PI * 2 * (i / 4.0))).xform(Vector3(0, 1, 0)); - projection = projection * CameraMatrix(Transform3D().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse()); - - state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES3::PROJECTION_MATRIX, projection); - state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES3::LIGHT_MATRIX, light); - state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES3::DISTANCE_NORM, 1.0 / p_far); - - if (i == 0) - *p_xform_cache = projection; - - glViewport(0, (cls->height / 4) * i, cls->size, cls->height / 4); - - LightOccluderInstance *instance = p_occluders; - - while (instance) { - RasterizerStorageGLES3::CanvasOccluder *cc = storage->canvas_occluder_owner.get_or_null(instance->polygon_buffer); - if (!cc || cc->len == 0 || !(p_light_mask & instance->light_mask)) { - instance = instance->next; - continue; - } - - state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES3::WORLD_MATRIX, instance->xform_cache); - - RS::CanvasOccluderPolygonCullMode transformed_cull_cache = instance->cull_cache; - - if (transformed_cull_cache != RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED && - (p_light_xform.basis_determinant() * instance->xform_cache.basis_determinant()) < 0) { - transformed_cull_cache = - transformed_cull_cache == RS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE ? - RS::CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE : - RS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE; - } - - if (cull != transformed_cull_cache) { - cull = transformed_cull_cache; - switch (cull) { - case RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED: { - glDisable(GL_CULL_FACE); - - } break; - case RS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE: { - glEnable(GL_CULL_FACE); - glCullFace(GL_FRONT); - } break; - case RS::CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE: { - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - - } break; - } - } - - glBindBuffer(GL_ARRAY_BUFFER, cc->vertex_id); - glEnableVertexAttribArray(RS::ARRAY_VERTEX); - glVertexAttribPointer(RS::ARRAY_VERTEX, 3, GL_FLOAT, false, 0, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cc->index_id); - - glDrawElements(GL_TRIANGLES, cc->len * 3, GL_UNSIGNED_SHORT, 0); - - instance = instance->next; - } - } - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -#endif -} - -void RasterizerCanvasBaseGLES3::draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) { - Vector2 half_size; - if (storage->frame.current_rt) { - half_size = Vector2(storage->frame.current_rt->width, storage->frame.current_rt->height); - } else { - // half_size = OS::get_singleton()->get_window_size(); - half_size = Vector2(storage->_dims.win_width, storage->_dims.win_height); - } - half_size *= 0.5; - Vector2 offset((p_rect.position.x - half_size.x) / half_size.x, (p_rect.position.y - half_size.y) / half_size.y); - Vector2 scale(p_rect.size.x / half_size.x, p_rect.size.y / half_size.y); - - float aspect_ratio = p_rect.size.x / p_rect.size.y; - - // setup our lens shader - state.lens_shader.bind(); - state.lens_shader.set_uniform(LensDistortedShaderGLES3::OFFSET, offset); - state.lens_shader.set_uniform(LensDistortedShaderGLES3::SCALE, scale); - state.lens_shader.set_uniform(LensDistortedShaderGLES3::K1, p_k1); - state.lens_shader.set_uniform(LensDistortedShaderGLES3::K2, p_k2); - state.lens_shader.set_uniform(LensDistortedShaderGLES3::EYE_CENTER, p_eye_center); - state.lens_shader.set_uniform(LensDistortedShaderGLES3::UPSCALE, p_oversample); - state.lens_shader.set_uniform(LensDistortedShaderGLES3::ASPECT_RATIO, aspect_ratio); - - // bind our quad buffer - _bind_quad_buffer(); - - // and draw - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - // and cleanup - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -void RasterizerCanvasBaseGLES3::initialize() { - bool flag_stream = false; - //flag_stream = GLOBAL_GET("rendering/options/api_usage_legacy/flag_stream"); - if (flag_stream) - _buffer_upload_usage_flag = GL_STREAM_DRAW; - else - _buffer_upload_usage_flag = GL_DYNAMIC_DRAW; - - // quad buffer - { - glGenBuffers(1, &data.canvas_quad_vertices); - glBindBuffer(GL_ARRAY_BUFFER, data.canvas_quad_vertices); - - const float qv[8] = { - 0, 0, - 0, 1, - 1, 1, - 1, 0 - }; - - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, qv, GL_STATIC_DRAW); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glGenVertexArrays(1, &data.canvas_quad_array); - glBindVertexArray(data.canvas_quad_array); - glBindBuffer(GL_ARRAY_BUFFER, data.canvas_quad_vertices); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, nullptr); - glEnableVertexAttribArray(0); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind - } - - { - //particle quad buffers - - glGenBuffers(1, &data.particle_quad_vertices); - glBindBuffer(GL_ARRAY_BUFFER, data.particle_quad_vertices); - { - //quad of size 1, with pivot on the center for particles, then regular UVS. Color is general plus fetched from particle - const float qv[16] = { - -0.5, -0.5, - 0.0, 0.0, - -0.5, 0.5, - 0.0, 1.0, - 0.5, 0.5, - 1.0, 1.0, - 0.5, -0.5, - 1.0, 0.0 - }; - - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 16, qv, GL_STATIC_DRAW); - } - - glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind - - glGenVertexArrays(1, &data.particle_quad_array); - glBindVertexArray(data.particle_quad_array); - glBindBuffer(GL_ARRAY_BUFFER, data.particle_quad_vertices); - glEnableVertexAttribArray(RS::ARRAY_VERTEX); - glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, nullptr); - glEnableVertexAttribArray(RS::ARRAY_TEX_UV); - glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, CAST_INT_TO_UCHAR_PTR(8)); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind - } - - // polygon buffer - { - uint32_t poly_size = 128; //GLOBAL_DEF_RST("rendering/limits/buffers/canvas_polygon_buffer_size_kb", 128); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/canvas_polygon_buffer_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/canvas_polygon_buffer_size_kb", PROPERTY_HINT_RANGE, "0,256,1,or_greater")); - poly_size = MAX(poly_size, 2); // minimum 2k, may still see anomalies in editor - poly_size *= 1024; //kb - glGenBuffers(1, &data.polygon_buffer); - glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); - glBufferData(GL_ARRAY_BUFFER, poly_size, nullptr, GL_DYNAMIC_DRAW); //allocate max size - glBindBuffer(GL_ARRAY_BUFFER, 0); - data.polygon_buffer_size = poly_size; - - //quad arrays - for (int i = 0; i < Data::NUM_QUAD_ARRAY_VARIATIONS; i++) { - glGenVertexArrays(1, &data.polygon_buffer_quad_arrays[i]); - glBindVertexArray(data.polygon_buffer_quad_arrays[i]); - glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); - - int uv_ofs = 0; - int color_ofs = 0; - int light_angle_ofs = 0; - int stride = 2 * 4; - - if (i & 1) { //color - color_ofs = stride; - stride += 4 * 4; - } - - if (i & 2) { //uv - uv_ofs = stride; - stride += 2 * 4; - } - - if (i & 4) { //light_angle - light_angle_ofs = stride; - stride += 1 * 4; - } - - glEnableVertexAttribArray(RS::ARRAY_VERTEX); - glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, stride, nullptr); - - if (i & 1) { - glEnableVertexAttribArray(RS::ARRAY_COLOR); - glVertexAttribPointer(RS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(color_ofs)); - } - - if (i & 2) { - glEnableVertexAttribArray(RS::ARRAY_TEX_UV); - glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(uv_ofs)); - } - - if (i & 4) { - // reusing tangent for light_angle - glEnableVertexAttribArray(RS::ARRAY_TANGENT); - glVertexAttribPointer(RS::ARRAY_TANGENT, 1, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(light_angle_ofs)); - } - - glBindVertexArray(0); - } - - glGenVertexArrays(1, &data.polygon_buffer_pointer_array); - - uint32_t index_size = 128; //GLOBAL_DEF_RST("rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", 128); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", PROPERTY_HINT_RANGE, "0,256,1,or_greater")); - index_size = MAX(index_size, 2); - index_size *= 1024; //kb - glGenBuffers(1, &data.polygon_index_buffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_size, nullptr, GL_DYNAMIC_DRAW); //allocate max size - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - data.polygon_index_buffer_size = index_size; - } - - // ninepatch buffers - { - // array buffer - glGenBuffers(1, &data.ninepatch_vertices); - glBindBuffer(GL_ARRAY_BUFFER, data.ninepatch_vertices); - - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * (16 + 16) * 2, NULL, GL_DYNAMIC_DRAW); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - - // element buffer - glGenBuffers(1, &data.ninepatch_elements); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ninepatch_elements); - -#define _EIDX(y, x) (y * 4 + x) - uint8_t elems[3 * 2 * 9] = { - // first row - - _EIDX(0, 0), _EIDX(0, 1), _EIDX(1, 1), - _EIDX(1, 1), _EIDX(1, 0), _EIDX(0, 0), - - _EIDX(0, 1), _EIDX(0, 2), _EIDX(1, 2), - _EIDX(1, 2), _EIDX(1, 1), _EIDX(0, 1), - - _EIDX(0, 2), _EIDX(0, 3), _EIDX(1, 3), - _EIDX(1, 3), _EIDX(1, 2), _EIDX(0, 2), - - // second row - - _EIDX(1, 0), _EIDX(1, 1), _EIDX(2, 1), - _EIDX(2, 1), _EIDX(2, 0), _EIDX(1, 0), - - // the center one would be here, but we'll put it at the end - // so it's easier to disable the center and be able to use - // one draw call for both - - _EIDX(1, 2), _EIDX(1, 3), _EIDX(2, 3), - _EIDX(2, 3), _EIDX(2, 2), _EIDX(1, 2), - - // third row - - _EIDX(2, 0), _EIDX(2, 1), _EIDX(3, 1), - _EIDX(3, 1), _EIDX(3, 0), _EIDX(2, 0), - - _EIDX(2, 1), _EIDX(2, 2), _EIDX(3, 2), - _EIDX(3, 2), _EIDX(3, 1), _EIDX(2, 1), - - _EIDX(2, 2), _EIDX(2, 3), _EIDX(3, 3), - _EIDX(3, 3), _EIDX(3, 2), _EIDX(2, 2), - - // center field - - _EIDX(1, 1), _EIDX(1, 2), _EIDX(2, 2), - _EIDX(2, 2), _EIDX(2, 1), _EIDX(1, 1) - }; -#undef _EIDX - - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elems), elems, GL_STATIC_DRAW); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } - - store_transform3d(Transform3D(), state.canvas_item_ubo_data.projection_matrix); - - glGenBuffers(1, &state.canvas_item_ubo); - glBindBuffer(GL_UNIFORM_BUFFER, state.canvas_item_ubo); - glBufferData(GL_UNIFORM_BUFFER, sizeof(CanvasItemUBO), &state.canvas_item_ubo_data, GL_DYNAMIC_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, 0); - - state.canvas_shadow_shader.init(); - state.canvas_shader.init(); - _set_texture_rect_mode(true); - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_RGBA_SHADOWS, storage->config.use_rgba_2d_shadows); - - state.canvas_shader.bind(); - - state.lens_shader.init(); - - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/quality/2d/use_pixel_snap", false)); - - state.using_light = NULL; - state.using_transparent_rt = false; - state.using_skeleton = false; -} - -RendererCanvasRender::PolygonID RasterizerCanvasBaseGLES3::request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights) { - uint32_t id = _polydata.alloc(); - PolyData &pd = _polydata[id]; - pd.indices = p_indices; - pd.points = p_points; - pd.colors = p_colors; - pd.uvs = p_uvs; - return id; -} -void RasterizerCanvasBaseGLES3::free_polygon(PolygonID p_polygon) { - _polydata.free(p_polygon); -} - -void RasterizerCanvasBaseGLES3::finalize() { - glDeleteBuffers(1, &data.canvas_quad_vertices); - glDeleteVertexArrays(1, &data.canvas_quad_array); - - glDeleteBuffers(1, &data.canvas_quad_vertices); - glDeleteVertexArrays(1, &data.canvas_quad_array); - - glDeleteVertexArrays(1, &data.polygon_buffer_pointer_array); -} - -RasterizerCanvasBaseGLES3::RasterizerCanvasBaseGLES3() { -} - -#endif // GLES3_BACKEND_ENABLED diff --git a/drivers/gles3/rasterizer_canvas_base_gles3.h b/drivers/gles3/rasterizer_canvas_base_gles3.h deleted file mode 100644 index 60292ff875..0000000000 --- a/drivers/gles3/rasterizer_canvas_base_gles3.h +++ /dev/null @@ -1,213 +0,0 @@ -/*************************************************************************/ -/* rasterizer_canvas_base_gles3.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef RASTERIZER_CANVAS_BASE_OPENGL_H -#define RASTERIZER_CANVAS_BASE_OPENGL_H - -#include "drivers/gles3/rasterizer_platforms.h" -#ifdef GLES3_BACKEND_ENABLED - -#include "drivers/gles3/rasterizer_array.h" -#include "drivers/gles3/rasterizer_storage_common.h" -#include "rasterizer_scene_gles3.h" -#include "rasterizer_storage_gles3.h" -#include "servers/rendering/renderer_canvas_render.h" -#include "servers/rendering/renderer_compositor.h" - -#include "shaders/canvas.glsl.gen.h" -#include "shaders/canvas_shadow.glsl.gen.h" -#include "shaders/lens_distorted.glsl.gen.h" - -class RasterizerCanvasBaseGLES3 : public RendererCanvasRender { -public: - enum { - INSTANCE_ATTRIB_BASE = 8, - }; - - struct Uniforms { - Transform3D projection_matrix; - - Transform2D modelview_matrix; - Transform2D extra_matrix; - - Color final_modulate; - - float time; - }; - - struct CanvasItemUBO { - float projection_matrix[16]; - float time; - uint8_t padding[12]; - }; - - struct Data { - enum { NUM_QUAD_ARRAY_VARIATIONS = 8 }; - - GLuint canvas_quad_vertices; - GLuint canvas_quad_array; - - GLuint polygon_buffer; - GLuint polygon_buffer_quad_arrays[NUM_QUAD_ARRAY_VARIATIONS]; - GLuint polygon_buffer_pointer_array; - GLuint polygon_index_buffer; - - GLuint particle_quad_vertices; - GLuint particle_quad_array; - - uint32_t polygon_buffer_size; - uint32_t polygon_index_buffer_size; - - GLuint ninepatch_vertices; - GLuint ninepatch_elements; - } data; - - struct State { - Uniforms uniforms; - CanvasItemUBO canvas_item_ubo_data; - GLuint canvas_item_ubo; - bool canvas_texscreen_used; - CanvasShaderGLES3 canvas_shader; - CanvasShadowShaderGLES3 canvas_shadow_shader; - LensDistortedShaderGLES3 lens_shader; - - bool using_texture_rect; - - bool using_light_angle; - bool using_modulate; - bool using_large_vertex; - - bool using_ninepatch; - bool using_skeleton; - - Transform2D skeleton_transform; - Transform2D skeleton_transform_inverse; - Size2i skeleton_texture_size; - - RID current_tex; - RID current_normal; - RasterizerStorageGLES3::Texture *current_tex_ptr; - - Transform3D vp; - Light *using_light; - bool using_shadow; - bool using_transparent_rt; - - // new for Godot 4.0 - // min mag filter is per item, and repeat - RS::CanvasItemTextureFilter current_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR; - RS::CanvasItemTextureRepeat current_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; - } state; - - typedef void Texture; - - RasterizerSceneGLES3 *scene_render; - - RasterizerStorageGLES3 *storage; - - // allow user to choose api usage - GLenum _buffer_upload_usage_flag; - - void _set_uniforms(); - - virtual RID light_internal_create(); - virtual void light_internal_update(RID p_rid, Light *p_light); - virtual void light_internal_free(RID p_rid); - - virtual void canvas_begin(); - virtual void canvas_end(); - -protected: - void _legacy_draw_primitive(Item::CommandPrimitive *p_pr, RasterizerStorageGLES3::Material *p_material); - void _legacy_draw_line(Item::CommandPrimitive *p_pr, RasterizerStorageGLES3::Material *p_material); - void _legacy_draw_poly_triangles(Item::CommandPolygon *p_poly, RasterizerStorageGLES3::Material *p_material); - -public: - void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs, const float *p_light_angles = nullptr); - void _draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor, const float *p_weights = NULL, const int *p_bones = NULL); - void _draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor); - void _draw_generic_indices(GLuint p_primitive, const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor); - - void _bind_quad_buffer(); - void _copy_texscreen(const Rect2 &p_rect); - void _copy_screen(const Rect2 &p_rect); - - //virtual void draw_window_margins(int *black_margin, RID *black_image) override; - void draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src); - void draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample); - - virtual void reset_canvas(); - virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache); - - // Copied from RasterizerCanvasDummy: - virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) override; - - RID light_create() override; - void light_set_texture(RID p_rid, RID p_texture) override; - void light_set_use_shadow(RID p_rid, bool p_enable) override; - void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) override; - void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) override; - - void render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) override; - RID occluder_polygon_create() override; - void occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) override; - void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) override; - void set_shadow_texture_size(int p_size) override; - - bool free(RID p_rid) override; - void update() override; - // End copied from RasterizerCanvasDummy. - - RasterizerStorageGLES3::Texture *_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map); - void _set_texture_rect_mode(bool p_texture_rect, bool p_light_angle = false, bool p_modulate = false, bool p_large_vertex = false); - - // NEW API - struct PolyData { - LocalVector<int> indices; - LocalVector<Point2> points; - LocalVector<Color> colors; - LocalVector<Point2> uvs; - }; - - RendererCanvasRender::PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()) override; - void free_polygon(PolygonID p_polygon) override; - - RasterizerPooledIndirectList<PolyData> _polydata; - - ////////////////////// - void initialize(); - void finalize(); - - RasterizerCanvasBaseGLES3(); -}; - -#endif // GLES3_BACKEND_ENABLED - -#endif // RASTERIZER_CANVAS_BASE_OPENGL_H diff --git a/drivers/gles3/rasterizer_canvas_batcher.h b/drivers/gles3/rasterizer_canvas_batcher.h deleted file mode 100644 index c505d46859..0000000000 --- a/drivers/gles3/rasterizer_canvas_batcher.h +++ /dev/null @@ -1,1560 +0,0 @@ -/*************************************************************************/ -/* rasterizer_canvas_batcher.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef RASTERIZER_CANVAS_BATCHER_H -#define RASTERIZER_CANVAS_BATCHER_H - -#include "core/os/os.h" -#include "core/templates/local_vector.h" -#include "rasterizer_array.h" -#include "rasterizer_asserts.h" -#include "rasterizer_storage_common.h" - -#include "core/config/project_settings.h" -#include "servers/rendering/renderer_compositor.h" - -// We are using the curiously recurring template pattern -// https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern -// For static polymorphism. - -// This makes it super easy to access -// data / call funcs in the derived rasterizers from the base without writing and -// maintaining a boatload of virtual functions. -// In addition it assures that vtable will not be used and the function calls can be optimized, -// because it gives compile time static polymorphism. - -// These macros makes it simpler and less verbose to define (and redefine) the inline functions -// template preamble -#define T_PREAMBLE template <class T, typename T_STORAGE> -// class preamble -#define C_PREAMBLE RasterizerCanvasBatcher<T, T_STORAGE> -// generic preamble -#define PREAMBLE(RET_T) \ - T_PREAMBLE \ - RET_T C_PREAMBLE - -template <class T, typename T_STORAGE> -class RasterizerCanvasBatcher { -public: - // used to determine whether we use hardware transform (none) - // software transform all verts, or software transform just a translate - // (no rotate or scale) - enum TransformMode { - TM_NONE, - TM_ALL, - TM_TRANSLATE, - }; - - // pod versions of vector and color and RID, need to be 32 bit for vertex format - struct BatchVector2 { - float x, y; - void set(float xx, float yy) { - x = xx; - y = yy; - } - void set(const Vector2 &p_o) { - x = p_o.x; - y = p_o.y; - } - void to(Vector2 &r_o) const { - r_o.x = x; - r_o.y = y; - } - }; - - struct BatchColor { - float r, g, b, a; - void set_white() { - r = 1.0f; - g = 1.0f; - b = 1.0f; - a = 1.0f; - } - void set(const Color &p_c) { - r = p_c.r; - g = p_c.g; - b = p_c.b; - a = p_c.a; - } - void set(float rr, float gg, float bb, float aa) { - r = rr; - g = gg; - b = bb; - a = aa; - } - bool operator==(const BatchColor &p_c) const { - return (r == p_c.r) && (g == p_c.g) && (b == p_c.b) && (a == p_c.a); - } - bool operator!=(const BatchColor &p_c) const { return (*this == p_c) == false; } - bool equals(const Color &p_c) const { - return (r == p_c.r) && (g == p_c.g) && (b == p_c.b) && (a == p_c.a); - } - const float *get_data() const { return &r; } - String to_string() const { - String sz = "{"; - const float *data = get_data(); - for (int c = 0; c < 4; c++) { - float f = data[c]; - int val = ((f * 255.0f) + 0.5f); - sz += String(Variant(val)) + " "; - } - sz += "}"; - return sz; - } - }; - - // simplest FVF - local or baked position - struct BatchVertex { - // must be 32 bit pod - BatchVector2 pos; - BatchVector2 uv; - }; - - // simple FVF but also incorporating baked color - struct BatchVertexColored : public BatchVertex { - // must be 32 bit pod - BatchColor col; - }; - - // if we are using normal mapping, we need light angles to be sent - struct BatchVertexLightAngled : public BatchVertexColored { - // must be pod - float light_angle; - }; - - // CUSTOM SHADER vertex formats. These are larger but will probably - // be needed with custom shaders in order to have the data accessible in the shader. - - // if we are using COLOR in vertex shader but not position (VERTEX) - struct BatchVertexModulated : public BatchVertexLightAngled { - BatchColor modulate; - }; - - struct BatchTransform { - BatchVector2 translate; - BatchVector2 basis[2]; - }; - - // last resort, specially for custom shader, we put everything possible into a huge FVF - // not very efficient, but better than no batching at all. - struct BatchVertexLarge : public BatchVertexModulated { - // must be pod - BatchTransform transform; - }; - - // Batch should be as small as possible, and ideally nicely aligned (is 32 bytes at the moment) - struct Batch { - RasterizerStorageCommon::BatchType type; // should be 16 bit - uint16_t batch_texture_id; - - // also item reference number - uint32_t first_command; - - // in the case of DEFAULT, this is num commands. - // with rects, is number of command and rects. - // with lines, is number of lines - uint32_t num_commands; - - // first vertex of this batch in the vertex lists - uint32_t first_vert; - - BatchColor color; - }; - - struct BatchTex { - enum TileMode : uint32_t { - TILE_OFF, - TILE_NORMAL, - TILE_FORCE_REPEAT, - }; - RID RID_texture; - RID RID_normal; - TileMode tile_mode; - BatchVector2 tex_pixel_size; - uint32_t flags; - }; - - // items in a list to be sorted prior to joining - struct BSortItem { - // have a function to keep as pod, rather than operator - void assign(const BSortItem &o) { - item = o.item; - z_index = o.z_index; - } - RendererCanvasRender::Item *item; - int z_index; - }; - - // batch item may represent 1 or more items - struct BItemJoined { - uint32_t first_item_ref; - uint32_t num_item_refs; - - Rect2 bounding_rect; - - // note the z_index may only be correct for the first of the joined item references - // this has implications for light culling with z ranged lights. - int16_t z_index; - - // these are defined in RasterizerStorageCommon::BatchFlags - uint16_t flags; - - // we are always splitting items with lots of commands, - // and items with unhandled primitives (default) - bool use_hardware_transform() const { return num_item_refs == 1; } - }; - - struct BItemRef { - RendererCanvasRender::Item *item; - Color final_modulate; - }; - - struct BLightRegion { - void reset() { - light_bitfield = 0; - shadow_bitfield = 0; - too_many_lights = false; - } - uint64_t light_bitfield; - uint64_t shadow_bitfield; - bool too_many_lights; // we can only do light region optimization if there are 64 or less lights - }; - - struct BatchData { - BatchData() { - reset_flush(); - reset_joined_item(); - - gl_vertex_buffer = 0; - gl_index_buffer = 0; - max_quads = 0; - vertex_buffer_size_units = 0; - vertex_buffer_size_bytes = 0; - index_buffer_size_units = 0; - index_buffer_size_bytes = 0; - - use_colored_vertices = false; - - settings_use_batching = false; - settings_max_join_item_commands = 0; - settings_colored_vertex_format_threshold = 0.0f; - settings_batch_buffer_num_verts = 0; - scissor_threshold_area = 0.0f; - joined_item_batch_flags = 0; - diagnose_frame = false; - next_diagnose_tick = 10000; - diagnose_frame_number = 9999999999; // some high number - join_across_z_indices = true; - settings_item_reordering_lookahead = 0; - - settings_use_batching_original_choice = false; - settings_flash_batching = false; - settings_diagnose_frame = false; - settings_scissor_lights = false; - settings_scissor_threshold = -1.0f; - settings_use_single_rect_fallback = false; - settings_use_software_skinning = true; - settings_ninepatch_mode = 0; // default - settings_light_max_join_items = 16; - - settings_uv_contract = false; - settings_uv_contract_amount = 0.0f; - - buffer_mode_batch_upload_send_null = true; - buffer_mode_batch_upload_flag_stream = false; - - stats_items_sorted = 0; - stats_light_items_joined = 0; - } - - // called for each joined item - void reset_joined_item() { - // noop but left in as a stub - } - - // called after each flush - void reset_flush() { - batches.reset(); - batch_textures.reset(); - - vertices.reset(); - light_angles.reset(); - vertex_colors.reset(); - vertex_modulates.reset(); - vertex_transforms.reset(); - - total_quads = 0; - total_verts = 0; - total_color_changes = 0; - - use_light_angles = false; - use_modulate = false; - use_large_verts = false; - fvf = RasterizerStorageCommon::FVF_REGULAR; - } - - unsigned int gl_vertex_buffer; - unsigned int gl_index_buffer; - - uint32_t max_quads; - uint32_t vertex_buffer_size_units; - uint32_t vertex_buffer_size_bytes; - uint32_t index_buffer_size_units; - uint32_t index_buffer_size_bytes; - - // small vertex FVF type - pos and UV. - // This will always be written to initially, but can be translated - // to larger FVFs if necessary. - RasterizerArray<BatchVertex> vertices; - - // extra data which can be stored during prefilling, for later translation to larger FVFs - RasterizerArray<float> light_angles; - RasterizerArray<BatchColor> vertex_colors; // these aren't usually used, but are for polys - RasterizerArray<BatchColor> vertex_modulates; - RasterizerArray<BatchTransform> vertex_transforms; - - // instead of having a different buffer for each vertex FVF type - // we have a special array big enough for the biggest FVF - // which can have a changeable unit size, and reuse it. - RasterizerUnitArray unit_vertices; - - RasterizerArray<Batch> batches; - RasterizerArray<Batch> batches_temp; // used for translating to colored vertex batches - RasterizerArray_non_pod<BatchTex> batch_textures; // the only reason this is non-POD is because of RIDs - - // SHOULD THESE BE IN FILLSTATE? - // flexible vertex format. - // all verts have pos and UV. - // some have color, some light angles etc. - RasterizerStorageCommon::FVF fvf; - bool use_colored_vertices; - bool use_light_angles; - bool use_modulate; - bool use_large_verts; - - // if the shader is using MODULATE, we prevent baking color so the final_modulate can - // be read in the shader. - // if the shader is reading VERTEX, we prevent baking vertex positions with extra matrices etc - // to prevent the read position being incorrect. - // These flags are defined in RasterizerStorageCommon::BatchFlags - uint32_t joined_item_batch_flags; - - RasterizerArray<BItemJoined> items_joined; - RasterizerArray<BItemRef> item_refs; - - // items are sorted prior to joining - RasterizerArray<BSortItem> sort_items; - - // new for Godot 4 .. the client outputs a linked list so we need to convert this - // to a linear array - LocalVector<RendererCanvasRender::Item::Command *> command_shortlist; - - // counts - int total_quads; - int total_verts; - - // we keep a record of how many color changes caused new batches - // if the colors are causing an excessive number of batches, we switch - // to alternate batching method and add color to the vertex format. - int total_color_changes; - - // measured in pixels, recalculated each frame - float scissor_threshold_area; - - // diagnose this frame, every nTh frame when settings_diagnose_frame is on - bool diagnose_frame; - String frame_string; - uint32_t next_diagnose_tick; - uint64_t diagnose_frame_number; - - // whether to join items across z_indices - this can interfere with z ranged lights, - // so has to be disabled in some circumstances - bool join_across_z_indices; - - // global settings - bool settings_use_batching; // the current use_batching (affected by flash) - bool settings_use_batching_original_choice; // the choice entered in project settings - bool settings_flash_batching; // for regression testing, flash between non-batched and batched renderer - bool settings_diagnose_frame; // print out batches to help optimize / regression test - int settings_max_join_item_commands; - float settings_colored_vertex_format_threshold; - int settings_batch_buffer_num_verts; - bool settings_scissor_lights; - float settings_scissor_threshold; // 0.0 to 1.0 - int settings_item_reordering_lookahead; - bool settings_use_single_rect_fallback; - bool settings_use_software_skinning; - int settings_light_max_join_items; - int settings_ninepatch_mode; - - // buffer orphaning modes - bool buffer_mode_batch_upload_send_null; - bool buffer_mode_batch_upload_flag_stream; - - // uv contraction - bool settings_uv_contract; - float settings_uv_contract_amount; - - // only done on diagnose frame - void reset_stats() { - stats_items_sorted = 0; - stats_light_items_joined = 0; - } - - // frame stats (just for monitoring and debugging) - int stats_items_sorted; - int stats_light_items_joined; - } bdata; - - struct FillState { - void reset_flush() { - // don't reset members that need to be preserved after flushing - // half way through a list of commands - curr_batch = 0; - batch_tex_id = -1; - texpixel_size = Vector2(1, 1); - contract_uvs = false; - - sequence_batch_type_flags = 0; - } - - void reset_joined_item(bool p_use_hardware_transform) { - reset_flush(); - use_hardware_transform = p_use_hardware_transform; - extra_matrix_sent = false; - } - - // for batching multiple types, we don't allow mixing RECTs / LINEs etc. - // using flags allows quicker rejection of sequences with different batch types - uint32_t sequence_batch_type_flags; - - Batch *curr_batch; - int batch_tex_id; - bool use_hardware_transform; - bool contract_uvs; - Vector2 texpixel_size; - Color final_modulate; - TransformMode transform_mode; - TransformMode orig_transform_mode; - - // support for extra matrices - bool extra_matrix_sent; // whether sent on this item (in which case software transform can't be used untl end of item) - int transform_extra_command_number_p1; // plus one to allow fast checking against zero - Transform2D transform_combined; // final * extra - }; - - // used during try_join - struct RenderItemState { - RenderItemState() { reset(); } - void reset() { - current_clip = nullptr; - shader_cache = nullptr; - rebind_shader = true; - prev_use_skeleton = false; - last_blend_mode = -1; - canvas_last_material = RID(); - item_group_z = 0; - item_group_light = nullptr; - final_modulate = Color(-1.0, -1.0, -1.0, -1.0); // just something unlikely - - joined_item_batch_type_flags_curr = 0; - joined_item_batch_type_flags_prev = 0; - - joined_item = nullptr; - } - - RendererCanvasRender::Item *current_clip; - typename T_STORAGE::Shader *shader_cache; - bool rebind_shader; - bool prev_use_skeleton; - bool prev_distance_field; - int last_blend_mode; - RID canvas_last_material; - Color final_modulate; - - // used for joining items only - BItemJoined *joined_item; - bool join_batch_break; - BLightRegion light_region; - - // we need some logic to prevent joining items that have vastly different batch types - // these are defined in RasterizerStorageCommon::BatchTypeFlags - uint32_t joined_item_batch_type_flags_curr; - uint32_t joined_item_batch_type_flags_prev; - - // 'item group' is data over a single call to canvas_render_items - int item_group_z; - Color item_group_modulate; - RendererCanvasRender::Light *item_group_light; - Transform2D item_group_base_transform; - } _render_item_state; - - bool use_nvidia_rect_workaround; - - ////////////////////////////////////////////////////////////////////////////// - // End of structs used by the batcher. Beginning of funcs. -private: - // curiously recurring template pattern - allows access to functions in the DERIVED class - // this is kind of like using virtual functions but more efficient as they are resolved at compile time - T_STORAGE *get_storage() { return static_cast<const T *>(this)->storage; } - const T_STORAGE *get_storage() const { return static_cast<const T *>(this)->storage; } - T *get_this() { return static_cast<T *>(this); } - const T *get_this() const { return static_cast<const T *>(this); } - -protected: - // main functions called from the rasterizer canvas - void batch_constructor(); - void batch_initialize(); - - void batch_canvas_begin(); - void batch_canvas_end(); - void batch_canvas_render_items_begin(const Color &p_modulate, RendererCanvasRender::Light *p_light, const Transform2D &p_base_transform); - void batch_canvas_render_items_end(); - void batch_canvas_render_items(RendererCanvasRender::Item *p_item_list, int p_z, const Color &p_modulate, RendererCanvasRender::Light *p_light, const Transform2D &p_base_transform); - - // recording and sorting items from the initial pass - void record_items(RendererCanvasRender::Item *p_item_list, int p_z); - void join_sorted_items(); - void sort_items(); - bool _sort_items_match(const BSortItem &p_a, const BSortItem &p_b) const; - bool sort_items_from(int p_start); - - // joining logic - bool _disallow_item_join_if_batch_types_too_different(RenderItemState &r_ris, uint32_t btf_allowed); - bool _detect_item_batch_break(RenderItemState &r_ris, RendererCanvasRender::Item *p_ci, bool &r_batch_break); - - // drives the loop filling batches and flushing - void render_joined_item_commands(const BItemJoined &p_bij, RendererCanvasRender::Item *p_current_clip, bool &r_reclip, typename T_STORAGE::Material *p_material, bool p_lit); - -private: - // flush once full or end of joined item - void flush_render_batches(RendererCanvasRender::Item *p_first_item, RendererCanvasRender::Item *p_current_clip, bool &r_reclip, typename T_STORAGE::Material *p_material, uint32_t p_sequence_batch_type_flags); - - // a single joined item can contain multiple itemrefs, and thus create lots of batches - // command start given a separate name to make easier to tell apart godot 3 and 4 - bool prefill_joined_item(FillState &r_fill_state, RendererCanvasRender::Item::Command **r_first_command, RendererCanvasRender::Item *p_item, RendererCanvasRender::Item *p_current_clip, bool &r_reclip, typename T_STORAGE::Material *p_material); - - // prefilling different types of batch - - // default batch is an 'unhandled' legacy type batch that will be drawn with the legacy path, - // all other batches are accelerated. - void _prefill_default_batch(FillState &r_fill_state, int p_command_num, const RendererCanvasRender::Item &p_item); - - // accelerated batches - bool _prefill_rect(RendererCanvasRender::Item::CommandRect *rect, FillState &r_fill_state, int &r_command_start, int command_num, int command_count, RendererCanvasRender::Item::Command *const *commands, RendererCanvasRender::Item *p_item, bool multiply_final_modulate); - - // dealing with textures - int _batch_find_or_create_tex(const RID &p_texture, const RID &p_normal, bool p_tile, int p_previous_match); - -protected: - // legacy support for non batched mode - void _legacy_canvas_item_render_commands(RendererCanvasRender::Item *p_item, RendererCanvasRender::Item *p_current_clip, bool &r_reclip, typename T_STORAGE::Material *p_material); - - // light scissoring - bool _light_scissor_begin(const Rect2 &p_item_rect, const Transform2D &p_light_xform, const Rect2 &p_light_rect) const; - bool _light_find_intersection(const Rect2 &p_item_rect, const Transform2D &p_light_xform, const Rect2 &p_light_rect, Rect2 &r_cliprect) const; - void _calculate_scissor_threshold_area(); - -private: - // translating vertex formats prior to rendering - void _translate_batches_to_vertex_colored_FVF(); - template <class BATCH_VERTEX_TYPE, bool INCLUDE_LIGHT_ANGLES, bool INCLUDE_MODULATE, bool INCLUDE_LARGE> - void _translate_batches_to_larger_FVF(uint32_t p_sequence_batch_type_flags); - -protected: - // accessory funcs - void _software_transform_vertex(BatchVector2 &r_v, const Transform2D &p_tr) const; - void _software_transform_vertex(Vector2 &r_v, const Transform2D &p_tr) const; - TransformMode _find_transform_mode(const Transform2D &p_tr) const { - // decided whether to do translate only for software transform - if ((p_tr.elements[0].x == 1.0f) && - (p_tr.elements[0].y == 0.0f) && - (p_tr.elements[1].x == 0.0f) && - (p_tr.elements[1].y == 1.0f)) { - return TM_TRANSLATE; - } - - return TM_ALL; - } - - typename T_STORAGE::Texture *_get_canvas_texture(const RID &p_texture) const { - if (p_texture.is_valid()) { - typename T_STORAGE::Texture *texture = get_storage()->texture_owner.get_or_null(p_texture); - - if (texture) { - return texture->get_ptr(); - } - } - - return 0; - } - -public: - Batch *_batch_request_new(bool p_blank = true) { - Batch *batch = bdata.batches.request(); - if (!batch) { - // grow the batches - bdata.batches.grow(); - - // and the temporary batches (used for color verts) - bdata.batches_temp.reset(); - bdata.batches_temp.grow(); - - // this should always succeed after growing - batch = bdata.batches.request(); - RAST_DEBUG_ASSERT(batch); - } - - if (p_blank) - memset(batch, 0, sizeof(Batch)); - - return batch; - } - - BatchVertex *_batch_vertex_request_new() { - return bdata.vertices.request(); - } - -protected: - int godot4_commands_count(RendererCanvasRender::Item::Command *p_comm) const { - int count = 0; - while (p_comm) { - count++; - p_comm = p_comm->next; - } - return count; - } - - unsigned int godot4_commands_to_vector(RendererCanvasRender::Item::Command *p_comm, LocalVector<RendererCanvasRender::Item::Command *> &p_list) { - p_list.clear(); - while (p_comm) { - p_list.push_back(p_comm); - p_comm = p_comm->next; - } - return p_list.size(); - } -}; - -PREAMBLE(void)::batch_canvas_begin() { - // diagnose_frame? - bdata.frame_string = ""; // just in case, always set this as we don't want a string leak in release... -#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED) - if (bdata.settings_diagnose_frame) { - bdata.diagnose_frame = false; - - uint32_t tick = OS::get_singleton()->get_ticks_msec(); - uint64_t frame = Engine::get_singleton()->get_frames_drawn(); - - if (tick >= bdata.next_diagnose_tick) { - bdata.next_diagnose_tick = tick + 10000; - - // the plus one is prevent starting diagnosis half way through frame - bdata.diagnose_frame_number = frame + 1; - } - - if (frame == bdata.diagnose_frame_number) { - bdata.diagnose_frame = true; - bdata.reset_stats(); - } - - if (bdata.diagnose_frame) { - bdata.frame_string = "canvas_begin FRAME " + itos(frame) + "\n"; - } - } -#endif -} - -PREAMBLE(void)::batch_canvas_end() { -#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED) - if (bdata.diagnose_frame) { - bdata.frame_string += "canvas_end\n"; - if (bdata.stats_items_sorted) { - bdata.frame_string += "\titems reordered: " + itos(bdata.stats_items_sorted) + "\n"; - } - if (bdata.stats_light_items_joined) { - bdata.frame_string += "\tlight items joined: " + itos(bdata.stats_light_items_joined) + "\n"; - } - - print_line(bdata.frame_string); - } -#endif -} - -PREAMBLE(void)::batch_canvas_render_items_begin(const Color &p_modulate, RendererCanvasRender::Light *p_light, const Transform2D &p_base_transform) { - // if we are debugging, flash each frame between batching renderer and old version to compare for regressions - if (bdata.settings_flash_batching) { - if ((Engine::get_singleton()->get_frames_drawn() % 2) == 0) - bdata.settings_use_batching = true; - else - bdata.settings_use_batching = false; - } - - if (!bdata.settings_use_batching) { - return; - } - - // this only needs to be done when screen size changes, but this should be - // infrequent enough - _calculate_scissor_threshold_area(); - - // set up render item state for all the z_indexes (this is common to all z_indexes) - _render_item_state.reset(); - _render_item_state.item_group_modulate = p_modulate; - _render_item_state.item_group_light = p_light; - _render_item_state.item_group_base_transform = p_base_transform; - _render_item_state.light_region.reset(); - - // batch break must be preserved over the different z indices, - // to prevent joining to an item on a previous index if not allowed - _render_item_state.join_batch_break = false; - - // whether to join across z indices depends on whether there are z ranged lights. - // joined z_index items can be wrongly classified with z ranged lights. - bdata.join_across_z_indices = true; - - int light_count = 0; - while (p_light) { - light_count++; - - if ((p_light->z_min != RS::CANVAS_ITEM_Z_MIN) || (p_light->z_max != RS::CANVAS_ITEM_Z_MAX)) { - // prevent joining across z indices. This would have caused visual regressions - bdata.join_across_z_indices = false; - } - - p_light = p_light->next_ptr; - } - - // can't use the light region bitfield if there are too many lights - // hopefully most games won't blow this limit.. - // if they do they will work but it won't batch join items just in case - if (light_count > 64) { - _render_item_state.light_region.too_many_lights = true; - } -} - -PREAMBLE(void)::batch_canvas_render_items_end() { - if (!bdata.settings_use_batching) { - return; - } - - join_sorted_items(); - -#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED) - if (bdata.diagnose_frame) { - bdata.frame_string += "items\n"; - } -#endif - - // batching render is deferred until after going through all the z_indices, joining all the items - get_this()->canvas_render_items_implementation(0, 0, _render_item_state.item_group_modulate, - _render_item_state.item_group_light, - _render_item_state.item_group_base_transform); - - bdata.items_joined.reset(); - bdata.item_refs.reset(); - bdata.sort_items.reset(); -} - -PREAMBLE(void)::batch_canvas_render_items(RendererCanvasRender::Item *p_item_list, int p_z, const Color &p_modulate, RendererCanvasRender::Light *p_light, const Transform2D &p_base_transform) { - // stage 1 : join similar items, so that their state changes are not repeated, - // and commands from joined items can be batched together - if (bdata.settings_use_batching) { - record_items(p_item_list, p_z); - return; - } - - // only legacy renders at this stage, batched renderer doesn't render until canvas_render_items_end() - get_this()->canvas_render_items_implementation(p_item_list, p_z, p_modulate, p_light, p_base_transform); -} - -// Default batches will not occur in software transform only items -// EXCEPT IN THE CASE OF SINGLE RECTS (and this may well not occur, check the logic in prefill_join_item TYPE_RECT) -// but can occur where transform commands have been sent during hardware batch -PREAMBLE(void)::_prefill_default_batch(FillState &r_fill_state, int p_command_num, const RendererCanvasRender::Item &p_item) { - if (r_fill_state.curr_batch->type == RasterizerStorageCommon::BT_DEFAULT) { - // don't need to flush an extra transform command? - if (!r_fill_state.transform_extra_command_number_p1) { - // another default command, just add to the existing batch - r_fill_state.curr_batch->num_commands++; - } else { -#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED) - if (r_fill_state.transform_extra_command_number_p1 != p_command_num) { - WARN_PRINT_ONCE("_prefill_default_batch : transform_extra_command_number_p1 != p_command_num"); - } -#endif - // if the first member of the batch is a transform we have to be careful - if (!r_fill_state.curr_batch->num_commands) { - // there can be leading useless extra transforms (sometimes happens with debug collision polys) - // we need to rejig the first_command for the first useful transform - r_fill_state.curr_batch->first_command += r_fill_state.transform_extra_command_number_p1 - 1; - } - - // we do have a pending extra transform command to flush - // either the extra transform is in the prior command, or not, in which case we need 2 batches - r_fill_state.curr_batch->num_commands += 2; - - r_fill_state.transform_extra_command_number_p1 = 0; // mark as sent - r_fill_state.extra_matrix_sent = true; - - // the original mode should always be hardware transform .. - // test this assumption - //CRASH_COND(r_fill_state.orig_transform_mode != TM_NONE); - r_fill_state.transform_mode = r_fill_state.orig_transform_mode; - - // do we need to restore anything else? - } - } else { - // end of previous different type batch, so start new default batch - - // first consider whether there is a dirty extra matrix to send - if (r_fill_state.transform_extra_command_number_p1) { - // get which command the extra is in, and blank all the records as it no longer is stored CPU side - int extra_command = r_fill_state.transform_extra_command_number_p1 - 1; // plus 1 based - r_fill_state.transform_extra_command_number_p1 = 0; - r_fill_state.extra_matrix_sent = true; - - // send the extra to the GPU in a batch - r_fill_state.curr_batch = _batch_request_new(); - r_fill_state.curr_batch->type = RasterizerStorageCommon::BT_DEFAULT; - r_fill_state.curr_batch->first_command = extra_command; - r_fill_state.curr_batch->num_commands = 1; - - // revert to the original transform mode - // e.g. go back to NONE if we were in hardware transform mode - r_fill_state.transform_mode = r_fill_state.orig_transform_mode; - - // reset the original transform if we are going back to software mode, - // because the extra is now done on the GPU... - // (any subsequent extras are sent directly to the GPU, no deferring) - if (r_fill_state.orig_transform_mode != TM_NONE) { - r_fill_state.transform_combined = p_item.final_transform; - } - - // can possibly combine batch with the next one in some cases - // this is more efficient than having an extra batch especially for the extra - if ((extra_command + 1) == p_command_num) { - r_fill_state.curr_batch->num_commands = 2; - return; - } - } - - // start default batch - r_fill_state.curr_batch = _batch_request_new(); - r_fill_state.curr_batch->type = RasterizerStorageCommon::BT_DEFAULT; - r_fill_state.curr_batch->first_command = p_command_num; - r_fill_state.curr_batch->num_commands = 1; - } -} - -PREAMBLE(int)::_batch_find_or_create_tex(const RID &p_texture, const RID &p_normal, bool p_tile, int p_previous_match) { - // optimization .. in 99% cases the last matched value will be the same, so no need to traverse the list - if (p_previous_match > 0) // if it is zero, it will get hit first in the linear search anyway - { - const BatchTex &batch_texture = bdata.batch_textures[p_previous_match]; - - // note for future reference, if RID implementation changes, this could become more expensive - if ((batch_texture.RID_texture == p_texture) && (batch_texture.RID_normal == p_normal)) { - // tiling mode must also match - bool tiles = batch_texture.tile_mode != BatchTex::TILE_OFF; - - if (tiles == p_tile) - // match! - return p_previous_match; - } - } - - // not the previous match .. we will do a linear search ... slower, but should happen - // not very often except with non-batchable runs, which are going to be slow anyway - // n.b. could possibly be replaced later by a fast hash table - for (int n = 0; n < bdata.batch_textures.size(); n++) { - const BatchTex &batch_texture = bdata.batch_textures[n]; - if ((batch_texture.RID_texture == p_texture) && (batch_texture.RID_normal == p_normal)) { - // tiling mode must also match - bool tiles = batch_texture.tile_mode != BatchTex::TILE_OFF; - - if (tiles == p_tile) - // match! - return n; - } - } - - // pushing back from local variable .. not ideal but has to use a Vector because non pod - // due to RIDs - BatchTex new_batch_tex; - new_batch_tex.RID_texture = p_texture; - new_batch_tex.RID_normal = p_normal; - - // get the texture - typename T_STORAGE::Texture *texture = _get_canvas_texture(p_texture); - - if (texture) { - // special case, there can be textures with no width or height - int w = texture->width; - int h = texture->height; - - if (!w || !h) { - w = 1; - h = 1; - } - - new_batch_tex.tex_pixel_size.x = 1.0 / w; - new_batch_tex.tex_pixel_size.y = 1.0 / h; - new_batch_tex.flags = texture->flags; - } else { - // maybe doesn't need doing... - new_batch_tex.tex_pixel_size.x = 1.0f; - new_batch_tex.tex_pixel_size.y = 1.0f; - new_batch_tex.flags = 0; - } - - if (p_tile) { - if (texture) { - // default - new_batch_tex.tile_mode = BatchTex::TILE_NORMAL; - - // no hardware support for non power of 2 tiling - if (!get_storage()->config.support_npot_repeat_mipmap) { - if (next_power_of_2(texture->alloc_width) != (unsigned int)texture->alloc_width && next_power_of_2(texture->alloc_height) != (unsigned int)texture->alloc_height) { - new_batch_tex.tile_mode = BatchTex::TILE_FORCE_REPEAT; - } - } - } else { - // this should not happen? - new_batch_tex.tile_mode = BatchTex::TILE_OFF; - } - } else { - new_batch_tex.tile_mode = BatchTex::TILE_OFF; - } - - // push back - bdata.batch_textures.push_back(new_batch_tex); - - return bdata.batch_textures.size() - 1; -} - -PREAMBLE(void)::batch_constructor() { - bdata.settings_use_batching = false; - -#ifdef GLES_OVER_GL - use_nvidia_rect_workaround = GLOBAL_GET("rendering/quality/2d/use_nvidia_rect_flicker_workaround"); -#else - // Not needed (a priori) on GLES devices - use_nvidia_rect_workaround = false; -#endif -} - -PREAMBLE(void)::batch_initialize() { -#define BATCHING_LOAD_PROJECT_SETTINGS - -#ifdef BATCHING_LOAD_PROJECT_SETTINGS - bdata.settings_use_batching = GLOBAL_GET("rendering/batching/options/use_batching"); - bdata.settings_max_join_item_commands = GLOBAL_GET("rendering/batching/parameters/max_join_item_commands"); - bdata.settings_colored_vertex_format_threshold = GLOBAL_GET("rendering/batching/parameters/colored_vertex_format_threshold"); - bdata.settings_item_reordering_lookahead = GLOBAL_GET("rendering/batching/parameters/item_reordering_lookahead"); - bdata.settings_light_max_join_items = GLOBAL_GET("rendering/batching/lights/max_join_items"); - bdata.settings_use_single_rect_fallback = GLOBAL_GET("rendering/batching/options/single_rect_fallback"); - bdata.settings_use_software_skinning = GLOBAL_GET("rendering/quality/2d/use_software_skinning"); - bdata.settings_ninepatch_mode = GLOBAL_GET("rendering/quality/2d/ninepatch_mode"); - - // alternatively only enable uv contract if pixel snap in use, - // but with this enable bool, it should not be necessary - bdata.settings_uv_contract = GLOBAL_GET("rendering/batching/precision/uv_contract"); - bdata.settings_uv_contract_amount = (float)GLOBAL_GET("rendering/batching/precision/uv_contract_amount") / 1000000.0f; - - // we can use the threshold to determine whether to turn scissoring off or on - bdata.settings_scissor_threshold = GLOBAL_GET("rendering/batching/lights/scissor_area_threshold"); -#endif - - if (bdata.settings_scissor_threshold > 0.999f) { - bdata.settings_scissor_lights = false; - } else { - bdata.settings_scissor_lights = true; - - // apply power of 4 relationship for the area, as most of the important changes - // will be happening at low values of scissor threshold - bdata.settings_scissor_threshold *= bdata.settings_scissor_threshold; - bdata.settings_scissor_threshold *= bdata.settings_scissor_threshold; - } - - // The sweet spot on my desktop for cache is actually smaller than the max, and this - // is the default. This saves memory too so we will use it for now, needs testing to see whether this varies according - // to device / platform. -#ifdef BATCHING_LOAD_PROJECT_SETTINGS - bdata.settings_batch_buffer_num_verts = GLOBAL_GET("rendering/batching/parameters/batch_buffer_size"); - - // override the use_batching setting in the editor - // (note that if the editor can't start, you can't change the use_batching project setting!) - if (Engine::get_singleton()->is_editor_hint()) { - bool use_in_editor = GLOBAL_GET("rendering/batching/options/use_batching_in_editor"); - bdata.settings_use_batching = use_in_editor; - - // fix some settings in the editor, as the performance not worth the risk - bdata.settings_use_single_rect_fallback = false; - } -#endif - - // if we are using batching, we will purposefully disable the nvidia workaround. - // This is because the only reason to use the single rect fallback is the approx 2x speed - // of the uniform drawing technique. If we used nvidia workaround, speed would be - // approx equal to the batcher drawing technique (indexed primitive + VB). - if (bdata.settings_use_batching) { - use_nvidia_rect_workaround = false; - } - - // For debugging, if flash is set in project settings, it will flash on alternate frames - // between the non-batched renderer and the batched renderer, - // in order to find regressions. - // This should not be used except during development. - // make a note of the original choice in case we are flashing on and off the batching - bdata.settings_use_batching_original_choice = bdata.settings_use_batching; - -#ifdef BATCHING_LOAD_PROJECT_SETTINGS - bdata.settings_flash_batching = GLOBAL_GET("rendering/batching/debug/flash_batching"); -#endif - if (!bdata.settings_use_batching) { - // no flash when batching turned off - bdata.settings_flash_batching = false; - } - - // frame diagnosis. print out the batches every nth frame - bdata.settings_diagnose_frame = false; - if (!Engine::get_singleton()->is_editor_hint() && bdata.settings_use_batching) { -#ifdef BATCHING_LOAD_PROJECT_SETTINGS - bdata.settings_diagnose_frame = GLOBAL_GET("rendering/batching/debug/diagnose_frame"); -#endif - } - - // the maximum num quads in a batch is limited by GLES2. We can have only 16 bit indices, - // which means we can address a vertex buffer of max size 65535. 4 vertices are needed per quad. - - // Note this determines the memory use by the vertex buffer vector. max quads (65536/4)-1 - // but can be reduced to save memory if really required (will result in more batches though) - const int max_possible_quads = (65536 / 4) - 1; - const int min_possible_quads = 8; // some reasonable small value - - // value from project settings - int max_quads = bdata.settings_batch_buffer_num_verts / 4; - - // sanity checks - max_quads = CLAMP(max_quads, min_possible_quads, max_possible_quads); - bdata.settings_max_join_item_commands = CLAMP(bdata.settings_max_join_item_commands, 0, 65535); - bdata.settings_colored_vertex_format_threshold = CLAMP(bdata.settings_colored_vertex_format_threshold, 0.0f, 1.0f); - bdata.settings_scissor_threshold = CLAMP(bdata.settings_scissor_threshold, 0.0f, 1.0f); - bdata.settings_light_max_join_items = CLAMP(bdata.settings_light_max_join_items, 0, 65535); - bdata.settings_item_reordering_lookahead = CLAMP(bdata.settings_item_reordering_lookahead, 0, 65535); - - // allow user to override the api usage techniques using project settings - // bdata.buffer_mode_batch_upload_send_null = GLOBAL_GET("rendering/options/api_usage_batching/send_null"); - // bdata.buffer_mode_batch_upload_flag_stream = GLOBAL_GET("rendering/options/api_usage_batching/flag_stream"); - - // for debug purposes, output a string with the batching options - String batching_options_string = "OpenGL ES Batching: "; - if (bdata.settings_use_batching) { - batching_options_string += "ON"; - - if (OS::get_singleton()->is_stdout_verbose()) { - batching_options_string += "\n\tOPTIONS\n"; - batching_options_string += "\tmax_join_item_commands " + itos(bdata.settings_max_join_item_commands) + "\n"; - batching_options_string += "\tcolored_vertex_format_threshold " + String(Variant(bdata.settings_colored_vertex_format_threshold)) + "\n"; - batching_options_string += "\tbatch_buffer_size " + itos(bdata.settings_batch_buffer_num_verts) + "\n"; - batching_options_string += "\tlight_scissor_area_threshold " + String(Variant(bdata.settings_scissor_threshold)) + "\n"; - - batching_options_string += "\titem_reordering_lookahead " + itos(bdata.settings_item_reordering_lookahead) + "\n"; - batching_options_string += "\tlight_max_join_items " + itos(bdata.settings_light_max_join_items) + "\n"; - batching_options_string += "\tsingle_rect_fallback " + String(Variant(bdata.settings_use_single_rect_fallback)) + "\n"; - - batching_options_string += "\tdebug_flash " + String(Variant(bdata.settings_flash_batching)) + "\n"; - batching_options_string += "\tdiagnose_frame " + String(Variant(bdata.settings_diagnose_frame)); - } - - print_line(batching_options_string); - } - - // special case, for colored vertex format threshold. - // as the comparison is >=, we want to be able to totally turn on or off - // conversion to colored vertex format at the extremes, so we will force - // 1.0 to be just above 1.0 - if (bdata.settings_colored_vertex_format_threshold > 0.995f) { - bdata.settings_colored_vertex_format_threshold = 1.01f; - } - - // save memory when batching off - if (!bdata.settings_use_batching) { - max_quads = 0; - } - - uint32_t sizeof_batch_vert = sizeof(BatchVertex); - - bdata.max_quads = max_quads; - - // 4 verts per quad - bdata.vertex_buffer_size_units = max_quads * 4; - - // the index buffer can be longer than 65535, only the indices need to be within this range - bdata.index_buffer_size_units = max_quads * 6; - - const int max_verts = bdata.vertex_buffer_size_units; - - // this comes out at approx 64K for non-colored vertex buffer, and 128K for colored vertex buffer - bdata.vertex_buffer_size_bytes = max_verts * sizeof_batch_vert; - bdata.index_buffer_size_bytes = bdata.index_buffer_size_units * 2; // 16 bit inds - - // create equal number of normal and (max) unit sized verts (as the normal may need to be translated to a larger FVF) - bdata.vertices.create(max_verts); // 512k - bdata.unit_vertices.create(max_verts, sizeof(BatchVertexLarge)); - - // extra data per vert needed for larger FVFs - bdata.light_angles.create(max_verts); - bdata.vertex_colors.create(max_verts); - bdata.vertex_modulates.create(max_verts); - bdata.vertex_transforms.create(max_verts); - - // num batches will be auto increased dynamically if required - bdata.batches.create(1024); - bdata.batches_temp.create(bdata.batches.max_size()); - - // batch textures can also be increased dynamically - bdata.batch_textures.create(32); -} - -PREAMBLE(bool)::_light_scissor_begin(const Rect2 &p_item_rect, const Transform2D &p_light_xform, const Rect2 &p_light_rect) const { - float area_item = p_item_rect.size.x * p_item_rect.size.y; // double check these are always positive - - // quick reject .. the area of pixels saved can never be more than the area of the item - if (area_item < bdata.scissor_threshold_area) { - return false; - } - - Rect2 cliprect; - if (!_light_find_intersection(p_item_rect, p_light_xform, p_light_rect, cliprect)) { - // should not really occur .. but just in case - cliprect = Rect2(0, 0, 0, 0); - } else { - // some conditions not to scissor - // determine the area (fill rate) that will be saved - float area_cliprect = cliprect.size.x * cliprect.size.y; - float area_saved = area_item - area_cliprect; - - // if area saved is too small, don't scissor - if (area_saved < bdata.scissor_threshold_area) { - return false; - } - } - - int rh = get_storage()->frame.current_rt->height; - - int y = rh - (cliprect.position.y + cliprect.size.y); - get_this()->gl_enable_scissor(cliprect.position.x, y, cliprect.size.width, cliprect.size.height); - - return true; -} - -PREAMBLE(bool)::_light_find_intersection(const Rect2 &p_item_rect, const Transform2D &p_light_xform, const Rect2 &p_light_rect, Rect2 &r_cliprect) const { - // transform light to world space (note this is done in the earlier intersection test, so could - // be made more efficient) - Vector2 pts[4] = { - p_light_xform.xform(p_light_rect.position), - p_light_xform.xform(Vector2(p_light_rect.position.x + p_light_rect.size.x, p_light_rect.position.y)), - p_light_xform.xform(Vector2(p_light_rect.position.x, p_light_rect.position.y + p_light_rect.size.y)), - p_light_xform.xform(Vector2(p_light_rect.position.x + p_light_rect.size.x, p_light_rect.position.y + p_light_rect.size.y)), - }; - - // calculate the light bound rect in world space - Rect2 lrect(pts[0].x, pts[0].y, 0, 0); - for (int n = 1; n < 4; n++) { - lrect.expand_to(pts[n]); - } - - // intersection between the 2 rects - // they should probably always intersect, because of earlier check, but just in case... - if (!p_item_rect.intersects(lrect)) - return false; - - // note this does almost the same as Rect2.clip but slightly more efficient for our use case - r_cliprect.position.x = MAX(p_item_rect.position.x, lrect.position.x); - r_cliprect.position.y = MAX(p_item_rect.position.y, lrect.position.y); - - Point2 item_rect_end = p_item_rect.position + p_item_rect.size; - Point2 lrect_end = lrect.position + lrect.size; - - r_cliprect.size.x = MIN(item_rect_end.x, lrect_end.x) - r_cliprect.position.x; - r_cliprect.size.y = MIN(item_rect_end.y, lrect_end.y) - r_cliprect.position.y; - - return true; -} - -PREAMBLE(void)::_calculate_scissor_threshold_area() { - if (!bdata.settings_scissor_lights) { - return; - } - - // scissor area threshold is 0.0 to 1.0 in the settings for ease of use. - // we need to translate to an absolute area to determine quickly whether - // to scissor. - if (bdata.settings_scissor_threshold < 0.0001f) { - bdata.scissor_threshold_area = -1.0f; // will always pass - } else { - // in pixels - int w = get_storage()->frame.current_rt->width; - int h = get_storage()->frame.current_rt->height; - - int screen_area = w * h; - - bdata.scissor_threshold_area = bdata.settings_scissor_threshold * screen_area; - } -} - -PREAMBLE(void)::render_joined_item_commands(const BItemJoined &p_bij, RendererCanvasRender::Item *p_current_clip, bool &r_reclip, typename T_STORAGE::Material *p_material, bool p_lit) { - RendererCanvasRender::Item *item = 0; - RendererCanvasRender::Item *first_item = bdata.item_refs[p_bij.first_item_ref].item; - - // fill_state and bdata have once off setup per joined item, and a smaller reset on flush - FillState fill_state; - fill_state.reset_joined_item(p_bij.use_hardware_transform()); - - bdata.reset_joined_item(); - - // should this joined item be using large FVF? - if (p_bij.flags & RasterizerStorageCommon::USE_MODULATE_FVF) { - bdata.use_modulate = true; - bdata.fvf = RasterizerStorageCommon::FVF_MODULATED; - } - if (p_bij.flags & RasterizerStorageCommon::USE_LARGE_FVF) { - bdata.use_modulate = true; - bdata.use_large_verts = true; - bdata.fvf = RasterizerStorageCommon::FVF_LARGE; - } - - // in the special case of custom shaders that read from VERTEX (i.e. vertex position) - // we want to disable software transform of extra matrix - if (bdata.joined_item_batch_flags & RasterizerStorageCommon::PREVENT_VERTEX_BAKING) { - fill_state.extra_matrix_sent = true; - } - - for (unsigned int i = 0; i < p_bij.num_item_refs; i++) { - const BItemRef &ref = bdata.item_refs[p_bij.first_item_ref + i]; - item = ref.item; - - if (!p_lit) { - // if not lit we use the complex calculated final modulate - fill_state.final_modulate = ref.final_modulate; - } else { - // if lit we ignore canvas modulate and just use the item modulate - fill_state.final_modulate = item->final_modulate; - } - - // ONCE OFF fill state setup, that will be retained over multiple calls to - // prefill_joined_item() - fill_state.transform_combined = item->final_transform; - - // decide the initial transform mode, and make a backup - // in orig_transform_mode in case we need to switch back - if (!fill_state.use_hardware_transform) { - fill_state.transform_mode = _find_transform_mode(fill_state.transform_combined); - } else { - fill_state.transform_mode = TM_NONE; - } - fill_state.orig_transform_mode = fill_state.transform_mode; - - // keep track of when we added an extra matrix - // so we can defer sending until we see a default command - fill_state.transform_extra_command_number_p1 = 0; - - RendererCanvasRender::Item::Command *current_command = item->commands; - while (current_command) { - // fill as many batches as possible (until all done, or the vertex buffer is full) - bool bFull = get_this()->prefill_joined_item(fill_state, current_command, item, p_current_clip, r_reclip, p_material); - - if (bFull) { - // always pass first item (commands for default are always first item) - flush_render_batches(first_item, p_current_clip, r_reclip, p_material, fill_state.sequence_batch_type_flags); - - // zero all the batch data ready for a new run - bdata.reset_flush(); - - // don't zero all the fill state, some may need to be preserved - fill_state.reset_flush(); - } - } - } - - // flush if any left - flush_render_batches(first_item, p_current_clip, r_reclip, p_material, fill_state.sequence_batch_type_flags); - - // zero all the batch data ready for a new run - bdata.reset_flush(); -} - -PREAMBLE(void)::_legacy_canvas_item_render_commands(RendererCanvasRender::Item *p_item, RendererCanvasRender::Item *p_current_clip, bool &r_reclip, typename T_STORAGE::Material *p_material) { - // reuse the same list each time to prevent needless dynamic allocations - unsigned int command_count = godot4_commands_to_vector(p_item->commands, bdata.command_shortlist); - RendererCanvasRender::Item::Command *const *commands = nullptr; - if (command_count) { - commands = &bdata.command_shortlist[0]; - } - - // legacy .. just create one massive batch and render everything as before - bdata.batches.reset(); - Batch *batch = _batch_request_new(); - batch->type = RasterizerStorageCommon::BT_DEFAULT; - batch->num_commands = command_count; - - get_this()->render_batches(commands, p_current_clip, r_reclip, p_material); - bdata.reset_flush(); -} - -PREAMBLE(void)::record_items(RendererCanvasRender::Item *p_item_list, int p_z) { - while (p_item_list) { - BSortItem *s = bdata.sort_items.request_with_grow(); - - s->item = p_item_list; - s->z_index = p_z; - - p_item_list = p_item_list->next; - } -} - -PREAMBLE(void)::join_sorted_items() { -} - -PREAMBLE(void)::_software_transform_vertex(BatchVector2 &r_v, const Transform2D &p_tr) const { - Vector2 vc(r_v.x, r_v.y); - vc = p_tr.xform(vc); - r_v.set(vc); -} - -PREAMBLE(void)::_software_transform_vertex(Vector2 &r_v, const Transform2D &p_tr) const { - r_v = p_tr.xform(r_v); -} - -PREAMBLE(void)::_translate_batches_to_vertex_colored_FVF() { - // zeros the size and sets up how big each unit is - bdata.unit_vertices.prepare(sizeof(BatchVertexColored)); - - const BatchColor *source_vertex_colors = &bdata.vertex_colors[0]; - RAST_DEBUG_ASSERT(bdata.vertex_colors.size() == bdata.vertices.size()); - - int num_verts = bdata.vertices.size(); - - for (int n = 0; n < num_verts; n++) { - const BatchVertex &bv = bdata.vertices[n]; - - BatchVertexColored *cv = (BatchVertexColored *)bdata.unit_vertices.request(); - - cv->pos = bv.pos; - cv->uv = bv.uv; - cv->col = *source_vertex_colors++; - } -} - -// Translation always involved adding color to the FVF, which enables -// joining of batches that have different colors. -// There is a trade off. Non colored verts are smaller so work faster, but -// there comes a point where it is better to just use colored verts to avoid lots of -// batches. -// In addition this can optionally add light angles to the FVF, necessary for normal mapping. -T_PREAMBLE -template <class BATCH_VERTEX_TYPE, bool INCLUDE_LIGHT_ANGLES, bool INCLUDE_MODULATE, bool INCLUDE_LARGE> -void C_PREAMBLE::_translate_batches_to_larger_FVF(uint32_t p_sequence_batch_type_flags) { - bool include_poly_color = false; - - // we ONLY want to include the color verts in translation when using polys, - // as rects do not write vertex colors, only colors per batch. - if (p_sequence_batch_type_flags & RasterizerStorageCommon::BTF_POLY) { - include_poly_color = INCLUDE_LIGHT_ANGLES | INCLUDE_MODULATE | INCLUDE_LARGE; - } - - // zeros the size and sets up how big each unit is - bdata.unit_vertices.prepare(sizeof(BATCH_VERTEX_TYPE)); - bdata.batches_temp.reset(); - - // As the vertices_colored and batches_temp are 'mirrors' of the non-colored version, - // the sizes should be equal, and allocations should never fail. Hence the use of debug - // asserts to check program flow, these should not occur at runtime unless the allocation - // code has been altered. - RAST_DEBUG_ASSERT(bdata.unit_vertices.max_size() == bdata.vertices.max_size()); - RAST_DEBUG_ASSERT(bdata.batches_temp.max_size() == bdata.batches.max_size()); - - Color curr_col(-1.0f, -1.0f, -1.0f, -1.0f); - - Batch *dest_batch = nullptr; - - const BatchColor *source_vertex_colors = &bdata.vertex_colors[0]; - const float *source_light_angles = &bdata.light_angles[0]; - const BatchColor *source_vertex_modulates = &bdata.vertex_modulates[0]; - const BatchTransform *source_vertex_transforms = &bdata.vertex_transforms[0]; - - // translate the batches into vertex colored batches - for (int n = 0; n < bdata.batches.size(); n++) { - const Batch &source_batch = bdata.batches[n]; - - // does source batch use light angles? - const BatchTex &btex = bdata.batch_textures[source_batch.batch_texture_id]; - bool source_batch_uses_light_angles = btex.RID_normal != RID(); - - bool needs_new_batch = true; - - if (dest_batch) { - if (dest_batch->type == source_batch.type) { - if (source_batch.type == RasterizerStorageCommon::BT_RECT) { - if (dest_batch->batch_texture_id == source_batch.batch_texture_id) { - // add to previous batch - dest_batch->num_commands += source_batch.num_commands; - needs_new_batch = false; - - // create the colored verts (only if not default) - //int first_vert = source_batch.first_quad * 4; - //int end_vert = 4 * (source_batch.first_quad + source_batch.num_commands); - int first_vert = source_batch.first_vert; - int end_vert = first_vert + (4 * source_batch.num_commands); - - for (int v = first_vert; v < end_vert; v++) { - RAST_DEV_DEBUG_ASSERT(bdata.vertices.size()); - const BatchVertex &bv = bdata.vertices[v]; - BATCH_VERTEX_TYPE *cv = (BATCH_VERTEX_TYPE *)bdata.unit_vertices.request(); - RAST_DEBUG_ASSERT(cv); - cv->pos = bv.pos; - cv->uv = bv.uv; - cv->col = source_batch.color; - - if (INCLUDE_LIGHT_ANGLES) { - RAST_DEV_DEBUG_ASSERT(bdata.light_angles.size()); - // this is required to allow compilation with non light angle vertex. - // it should be compiled out. - BatchVertexLightAngled *lv = (BatchVertexLightAngled *)cv; - if (source_batch_uses_light_angles) - lv->light_angle = *source_light_angles++; - else - lv->light_angle = 0.0f; // dummy, unused in vertex shader (could possibly be left uninitialized, but probably bad idea) - } // if including light angles - - if (INCLUDE_MODULATE) { - RAST_DEV_DEBUG_ASSERT(bdata.vertex_modulates.size()); - BatchVertexModulated *mv = (BatchVertexModulated *)cv; - mv->modulate = *source_vertex_modulates++; - } // including modulate - - if (INCLUDE_LARGE) { - RAST_DEV_DEBUG_ASSERT(bdata.vertex_transforms.size()); - BatchVertexLarge *lv = (BatchVertexLarge *)cv; - lv->transform = *source_vertex_transforms++; - } // if including large - } - } // textures match - } else { - // default - // we can still join, but only under special circumstances - // does this ever happen? not sure at this stage, but left for future expansion - uint32_t source_last_command = source_batch.first_command + source_batch.num_commands; - if (source_last_command == dest_batch->first_command) { - dest_batch->num_commands += source_batch.num_commands; - needs_new_batch = false; - } // if the commands line up exactly - } - } // if both batches are the same type - - } // if dest batch is valid - - if (needs_new_batch) { - dest_batch = bdata.batches_temp.request(); - RAST_DEBUG_ASSERT(dest_batch); - - *dest_batch = source_batch; - - // create the colored verts (only if not default) - if (source_batch.type != RasterizerStorageCommon::BT_DEFAULT) { - // int first_vert = source_batch.first_quad * 4; - // int end_vert = 4 * (source_batch.first_quad + source_batch.num_commands); - int first_vert = source_batch.first_vert; - int end_vert = first_vert + (4 * source_batch.num_commands); - - for (int v = first_vert; v < end_vert; v++) { - RAST_DEV_DEBUG_ASSERT(bdata.vertices.size()); - const BatchVertex &bv = bdata.vertices[v]; - BATCH_VERTEX_TYPE *cv = (BATCH_VERTEX_TYPE *)bdata.unit_vertices.request(); - RAST_DEBUG_ASSERT(cv); - cv->pos = bv.pos; - cv->uv = bv.uv; - - // polys are special, they can have per vertex colors - if (!include_poly_color) { - cv->col = source_batch.color; - } else { - RAST_DEV_DEBUG_ASSERT(bdata.vertex_colors.size()); - cv->col = *source_vertex_colors++; - } - - if (INCLUDE_LIGHT_ANGLES) { - RAST_DEV_DEBUG_ASSERT(bdata.light_angles.size()); - // this is required to allow compilation with non light angle vertex. - // it should be compiled out. - BatchVertexLightAngled *lv = (BatchVertexLightAngled *)cv; - if (source_batch_uses_light_angles) - lv->light_angle = *source_light_angles++; - else - lv->light_angle = 0.0f; // dummy, unused in vertex shader (could possibly be left uninitialized, but probably bad idea) - } // if using light angles - - if (INCLUDE_MODULATE) { - RAST_DEV_DEBUG_ASSERT(bdata.vertex_modulates.size()); - BatchVertexModulated *mv = (BatchVertexModulated *)cv; - mv->modulate = *source_vertex_modulates++; - } // including modulate - - if (INCLUDE_LARGE) { - RAST_DEV_DEBUG_ASSERT(bdata.vertex_transforms.size()); - BatchVertexLarge *lv = (BatchVertexLarge *)cv; - lv->transform = *source_vertex_transforms++; - } // if including large - } - } - } - } - - // copy the temporary batches to the master batch list (this could be avoided but it makes the code cleaner) - bdata.batches.copy_from(bdata.batches_temp); -} - -PREAMBLE(bool)::_disallow_item_join_if_batch_types_too_different(RenderItemState &r_ris, uint32_t btf_allowed) { - r_ris.joined_item_batch_type_flags_curr |= btf_allowed; - - bool disallow = false; - - if (r_ris.joined_item_batch_type_flags_prev & (~btf_allowed)) - disallow = true; - - return disallow; -} - -#undef PREAMBLE -#undef T_PREAMBLE -#undef C_PREAMBLE - -#endif // RASTERIZER_CANVAS_BATCHER_H diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 686910e1c6..270725ee63 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -29,17 +29,20 @@ /*************************************************************************/ #include "rasterizer_canvas_gles3.h" -#include "drivers/gles3/rasterizer_platforms.h" -#ifdef GLES3_BACKEND_ENABLED + +#ifdef GLES3_ENABLED #include "core/os/os.h" -#include "drivers/gles3/rasterizer_asserts.h" #include "rasterizer_scene_gles3.h" #include "rasterizer_storage_gles3.h" #include "core/config/project_settings.h" #include "servers/rendering/rendering_server_default.h" +#ifndef GLES_OVER_GL +#define glClearDepth glClearDepthf +#endif + //static const GLenum gl_primitive[] = { // GL_POINTS, // GL_LINES, @@ -50,1660 +53,1417 @@ // GL_TRIANGLE_FAN //}; -#if 0 -void RasterizerCanvasGLES3::_batch_upload_buffers() { - // noop? - if (!bdata.vertices.size()) - return; +void RasterizerCanvasGLES3::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) { + p_mat4[0] = p_transform.elements[0][0]; + p_mat4[1] = p_transform.elements[0][1]; + p_mat4[2] = 0; + p_mat4[3] = 0; + p_mat4[4] = p_transform.elements[1][0]; + p_mat4[5] = p_transform.elements[1][1]; + p_mat4[6] = 0; + p_mat4[7] = 0; + p_mat4[8] = 0; + p_mat4[9] = 0; + p_mat4[10] = 1; + p_mat4[11] = 0; + p_mat4[12] = p_transform.elements[2][0]; + p_mat4[13] = p_transform.elements[2][1]; + p_mat4[14] = 0; + p_mat4[15] = 1; +} - glBindBuffer(GL_ARRAY_BUFFER, bdata.gl_vertex_buffer); +void RasterizerCanvasGLES3::_update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4) { + p_mat2x4[0] = p_transform.elements[0][0]; + p_mat2x4[1] = p_transform.elements[1][0]; + p_mat2x4[2] = 0; + p_mat2x4[3] = p_transform.elements[2][0]; - // usage flag is a project setting - GLenum buffer_usage_flag = GL_DYNAMIC_DRAW; - if (bdata.buffer_mode_batch_upload_flag_stream) { - buffer_usage_flag = GL_STREAM_DRAW; - } - - // orphan the old (for now) - if (bdata.buffer_mode_batch_upload_send_null) { - glBufferData(GL_ARRAY_BUFFER, 0, 0, buffer_usage_flag); // GL_DYNAMIC_DRAW); - } + p_mat2x4[4] = p_transform.elements[0][1]; + p_mat2x4[5] = p_transform.elements[1][1]; + p_mat2x4[6] = 0; + p_mat2x4[7] = p_transform.elements[2][1]; +} - switch (bdata.fvf) { - case RasterizerStorageCommon::FVF_UNBATCHED: // should not happen - break; - case RasterizerStorageCommon::FVF_REGULAR: // no change - glBufferData(GL_ARRAY_BUFFER, sizeof(BatchVertex) * bdata.vertices.size(), bdata.vertices.get_data(), buffer_usage_flag); - break; - case RasterizerStorageCommon::FVF_COLOR: - glBufferData(GL_ARRAY_BUFFER, sizeof(BatchVertexColored) * bdata.unit_vertices.size(), bdata.unit_vertices.get_unit(0), buffer_usage_flag); - break; - case RasterizerStorageCommon::FVF_LIGHT_ANGLE: - glBufferData(GL_ARRAY_BUFFER, sizeof(BatchVertexLightAngled) * bdata.unit_vertices.size(), bdata.unit_vertices.get_unit(0), buffer_usage_flag); - break; - case RasterizerStorageCommon::FVF_MODULATED: - glBufferData(GL_ARRAY_BUFFER, sizeof(BatchVertexModulated) * bdata.unit_vertices.size(), bdata.unit_vertices.get_unit(0), buffer_usage_flag); - break; - case RasterizerStorageCommon::FVF_LARGE: - glBufferData(GL_ARRAY_BUFFER, sizeof(BatchVertexLarge) * bdata.unit_vertices.size(), bdata.unit_vertices.get_unit(0), buffer_usage_flag); - break; - } +void RasterizerCanvasGLES3::_update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3) { + p_mat2x3[0] = p_transform.elements[0][0]; + p_mat2x3[1] = p_transform.elements[0][1]; + p_mat2x3[2] = p_transform.elements[1][0]; + p_mat2x3[3] = p_transform.elements[1][1]; + p_mat2x3[4] = p_transform.elements[2][0]; + p_mat2x3[5] = p_transform.elements[2][1]; +} - // might not be necessary - glBindBuffer(GL_ARRAY_BUFFER, 0); +void RasterizerCanvasGLES3::_update_transform_to_mat4(const Transform3D &p_transform, float *p_mat4) { + p_mat4[0] = p_transform.basis.elements[0][0]; + p_mat4[1] = p_transform.basis.elements[1][0]; + p_mat4[2] = p_transform.basis.elements[2][0]; + p_mat4[3] = 0; + p_mat4[4] = p_transform.basis.elements[0][1]; + p_mat4[5] = p_transform.basis.elements[1][1]; + p_mat4[6] = p_transform.basis.elements[2][1]; + p_mat4[7] = 0; + p_mat4[8] = p_transform.basis.elements[0][2]; + p_mat4[9] = p_transform.basis.elements[1][2]; + p_mat4[10] = p_transform.basis.elements[2][2]; + p_mat4[11] = 0; + p_mat4[12] = p_transform.origin.x; + p_mat4[13] = p_transform.origin.y; + p_mat4[14] = p_transform.origin.z; + p_mat4[15] = 1; } -void RasterizerCanvasGLES3::_batch_render_lines(const Batch &p_batch, RasterizerStorageGLES3::Material *p_material, bool p_anti_alias) { - _set_texture_rect_mode(false); +void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) { + storage->frame.current_rt = nullptr; - if (state.canvas_shader.bind()) { - _set_uniforms(); - state.canvas_shader.use_material((void *)p_material); - } + storage->_set_current_render_target(p_to_render_target); - _bind_canvas_texture(RID(), RID()); + Transform2D canvas_transform_inverse = p_canvas_transform.affine_inverse(); - glDisableVertexAttribArray(RS::ARRAY_COLOR); - glVertexAttrib4fv(RS::ARRAY_COLOR, (float *)&p_batch.color); + // TODO: Setup Directional Lights -#ifdef GLES_OVER_GL - if (p_anti_alias) - glEnable(GL_LINE_SMOOTH); -#endif + // TODO: Setup lights - int sizeof_vert = sizeof(BatchVertex); + { + //update canvas state uniform buffer + StateBuffer state_buffer; - // bind the index and vertex buffer - glBindBuffer(GL_ARRAY_BUFFER, bdata.gl_vertex_buffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bdata.gl_index_buffer); + Size2i ssize = storage->render_target_get_size(p_to_render_target); - uint64_t pointer = 0; - glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof_vert, (const void *)pointer); + Transform3D screen_transform; + screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); + screen_transform.scale(Vector3(2.0f / ssize.width, 2.0f / ssize.height, 1.0f)); + _update_transform_to_mat4(screen_transform, state_buffer.screen_transform); + _update_transform_2d_to_mat4(p_canvas_transform, state_buffer.canvas_transform); - glDisableVertexAttribArray(RS::ARRAY_TEX_UV); + Transform2D normal_transform = p_canvas_transform; + normal_transform.elements[0].normalize(); + normal_transform.elements[1].normalize(); + normal_transform.elements[2] = Vector2(); + _update_transform_2d_to_mat4(normal_transform, state_buffer.canvas_normal_transform); - int64_t offset = p_batch.first_vert; // 6 inds per quad at 2 bytes each + state_buffer.canvas_modulate[0] = p_modulate.r; + state_buffer.canvas_modulate[1] = p_modulate.g; + state_buffer.canvas_modulate[2] = p_modulate.b; + state_buffer.canvas_modulate[3] = p_modulate.a; - int num_elements = p_batch.num_commands * 2; - glDrawArrays(GL_LINES, offset, num_elements); + Size2 render_target_size = storage->render_target_get_size(p_to_render_target); + state_buffer.screen_pixel_size[0] = 1.0 / render_target_size.x; + state_buffer.screen_pixel_size[1] = 1.0 / render_target_size.y; - storage->info.render._2d_draw_call_count++; + state_buffer.time = storage->frame.time; + state_buffer.use_pixel_snap = p_snap_2d_vertices_to_pixel; - // may not be necessary .. state change optimization still TODO - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + state_buffer.directional_light_count = 0; //directional_light_count; -#ifdef GLES_OVER_GL - if (p_anti_alias) - glDisable(GL_LINE_SMOOTH); -#endif -} + Vector2 canvas_scale = p_canvas_transform.get_scale(); -void RasterizerCanvasGLES3::_batch_render_generic(const Batch &p_batch, RasterizerStorageGLES3::Material *p_material) { - ERR_FAIL_COND(p_batch.num_commands <= 0); - - const bool &use_light_angles = bdata.use_light_angles; - const bool &use_modulate = bdata.use_modulate; - const bool &use_large_verts = bdata.use_large_verts; - const bool &colored_verts = bdata.use_colored_vertices | use_light_angles | use_modulate | use_large_verts; - - int sizeof_vert; - - switch (bdata.fvf) { - default: - sizeof_vert = 0; // prevent compiler warning - this should never happen - break; - case RasterizerStorageCommon::FVF_UNBATCHED: { - sizeof_vert = 0; // prevent compiler warning - this should never happen - return; - } break; - case RasterizerStorageCommon::FVF_REGULAR: // no change - sizeof_vert = sizeof(BatchVertex); - break; - case RasterizerStorageCommon::FVF_COLOR: - sizeof_vert = sizeof(BatchVertexColored); - break; - case RasterizerStorageCommon::FVF_LIGHT_ANGLE: - sizeof_vert = sizeof(BatchVertexLightAngled); - break; - case RasterizerStorageCommon::FVF_MODULATED: - sizeof_vert = sizeof(BatchVertexModulated); - break; - case RasterizerStorageCommon::FVF_LARGE: - sizeof_vert = sizeof(BatchVertexLarge); - break; - } + state_buffer.sdf_to_screen[0] = render_target_size.width / canvas_scale.x; + state_buffer.sdf_to_screen[1] = render_target_size.height / canvas_scale.y; - // make sure to set all conditionals BEFORE binding the shader - _set_texture_rect_mode(false, use_light_angles, use_modulate, use_large_verts); + state_buffer.screen_to_sdf[0] = 1.0 / state_buffer.sdf_to_screen[0]; + state_buffer.screen_to_sdf[1] = 1.0 / state_buffer.sdf_to_screen[1]; - // batch tex - const BatchTex &tex = bdata.batch_textures[p_batch.batch_texture_id]; - //VSG::rasterizer->gl_check_for_error(); + Rect2 sdf_rect = storage->render_target_get_sdf_rect(p_to_render_target); + Rect2 sdf_tex_rect(sdf_rect.position / canvas_scale, sdf_rect.size / canvas_scale); - // force repeat is set if non power of 2 texture, and repeat is needed if hardware doesn't support npot - if (tex.tile_mode == BatchTex::TILE_FORCE_REPEAT) { - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_FORCE_REPEAT, true); - } + state_buffer.sdf_to_tex[0] = 1.0 / sdf_tex_rect.size.width; + state_buffer.sdf_to_tex[1] = 1.0 / sdf_tex_rect.size.height; + state_buffer.sdf_to_tex[2] = -sdf_tex_rect.position.x / sdf_tex_rect.size.width; + state_buffer.sdf_to_tex[3] = -sdf_tex_rect.position.y / sdf_tex_rect.size.height; - if (state.canvas_shader.bind()) { - _set_uniforms(); - state.canvas_shader.use_material((void *)p_material); + //print_line("w: " + itos(ssize.width) + " s: " + rtos(canvas_scale)); + state_buffer.tex_to_sdf = 1.0 / ((canvas_scale.x + canvas_scale.y) * 0.5); + glBindBufferBase(GL_UNIFORM_BUFFER, 0, state.canvas_state_buffer); + glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), &state_buffer, GL_STREAM_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, 0); } - _bind_canvas_texture(tex.RID_texture, tex.RID_normal); - - // bind the index and vertex buffer - glBindBuffer(GL_ARRAY_BUFFER, bdata.gl_vertex_buffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bdata.gl_index_buffer); + { + state.default_filter = p_default_filter; + state.default_repeat = p_default_repeat; + } - uint64_t pointer = 0; - glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof_vert, (const void *)pointer); + state.current_tex = RID(); + state.current_tex_ptr = NULL; + state.current_normal = RID(); + state.current_specular = RID(); + state.canvas_texscreen_used = false; - // always send UVs, even within a texture specified because a shader can still use UVs - glEnableVertexAttribArray(RS::ARRAY_TEX_UV); - glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof_vert, CAST_INT_TO_UCHAR_PTR(pointer + (2 * 4))); + r_sdf_used = false; + int item_count = 0; - // color - if (!colored_verts) { - glDisableVertexAttribArray(RS::ARRAY_COLOR); - glVertexAttrib4fv(RS::ARRAY_COLOR, p_batch.color.get_data()); - } else { - glEnableVertexAttribArray(RS::ARRAY_COLOR); - glVertexAttribPointer(RS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof_vert, CAST_INT_TO_UCHAR_PTR(pointer + (4 * 4))); - } - - if (use_light_angles) { - glEnableVertexAttribArray(RS::ARRAY_TANGENT); - glVertexAttribPointer(RS::ARRAY_TANGENT, 1, GL_FLOAT, GL_FALSE, sizeof_vert, CAST_INT_TO_UCHAR_PTR(pointer + (8 * 4))); - } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); + Item *ci = p_item_list; + while (ci) { + // just add all items for now + items[item_count++] = ci; + + if (!ci->next || item_count == MAX_RENDER_ITEMS - 1) { + _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list); + //then reset + item_count = 0; + } - if (use_modulate) { - glEnableVertexAttribArray(RS::ARRAY_TEX_UV2); - glVertexAttribPointer(RS::ARRAY_TEX_UV2, 4, GL_FLOAT, GL_FALSE, sizeof_vert, CAST_INT_TO_UCHAR_PTR(pointer + (9 * 4))); + ci = ci->next; } +} - if (use_large_verts) { - glEnableVertexAttribArray(RS::ARRAY_BONES); - glVertexAttribPointer(RS::ARRAY_BONES, 2, GL_FLOAT, GL_FALSE, sizeof_vert, CAST_INT_TO_UCHAR_PTR(pointer + (13 * 4))); - glEnableVertexAttribArray(RS::ARRAY_WEIGHTS); - glVertexAttribPointer(RS::ARRAY_WEIGHTS, 4, GL_FLOAT, GL_FALSE, sizeof_vert, CAST_INT_TO_UCHAR_PTR(pointer + (15 * 4))); - } +void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer) { + Item *current_clip = nullptr; - // We only want to set the GL wrapping mode if the texture is not already tiled (i.e. set in Import). - // This is an optimization left over from the legacy renderer. - // If we DID set tiling in the API, and reverted to clamped, then the next draw using this texture - // may use clamped mode incorrectly. - bool tex_is_already_tiled = tex.flags & RasterizerStorageGLES3::TEXTURE_FLAG_REPEAT; - - if (tex.tile_mode == BatchTex::TILE_NORMAL) { - // if the texture is imported as tiled, no need to set GL state, as it will already be bound with repeat - if (!tex_is_already_tiled) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - } - } + Transform2D canvas_transform_inverse = p_canvas_transform_inverse; - // we need to convert explicitly from pod Vec2 to Vector2 ... - // could use a cast but this might be unsafe in future - Vector2 tps; - tex.tex_pixel_size.to(tps); - state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, tps); - - switch (p_batch.type) { - default: { - // prevent compiler warning - } break; - case RasterizerStorageCommon::BT_RECT: { - int64_t offset = p_batch.first_vert * 3; - - int num_elements = p_batch.num_commands * 6; - glDrawElements(GL_TRIANGLES, num_elements, GL_UNSIGNED_SHORT, (void *)offset); - } break; - case RasterizerStorageCommon::BT_POLY: { - int64_t offset = p_batch.first_vert; - - int num_elements = p_batch.num_commands; - glDrawArrays(GL_TRIANGLES, offset, num_elements); - } break; - } + RID framebuffer; + Vector<Color> clear_colors; - storage->info.render._2d_draw_call_count++; - - switch (tex.tile_mode) { - case BatchTex::TILE_FORCE_REPEAT: { - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_FORCE_REPEAT, false); - } break; - case BatchTex::TILE_NORMAL: { - // if the texture is imported as tiled, no need to revert GL state - if (!tex_is_already_tiled) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - } break; - default: { - } break; - } + canvas_begin(); - // could these have ifs? - glDisableVertexAttribArray(RS::ARRAY_TEX_UV); - glDisableVertexAttribArray(RS::ARRAY_COLOR); - glDisableVertexAttribArray(RS::ARRAY_TANGENT); - glDisableVertexAttribArray(RS::ARRAY_TEX_UV2); - glDisableVertexAttribArray(RS::ARRAY_BONES); - glDisableVertexAttribArray(RS::ARRAY_WEIGHTS); + RID prev_material; + uint32_t index = 0; - // may not be necessary .. state change optimization still TODO - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -} -#endif -void RasterizerCanvasGLES3::render_batches(Item::Command *const *p_commands, Item *p_current_clip, bool &r_reclip, RasterizerStorageGLES3::Material *p_material) { - int num_batches = bdata.batches.size(); + for (int i = 0; i < p_item_count; i++) { + Item *ci = items[i]; - for (int batch_num = 0; batch_num < num_batches; batch_num++) { - const Batch &batch = bdata.batches[batch_num]; + RID material = ci->material_owner == nullptr ? ci->material : ci->material_owner->material; + RasterizerStorageGLES3::Material *material_ptr = storage->material_owner.get_or_null(material); - switch (batch.type) { - case RasterizerStorageCommon::BT_RECT: { - //_batch_render_generic(batch, p_material); - } break; - case RasterizerStorageCommon::BT_POLY: { - //_batch_render_generic(batch, p_material); - } break; - case RasterizerStorageCommon::BT_LINE: { - //_batch_render_lines(batch, p_material, false); - } break; - case RasterizerStorageCommon::BT_LINE_AA: { - //_batch_render_lines(batch, p_material, true); - } break; - default: { - int end_command = batch.first_command + batch.num_commands; + if (material.is_null() && ci->canvas_group != nullptr) { + material = default_canvas_group_material; + } - for (int i = batch.first_command; i < end_command; i++) { - Item::Command *command = p_commands[i]; + if (material != prev_material) { + RasterizerStorageGLES3::Shader *shader_ptr = NULL; - switch (command->type) { -#if 0 - case Item::Command::TYPE_LINE: { - Item::CommandLine *line = static_cast<Item::CommandLine *>(command); + if (material_ptr) { + shader_ptr = material_ptr->shader; - _set_texture_rect_mode(false); + if (shader_ptr && shader_ptr->mode != RS::SHADER_CANVAS_ITEM) { + shader_ptr = NULL; // not a canvas item shader, don't use. + } + } - if (state.canvas_shader.bind()) { - _set_uniforms(); - state.canvas_shader.use_material((void *)p_material); - } + if (shader_ptr) { + if (true) { //check that shader has changed + if (shader_ptr->canvas_item.uses_time) { + RenderingServerDefault::redraw_request(); + } + //state.canvas_shader.version_bind_shader(shader_ptr->version, CanvasShaderGLES3::MODE_QUAD); + state.current_shader_version = shader_ptr->version; + } - _bind_canvas_texture(RID(), RID()); + int tc = material_ptr->textures.size(); + Pair<StringName, RID> *textures = material_ptr->textures.ptrw(); + + ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_ptr->texture_uniforms.ptrw(); + + for (int ti = 0; ti < tc; i++) { + glActiveTexture(GL_TEXTURE0 + ti); + + RasterizerStorageGLES3::Texture *t = storage->texture_owner.get_or_null(textures[ti].second); + + if (!t) { + switch (texture_uniforms[i].hint) { + case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO: + case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: { + glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex); + } break; + case ShaderLanguage::ShaderNode::Uniform::HINT_ANISOTROPY: { + glBindTexture(GL_TEXTURE_2D, storage->resources.aniso_tex); + } break; + case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: { + glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex); + } break; + default: { + glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); + } break; + } + + continue; + } - glDisableVertexAttribArray(RS::ARRAY_COLOR); - glVertexAttrib4fv(RS::ARRAY_COLOR, line->color.components); + //Set texture filter and repeat texture_uniforms[i].filter texture_uniforms[i].repeat - state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix); + if (t->redraw_if_visible) { + RenderingServerDefault::redraw_request(); + } - if (line->width <= 1) { - Vector2 verts[2] = { - Vector2(line->from.x, line->from.y), - Vector2(line->to.x, line->to.y) - }; + t = t->get_ptr(); -#ifdef GLES_OVER_GL - if (line->antialiased) - glEnable(GL_LINE_SMOOTH); +#ifdef TOOLS_ENABLED + if (t->detect_normal && texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL) { + t->detect_normal(t->detect_normal_ud); + } #endif - _draw_gui_primitive(2, verts, NULL, NULL); + if (t->render_target) + t->render_target->used_in_frame = true; -#ifdef GLES_OVER_GL - if (line->antialiased) - glDisable(GL_LINE_SMOOTH); -#endif - } else { - Vector2 t = (line->from - line->to).normalized().tangent() * line->width * 0.5; - - Vector2 verts[4] = { - line->from - t, - line->from + t, - line->to + t, - line->to - t - }; - - _draw_gui_primitive(4, verts, NULL, NULL); -#ifdef GLES_OVER_GL - if (line->antialiased) { - glEnable(GL_LINE_SMOOTH); - for (int j = 0; j < 4; j++) { - Vector2 vertsl[2] = { - verts[j], - verts[(j + 1) % 4], - }; - _draw_gui_primitive(2, vertsl, NULL, NULL); - } - glDisable(GL_LINE_SMOOTH); - } -#endif - } - } break; -#endif - case Item::Command::TYPE_PRIMITIVE: { - Item::CommandPrimitive *pr = static_cast<Item::CommandPrimitive *>(command); - - switch (pr->point_count) { - case 2: { - _legacy_draw_line(pr, p_material); - } break; - default: { - _legacy_draw_primitive(pr, p_material); - } break; - } - - } break; - - case Item::Command::TYPE_RECT: { - Item::CommandRect *r = static_cast<Item::CommandRect *>(command); - _bind_quad_buffer(); - glDisableVertexAttribArray(RS::ARRAY_COLOR); - glVertexAttrib4fv(RS::ARRAY_COLOR, r->modulate.components); - - bool can_tile = true; - - // we will take account of render target textures which need to be drawn upside down - // quirk of opengl - bool upside_down = r->flags & CANVAS_RECT_FLIP_V; - - // very inefficient, improve this - if (r->texture.is_valid()) { - RasterizerStorageGLES3::Texture *texture = storage->texture_owner.get_or_null(r->texture); - - if (texture) { - if (texture->is_upside_down()) - upside_down = true; - } - } - - if (r->texture.is_valid() && r->flags & CANVAS_RECT_TILE && !storage->config.support_npot_repeat_mipmap) { - // workaround for when setting tiling does not work due to hardware limitation - - RasterizerStorageGLES3::Texture *texture = storage->texture_owner.get_or_null(r->texture); - - if (texture) { - texture = texture->get_ptr(); - - if (next_power_of_2(texture->alloc_width) != (unsigned int)texture->alloc_width && next_power_of_2(texture->alloc_height) != (unsigned int)texture->alloc_height) { - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_FORCE_REPEAT, true); - can_tile = false; - } - } - } - - // On some widespread Nvidia cards, the normal draw method can produce some - // flickering in draw_rect and especially TileMap rendering (tiles randomly flicker). - // See GH-9913. - // To work it around, we use a simpler draw method which does not flicker, but gives - // a non negligible performance hit, so it's opt-in (GH-24466). - if (use_nvidia_rect_workaround) { - // are we using normal maps, if so we want to use light angle - bool send_light_angles = false; - - // only need to use light angles when normal mapping - // otherwise we can use the default shader - if (state.current_normal != RID()) { - send_light_angles = true; - } - - _set_texture_rect_mode(false, send_light_angles); - - if (state.canvas_shader.bind()) { - _set_uniforms(); - state.canvas_shader.use_material((void *)p_material); - } - - Vector2 points[4] = { - r->rect.position, - r->rect.position + Vector2(r->rect.size.x, 0.0), - r->rect.position + r->rect.size, - r->rect.position + Vector2(0.0, r->rect.size.y), - }; - - if (r->rect.size.x < 0) { - SWAP(points[0], points[1]); - SWAP(points[2], points[3]); - } - if (r->rect.size.y < 0) { - SWAP(points[0], points[3]); - SWAP(points[1], points[2]); - } - - // FTODO - //RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(r->texture, r->normal_map); - RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(r->texture, RID()); - - if (texture) { - Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height); - - Rect2 src_rect = (r->flags & CANVAS_RECT_REGION) ? Rect2(r->source.position * texpixel_size, r->source.size * texpixel_size) : Rect2(0, 0, 1, 1); - - Vector2 uvs[4] = { - src_rect.position, - src_rect.position + Vector2(src_rect.size.x, 0.0), - src_rect.position + src_rect.size, - src_rect.position + Vector2(0.0, src_rect.size.y), - }; - - // for encoding in light angle - bool flip_h = false; - bool flip_v = false; - - if (r->flags & CANVAS_RECT_TRANSPOSE) { - SWAP(uvs[1], uvs[3]); - } - - if (r->flags & CANVAS_RECT_FLIP_H) { - SWAP(uvs[0], uvs[1]); - SWAP(uvs[2], uvs[3]); - flip_h = true; - flip_v = !flip_v; - } - if (upside_down) { - SWAP(uvs[0], uvs[3]); - SWAP(uvs[1], uvs[2]); - flip_v = !flip_v; - } - - state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); - - bool untile = false; - - if (can_tile && r->flags & CANVAS_RECT_TILE && !(texture->flags & RasterizerStorageGLES3::TEXTURE_FLAG_REPEAT)) { - texture->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); - untile = true; - } - - if (send_light_angles) { - // for single rects, there is no need to fully utilize the light angle, - // we only need it to encode flips (horz and vert). But the shader can be reused with - // batching in which case the angle encodes the transform as well as - // the flips. - // Note transpose is NYI. I don't think it worked either with the non-nvidia method. - - // if horizontal flip, angle is 180 - float angle = 0.0f; - if (flip_h) - angle = Math_PI; - - // add 1 (to take care of zero floating point error with sign) - angle += 1.0f; - - // flip if necessary - if (flip_v) - angle *= -1.0f; - - // light angle must be sent for each vert, instead as a single uniform in the uniform draw method - // this has the benefit of enabling batching with light angles. - float light_angles[4] = { angle, angle, angle, angle }; - - _draw_gui_primitive(4, points, NULL, uvs, light_angles); - } else { - _draw_gui_primitive(4, points, NULL, uvs); - } - - if (untile) { - texture->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - } - } else { - static const Vector2 uvs[4] = { - Vector2(0.0, 0.0), - Vector2(0.0, 1.0), - Vector2(1.0, 1.0), - Vector2(1.0, 0.0), - }; - - state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, Vector2()); - _draw_gui_primitive(4, points, NULL, uvs); - } - - } else { - // This branch is better for performance, but can produce flicker on Nvidia, see above comment. - - _set_texture_rect_mode(true); - - if (state.canvas_shader.bind()) { - _set_uniforms(); - state.canvas_shader.use_material((void *)p_material); - } - _bind_quad_buffer(); - - // FTODO - //RasterizerStorageGLES3::Texture *tex = _bind_canvas_texture(r->texture, r->normal_map); - RasterizerStorageGLES3::Texture *tex = _bind_canvas_texture(r->texture, RID()); - - if (!tex) { - Rect2 dst_rect = Rect2(r->rect.position, r->rect.size); - - if (dst_rect.size.width < 0) { - dst_rect.position.x += dst_rect.size.width; - dst_rect.size.width *= -1; - } - if (dst_rect.size.height < 0) { - dst_rect.position.y += dst_rect.size.height; - dst_rect.size.height *= -1; - } - - state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(dst_rect.position.x, dst_rect.position.y, dst_rect.size.x, dst_rect.size.y)); - state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(0, 0, 1, 1)); - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - storage->info.render._2d_draw_call_count++; - } else { - bool untile = false; - - if (can_tile && r->flags & CANVAS_RECT_TILE && !(tex->flags & RasterizerStorageGLES3::TEXTURE_FLAG_REPEAT)) { - tex->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); - untile = true; - } - - Size2 texpixel_size(1.0 / tex->width, 1.0 / tex->height); - Rect2 src_rect = (r->flags & CANVAS_RECT_REGION) ? Rect2(r->source.position * texpixel_size, r->source.size * texpixel_size) : Rect2(0, 0, 1, 1); - - Rect2 dst_rect = Rect2(r->rect.position, r->rect.size); - - if (dst_rect.size.width < 0) { - dst_rect.position.x += dst_rect.size.width; - dst_rect.size.width *= -1; - } - if (dst_rect.size.height < 0) { - dst_rect.position.y += dst_rect.size.height; - dst_rect.size.height *= -1; - } - - if (r->flags & CANVAS_RECT_FLIP_H) { - src_rect.size.x *= -1; - } - - if (upside_down) { - src_rect.size.y *= -1; - } + glBindTexture(t->target, t->tex_id); + } - if (r->flags & CANVAS_RECT_TRANSPOSE) { - dst_rect.size.x *= -1; // Encoding in the dst_rect.z uniform - } + } else { + //state.canvas_shader.version_bind_shader(state.canvas_shader_default_version, CanvasShaderGLES3::MODE_QUAD); + state.current_shader_version = state.canvas_shader_default_version; + } + prev_material = material; + } - state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); + _render_item(p_to_render_target, ci, canvas_transform_inverse, current_clip, p_lights, index); + } + // Render last command + state.end_batch = true; + _render_batch(index); - state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(dst_rect.position.x, dst_rect.position.y, dst_rect.size.x, dst_rect.size.y)); - state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(src_rect.position.x, src_rect.position.y, src_rect.size.x, src_rect.size.y)); + canvas_end(); +} - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - storage->info.render._2d_draw_call_count++; +void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, uint32_t &r_index) { + RS::CanvasItemTextureFilter current_filter = state.default_filter; + RS::CanvasItemTextureRepeat current_repeat = state.default_repeat; - if (untile) { - tex->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - } - } + if (p_item->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT) { + current_filter = p_item->texture_filter; + } - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } + if (p_item->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) { + current_repeat = p_item->texture_repeat; + } - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_FORCE_REPEAT, false); + Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform; + Transform2D draw_transform; // Used by transform command - } break; - case Item::Command::TYPE_NINEPATCH: { - Item::CommandNinePatch *np = static_cast<Item::CommandNinePatch *>(command); + Color base_color = p_item->final_modulate; - _set_texture_rect_mode(false); - if (state.canvas_shader.bind()) { - _set_uniforms(); - state.canvas_shader.use_material((void *)p_material); - } - _bind_quad_buffer(); + uint32_t base_flags = 0; - glDisableVertexAttribArray(RS::ARRAY_COLOR); - glVertexAttrib4fv(RS::ARRAY_COLOR, np->color.components); + RID last_texture; + Size2 texpixel_size; - // FTODO - //RasterizerStorageGLES3::Texture *tex = _bind_canvas_texture(np->texture, np->normal_map); - RasterizerStorageGLES3::Texture *tex = _bind_canvas_texture(np->texture, RID()); + bool skipping = false; - if (!tex) { - // FIXME: Handle textureless ninepatch gracefully - WARN_PRINT("NinePatch without texture not supported yet in OpenGL backend, skipping."); - continue; - } - if (tex->width == 0 || tex->height == 0) { - WARN_PRINT("Cannot set empty texture to NinePatch."); - continue; - } + const Item::Command *c = p_item->commands; + while (c) { + if (skipping && c->type != Item::Command::TYPE_ANIMATION_SLICE) { + c = c->next; + continue; + } - Size2 texpixel_size(1.0 / tex->width, 1.0 / tex->height); + _update_transform_2d_to_mat2x3(base_transform * draw_transform, state.instance_data_array[r_index].world); + + for (int i = 0; i < 4; i++) { + state.instance_data_array[r_index].modulation[i] = 0.0; + state.instance_data_array[r_index].ninepatch_margins[i] = 0.0; + state.instance_data_array[r_index].src_rect[i] = 0.0; + state.instance_data_array[r_index].dst_rect[i] = 0.0; + state.instance_data_array[r_index].lights[i] = uint32_t(0); + } + state.instance_data_array[r_index].flags = base_flags; + state.instance_data_array[r_index].color_texture_pixel_size[0] = 0.0; + state.instance_data_array[r_index].color_texture_pixel_size[1] = 0.0; - // state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix); - state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); + state.instance_data_array[r_index].pad[0] = 0.0; + state.instance_data_array[r_index].pad[1] = 0.0; - Rect2 source = np->source; - if (source.size.x == 0 && source.size.y == 0) { - source.size.x = tex->width; - source.size.y = tex->height; - } + state.instance_data_array[r_index].flags = base_flags | (state.instance_data_array[r_index == 0 ? 0 : r_index - 1].flags & (FLAGS_DEFAULT_NORMAL_MAP_USED | FLAGS_DEFAULT_SPECULAR_MAP_USED)); //reset on each command for sanity, keep canvastexture binding config - float screen_scale = 1.0; + switch (c->type) { + case Item::Command::TYPE_RECT: { + const Item::CommandRect *rect = static_cast<const Item::CommandRect *>(c); - if ((bdata.settings_ninepatch_mode == 1) && (source.size.x != 0) && (source.size.y != 0)) { - screen_scale = MIN(np->rect.size.x / source.size.x, np->rect.size.y / source.size.y); - screen_scale = MIN(1.0, screen_scale); - } + if (rect->flags & CANVAS_RECT_TILE) { + current_repeat = RenderingServer::CanvasItemTextureRepeat::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED; + } - // prepare vertex buffer + if (rect->texture != last_texture || state.current_primitive_points != 0 || state.current_command != Item::Command::TYPE_RECT) { + state.end_batch = true; + _render_batch(r_index); - // this buffer contains [ POS POS UV UV ] * + state.current_primitive_points = 0; + state.current_command = Item::Command::TYPE_RECT; + } + _bind_canvas_texture(rect->texture, current_filter, current_repeat, r_index, last_texture, texpixel_size); + state.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_QUAD); - float buffer[16 * 2 + 16 * 2]; + Rect2 src_rect; + Rect2 dst_rect; - { - // first row + if (rect->texture != RID()) { + src_rect = (rect->flags & CANVAS_RECT_REGION) ? Rect2(rect->source.position * texpixel_size, rect->source.size * texpixel_size) : Rect2(0, 0, 1, 1); + dst_rect = Rect2(rect->rect.position, rect->rect.size); - buffer[(0 * 4 * 4) + 0] = np->rect.position.x; - buffer[(0 * 4 * 4) + 1] = np->rect.position.y; + if (dst_rect.size.width < 0) { + dst_rect.position.x += dst_rect.size.width; + dst_rect.size.width *= -1; + } + if (dst_rect.size.height < 0) { + dst_rect.position.y += dst_rect.size.height; + dst_rect.size.height *= -1; + } - buffer[(0 * 4 * 4) + 2] = source.position.x * texpixel_size.x; - buffer[(0 * 4 * 4) + 3] = source.position.y * texpixel_size.y; + if (rect->flags & CANVAS_RECT_FLIP_H) { + src_rect.size.x *= -1; + } - buffer[(0 * 4 * 4) + 4] = np->rect.position.x + np->margin[SIDE_LEFT] * screen_scale; - buffer[(0 * 4 * 4) + 5] = np->rect.position.y; + if (rect->flags & CANVAS_RECT_FLIP_V) { + src_rect.size.y *= -1; + } - buffer[(0 * 4 * 4) + 6] = (source.position.x + np->margin[SIDE_LEFT]) * texpixel_size.x; - buffer[(0 * 4 * 4) + 7] = source.position.y * texpixel_size.y; + if (rect->flags & CANVAS_RECT_TRANSPOSE) { + dst_rect.size.x *= -1; // Encoding in the dst_rect.z uniform + } - buffer[(0 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[SIDE_RIGHT] * screen_scale; - buffer[(0 * 4 * 4) + 9] = np->rect.position.y; + if (rect->flags & CANVAS_RECT_CLIP_UV) { + state.instance_data_array[r_index].flags |= FLAGS_CLIP_RECT_UV; + } - buffer[(0 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[SIDE_RIGHT]) * texpixel_size.x; - buffer[(0 * 4 * 4) + 11] = source.position.y * texpixel_size.y; + } else { + dst_rect = Rect2(rect->rect.position, rect->rect.size); - buffer[(0 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x; - buffer[(0 * 4 * 4) + 13] = np->rect.position.y; + if (dst_rect.size.width < 0) { + dst_rect.position.x += dst_rect.size.width; + dst_rect.size.width *= -1; + } + if (dst_rect.size.height < 0) { + dst_rect.position.y += dst_rect.size.height; + dst_rect.size.height *= -1; + } - buffer[(0 * 4 * 4) + 14] = (source.position.x + source.size.x) * texpixel_size.x; - buffer[(0 * 4 * 4) + 15] = source.position.y * texpixel_size.y; + src_rect = Rect2(0, 0, 1, 1); + } - // second row + if (rect->flags & CANVAS_RECT_MSDF) { + state.instance_data_array[r_index].flags |= FLAGS_USE_MSDF; + state.instance_data_array[r_index].msdf[0] = rect->px_range; // Pixel range. + state.instance_data_array[r_index].msdf[1] = rect->outline; // Outline size. + state.instance_data_array[r_index].msdf[2] = 0.f; // Reserved. + state.instance_data_array[r_index].msdf[3] = 0.f; // Reserved. + } - buffer[(1 * 4 * 4) + 0] = np->rect.position.x; - buffer[(1 * 4 * 4) + 1] = np->rect.position.y + np->margin[SIDE_TOP] * screen_scale; + state.instance_data_array[r_index].modulation[0] = rect->modulate.r * base_color.r; + state.instance_data_array[r_index].modulation[1] = rect->modulate.g * base_color.g; + state.instance_data_array[r_index].modulation[2] = rect->modulate.b * base_color.b; + state.instance_data_array[r_index].modulation[3] = rect->modulate.a * base_color.a; + + state.instance_data_array[r_index].src_rect[0] = src_rect.position.x; + state.instance_data_array[r_index].src_rect[1] = src_rect.position.y; + state.instance_data_array[r_index].src_rect[2] = src_rect.size.width; + state.instance_data_array[r_index].src_rect[3] = src_rect.size.height; + + state.instance_data_array[r_index].dst_rect[0] = dst_rect.position.x; + state.instance_data_array[r_index].dst_rect[1] = dst_rect.position.y; + state.instance_data_array[r_index].dst_rect[2] = dst_rect.size.width; + state.instance_data_array[r_index].dst_rect[3] = dst_rect.size.height; + //_render_batch(r_index); + r_index++; + if (r_index >= state.max_instances_per_batch - 1) { + //r_index--; + state.end_batch = true; + _render_batch(r_index); + } + } break; - buffer[(1 * 4 * 4) + 2] = source.position.x * texpixel_size.x; - buffer[(1 * 4 * 4) + 3] = (source.position.y + np->margin[SIDE_TOP]) * texpixel_size.y; + case Item::Command::TYPE_NINEPATCH: { + /* + const Item::CommandNinePatch *np = static_cast<const Item::CommandNinePatch *>(c); - buffer[(1 * 4 * 4) + 4] = np->rect.position.x + np->margin[SIDE_LEFT] * screen_scale; - buffer[(1 * 4 * 4) + 5] = np->rect.position.y + np->margin[SIDE_TOP] * screen_scale; + //bind pipeline + { + RID pipeline = pipeline_variants->variants[light_mode][PIPELINE_VARIANT_NINEPATCH].get_render_pipeline(RD::INVALID_ID, p_framebuffer_format); + RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline); + } - buffer[(1 * 4 * 4) + 6] = (source.position.x + np->margin[SIDE_LEFT]) * texpixel_size.x; - buffer[(1 * 4 * 4) + 7] = (source.position.y + np->margin[SIDE_TOP]) * texpixel_size.y; + //bind textures - buffer[(1 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[SIDE_RIGHT] * screen_scale; - buffer[(1 * 4 * 4) + 9] = np->rect.position.y + np->margin[SIDE_TOP] * screen_scale; + _bind_canvas_texture(p_draw_list, np->texture, current_filter, current_repeat, index, last_texture, texpixel_size); - buffer[(1 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[SIDE_RIGHT]) * texpixel_size.x; - buffer[(1 * 4 * 4) + 11] = (source.position.y + np->margin[SIDE_TOP]) * texpixel_size.y; + Rect2 src_rect; + Rect2 dst_rect(np->rect.position.x, np->rect.position.y, np->rect.size.x, np->rect.size.y); - buffer[(1 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x; - buffer[(1 * 4 * 4) + 13] = np->rect.position.y + np->margin[SIDE_TOP] * screen_scale; + if (np->texture == RID()) { + texpixel_size = Size2(1, 1); + src_rect = Rect2(0, 0, 1, 1); - buffer[(1 * 4 * 4) + 14] = (source.position.x + source.size.x) * texpixel_size.x; - buffer[(1 * 4 * 4) + 15] = (source.position.y + np->margin[SIDE_TOP]) * texpixel_size.y; + } else { + if (np->source != Rect2()) { + src_rect = Rect2(np->source.position.x * texpixel_size.width, np->source.position.y * texpixel_size.height, np->source.size.x * texpixel_size.width, np->source.size.y * texpixel_size.height); + state.instance_data_array[r_index].color_texture_pixel_size[0] = 1.0 / np->source.size.width; + state.instance_data_array[r_index].color_texture_pixel_size[1] = 1.0 / np->source.size.height; - // third row + } else { + src_rect = Rect2(0, 0, 1, 1); + } + } - buffer[(2 * 4 * 4) + 0] = np->rect.position.x; - buffer[(2 * 4 * 4) + 1] = np->rect.position.y + np->rect.size.y - np->margin[SIDE_BOTTOM] * screen_scale; + state.instance_data_array[r_index].modulation[0] = np->color.r * base_color.r; + state.instance_data_array[r_index].modulation[1] = np->color.g * base_color.g; + state.instance_data_array[r_index].modulation[2] = np->color.b * base_color.b; + state.instance_data_array[r_index].modulation[3] = np->color.a * base_color.a; - buffer[(2 * 4 * 4) + 2] = source.position.x * texpixel_size.x; - buffer[(2 * 4 * 4) + 3] = (source.position.y + source.size.y - np->margin[SIDE_BOTTOM]) * texpixel_size.y; + state.instance_data_array[r_index].src_rect[0] = src_rect.position.x; + state.instance_data_array[r_index].src_rect[1] = src_rect.position.y; + state.instance_data_array[r_index].src_rect[2] = src_rect.size.width; + state.instance_data_array[r_index].src_rect[3] = src_rect.size.height; - buffer[(2 * 4 * 4) + 4] = np->rect.position.x + np->margin[SIDE_LEFT] * screen_scale; - buffer[(2 * 4 * 4) + 5] = np->rect.position.y + np->rect.size.y - np->margin[SIDE_BOTTOM] * screen_scale; + state.instance_data_array[r_index].dst_rect[0] = dst_rect.position.x; + state.instance_data_array[r_index].dst_rect[1] = dst_rect.position.y; + state.instance_data_array[r_index].dst_rect[2] = dst_rect.size.width; + state.instance_data_array[r_index].dst_rect[3] = dst_rect.size.height; - buffer[(2 * 4 * 4) + 6] = (source.position.x + np->margin[SIDE_LEFT]) * texpixel_size.x; - buffer[(2 * 4 * 4) + 7] = (source.position.y + source.size.y - np->margin[SIDE_BOTTOM]) * texpixel_size.y; + state.instance_data_array[r_index].flags |= int(np->axis_x) << FLAGS_NINEPATCH_H_MODE_SHIFT; + state.instance_data_array[r_index].flags |= int(np->axis_y) << FLAGS_NINEPATCH_V_MODE_SHIFT; - buffer[(2 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[SIDE_RIGHT] * screen_scale; - buffer[(2 * 4 * 4) + 9] = np->rect.position.y + np->rect.size.y - np->margin[SIDE_BOTTOM] * screen_scale; + if (np->draw_center) { + state.instance_data_array[r_index].flags |= FLAGS_NINEPACH_DRAW_CENTER; + } - buffer[(2 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[SIDE_RIGHT]) * texpixel_size.x; - buffer[(2 * 4 * 4) + 11] = (source.position.y + source.size.y - np->margin[SIDE_BOTTOM]) * texpixel_size.y; + state.instance_data_array[r_index].ninepatch_margins[0] = np->margin[SIDE_LEFT]; + state.instance_data_array[r_index].ninepatch_margins[1] = np->margin[SIDE_TOP]; + state.instance_data_array[r_index].ninepatch_margins[2] = np->margin[SIDE_RIGHT]; + state.instance_data_array[r_index].ninepatch_margins[3] = np->margin[SIDE_BOTTOM]; - buffer[(2 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x; - buffer[(2 * 4 * 4) + 13] = np->rect.position.y + np->rect.size.y - np->margin[SIDE_BOTTOM] * screen_scale; + RD::get_singleton()->draw_list_set_state.instance_data_array[r_index](p_draw_list, &state.instance_data_array[r_index], sizeof(PushConstant)); + RD::get_singleton()->draw_list_bind_index_array(p_draw_list, shader.quad_index_array); + RD::get_singleton()->draw_list_draw(p_draw_list, true); - buffer[(2 * 4 * 4) + 14] = (source.position.x + source.size.x) * texpixel_size.x; - buffer[(2 * 4 * 4) + 15] = (source.position.y + source.size.y - np->margin[SIDE_BOTTOM]) * texpixel_size.y; + // Restore if overridden. + state.instance_data_array[r_index].color_texture_pixel_size[0] = texpixel_size.x; + state.instance_data_array[r_index].color_texture_pixel_size[1] = texpixel_size.y; +*/ + } break; - // fourth row + case Item::Command::TYPE_POLYGON: { + const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c); - buffer[(3 * 4 * 4) + 0] = np->rect.position.x; - buffer[(3 * 4 * 4) + 1] = np->rect.position.y + np->rect.size.y; + PolygonBuffers *pb = polygon_buffers.polygons.getptr(polygon->polygon.polygon_id); + ERR_CONTINUE(!pb); - buffer[(3 * 4 * 4) + 2] = source.position.x * texpixel_size.x; - buffer[(3 * 4 * 4) + 3] = (source.position.y + source.size.y) * texpixel_size.y; + if (polygon->texture != last_texture || state.current_primitive_points != 0 || state.current_command != Item::Command::TYPE_POLYGON) { + state.end_batch = true; + _render_batch(r_index); - buffer[(3 * 4 * 4) + 4] = np->rect.position.x + np->margin[SIDE_LEFT] * screen_scale; - buffer[(3 * 4 * 4) + 5] = np->rect.position.y + np->rect.size.y; + state.current_primitive_points = 0; + state.current_command = Item::Command::TYPE_POLYGON; + } + _bind_canvas_texture(polygon->texture, current_filter, current_repeat, r_index, last_texture, texpixel_size); + state.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_ATTRIBUTES); + + state.current_primitive = polygon->primitive; + state.instance_data_array[r_index].modulation[0] = base_color.r; + state.instance_data_array[r_index].modulation[1] = base_color.g; + state.instance_data_array[r_index].modulation[2] = base_color.b; + state.instance_data_array[r_index].modulation[3] = base_color.a; + + for (int j = 0; j < 4; j++) { + state.instance_data_array[r_index].src_rect[j] = 0; + state.instance_data_array[r_index].dst_rect[j] = 0; + state.instance_data_array[r_index].ninepatch_margins[j] = 0; + } - buffer[(3 * 4 * 4) + 6] = (source.position.x + np->margin[SIDE_LEFT]) * texpixel_size.x; - buffer[(3 * 4 * 4) + 7] = (source.position.y + source.size.y) * texpixel_size.y; + // If the previous operation is not done yet, allocated a new buffer + GLint syncStatus; + glGetSynciv(state.fences[state.current_buffer], GL_SYNC_STATUS, sizeof(GLint), nullptr, &syncStatus); + if (syncStatus == GL_UNSIGNALED) { + _allocate_instance_data_buffer(); + } else { + glDeleteSync(state.fences[state.current_buffer]); + } - buffer[(3 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[SIDE_RIGHT] * screen_scale; - buffer[(3 * 4 * 4) + 9] = np->rect.position.y + np->rect.size.y; + glBindBufferBase(GL_UNIFORM_BUFFER, 3, state.canvas_instance_data_buffers[state.current_buffer]); +#ifdef JAVASCRIPT_ENABLED + //WebGL 2.0 does not support mapping buffers, so use slow glBufferData instead + glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData), &state.instance_data_array[0], GL_DYNAMIC_DRAW); +#else + void *ubo = glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); + memcpy(ubo, &state.instance_data_array[0], sizeof(InstanceData)); + glUnmapBuffer(GL_UNIFORM_BUFFER); +#endif + glBindVertexArray(pb->vertex_array); - buffer[(3 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[SIDE_RIGHT]) * texpixel_size.x; - buffer[(3 * 4 * 4) + 11] = (source.position.y + source.size.y) * texpixel_size.y; + static const GLenum prim[5] = { GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP }; - buffer[(3 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x; - buffer[(3 * 4 * 4) + 13] = np->rect.position.y + np->rect.size.y; + if (pb->index_buffer != 0) { + glDrawElements(prim[polygon->primitive], pb->count, GL_UNSIGNED_INT, 0); + } else { + glDrawArrays(prim[polygon->primitive], 0, pb->count); + } + glBindVertexArray(0); + state.fences[state.current_buffer] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - buffer[(3 * 4 * 4) + 14] = (source.position.x + source.size.x) * texpixel_size.x; - buffer[(3 * 4 * 4) + 15] = (source.position.y + source.size.y) * texpixel_size.y; - } + state.current_buffer = (state.current_buffer + 1) % state.canvas_instance_data_buffers.size(); + } break; - glBindBuffer(GL_ARRAY_BUFFER, data.ninepatch_vertices); - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * (16 + 16) * 2, buffer, _buffer_upload_usage_flag); + case Item::Command::TYPE_PRIMITIVE: { + const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ninepatch_elements); + if (last_texture != default_canvas_texture || state.current_primitive_points != primitive->point_count || state.current_command != Item::Command::TYPE_PRIMITIVE) { + state.end_batch = true; + _render_batch(r_index); + state.current_primitive_points = primitive->point_count; + state.current_command = Item::Command::TYPE_PRIMITIVE; + } + _bind_canvas_texture(RID(), current_filter, current_repeat, r_index, last_texture, texpixel_size); + state.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_PRIMITIVE); + + for (uint32_t j = 0; j < MIN(3, primitive->point_count); j++) { + state.instance_data_array[r_index].points[j * 2 + 0] = primitive->points[j].x; + state.instance_data_array[r_index].points[j * 2 + 1] = primitive->points[j].y; + state.instance_data_array[r_index].uvs[j * 2 + 0] = primitive->uvs[j].x; + state.instance_data_array[r_index].uvs[j * 2 + 1] = primitive->uvs[j].y; + Color col = primitive->colors[j] * base_color; + state.instance_data_array[r_index].colors[j * 2 + 0] = (uint32_t(Math::make_half_float(col.g)) << 16) | Math::make_half_float(col.r); + state.instance_data_array[r_index].colors[j * 2 + 1] = (uint32_t(Math::make_half_float(col.a)) << 16) | Math::make_half_float(col.b); + } + r_index++; + if (primitive->point_count == 4) { + // Reset base data + _update_transform_2d_to_mat2x3(base_transform * draw_transform, state.instance_data_array[r_index].world); + state.instance_data_array[r_index].color_texture_pixel_size[0] = 0.0; + state.instance_data_array[r_index].color_texture_pixel_size[1] = 0.0; + + state.instance_data_array[r_index].flags = base_flags | (state.instance_data_array[r_index == 0 ? 0 : r_index - 1].flags & (FLAGS_DEFAULT_NORMAL_MAP_USED | FLAGS_DEFAULT_SPECULAR_MAP_USED)); //reset on each command for sanity, keep canvastexture binding config + + for (uint32_t j = 0; j < 3; j++) { + //second half of triangle + state.instance_data_array[r_index].points[j * 2 + 0] = primitive->points[j + 1].x; + state.instance_data_array[r_index].points[j * 2 + 1] = primitive->points[j + 1].y; + state.instance_data_array[r_index].uvs[j * 2 + 0] = primitive->uvs[j + 1].x; + state.instance_data_array[r_index].uvs[j * 2 + 1] = primitive->uvs[j + 1].y; + Color col = primitive->colors[j + 1] * base_color; + state.instance_data_array[r_index].colors[j * 2 + 0] = (uint32_t(Math::make_half_float(col.g)) << 16) | Math::make_half_float(col.r); + state.instance_data_array[r_index].colors[j * 2 + 1] = (uint32_t(Math::make_half_float(col.a)) << 16) | Math::make_half_float(col.b); + } + r_index++; + } + if (r_index >= state.max_instances_per_batch - 1) { + //r_index--; + state.end_batch = true; + _render_batch(r_index); + } + } break; - //glEnableVertexAttribArray(RS::ARRAY_VERTEX); - glEnableVertexAttribArray(RS::ARRAY_TEX_UV); + case Item::Command::TYPE_MESH: + case Item::Command::TYPE_MULTIMESH: + case Item::Command::TYPE_PARTICLES: { + /* + RID mesh; + RID mesh_instance; + RID texture; + Color modulate(1, 1, 1, 1); + int instance_count = 1; + + if (c->type == Item::Command::TYPE_MESH) { + const Item::CommandMesh *m = static_cast<const Item::CommandMesh *>(c); + mesh = m->mesh; + mesh_instance = m->mesh_instance; + texture = m->texture; + modulate = m->modulate; + _update_transform_2d_to_mat2x3(base_transform * draw_transform * m->transform, state.instance_data_array[r_index].world); + } else if (c->type == Item::Command::TYPE_MULTIMESH) { + const Item::CommandMultiMesh *mm = static_cast<const Item::CommandMultiMesh *>(c); + RID multimesh = mm->multimesh; + mesh = storage->multimesh_get_mesh(multimesh); + texture = mm->texture; + + if (storage->multimesh_get_transform_format(multimesh) != RS::MULTIMESH_TRANSFORM_2D) { + break; + } - //glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), NULL); - glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), CAST_INT_TO_UCHAR_PTR((sizeof(float) * 2))); + instance_count = storage->multimesh_get_instances_to_draw(multimesh); - //glDrawElements(GL_TRIANGLES, 18 * 3 - (np->draw_center ? 0 : 6), GL_UNSIGNED_SHORT, NULL); + if (instance_count == 0) { + break; + } - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - storage->info.render._2d_draw_call_count++; + state.instance_data_array[r_index].flags |= 1; //multimesh, trails disabled + if (storage->multimesh_uses_colors(multimesh)) { + state.instance_data_array[r_index].flags |= FLAGS_INSTANCING_HAS_COLORS; + } + if (storage->multimesh_uses_custom_data(multimesh)) { + state.instance_data_array[r_index].flags |= FLAGS_INSTANCING_HAS_CUSTOM_DATA; + } + } - } break; -#if 0 - case Item::Command::TYPE_CIRCLE: { - Item::CommandCircle *circle = static_cast<Item::CommandCircle *>(command); + // TODO: implement particles here - _set_texture_rect_mode(false); + if (mesh.is_null()) { + break; + } - if (state.canvas_shader.bind()) { - _set_uniforms(); - state.canvas_shader.use_material((void *)p_material); - } + if (texture != last_texture || state.current_primitive_points != 0 || state.current_command != Item::Command::TYPE_PRIMITIVE) { + state.end_batch = true; + _render_batch(r_index); + state.current_primitive_points = 0; + state.current_command = c->type; + } - static const int num_points = 32; + _bind_canvas_texture(texture, current_filter, current_repeat, r_index, last_texture, texpixel_size); - Vector2 points[num_points + 1]; - points[num_points] = circle->pos; + uint32_t surf_count = storage->mesh_get_surface_count(mesh); - int indices[num_points * 3]; + state.instance_data_array[r_index].modulation[0] = base_color.r * modulate.r; + state.instance_data_array[r_index].modulation[1] = base_color.g * modulate.g; + state.instance_data_array[r_index].modulation[2] = base_color.b * modulate.b; + state.instance_data_array[r_index].modulation[3] = base_color.a * modulate.a; - for (int j = 0; j < num_points; j++) { - points[j] = circle->pos + Vector2(Math::sin(j * Math_PI * 2.0 / num_points), Math::cos(j * Math_PI * 2.0 / num_points)) * circle->radius; - indices[j * 3 + 0] = j; - indices[j * 3 + 1] = (j + 1) % num_points; - indices[j * 3 + 2] = num_points; - } + for (int j = 0; j < 4; j++) { + state.instance_data_array[r_index].src_rect[j] = 0; + state.instance_data_array[r_index].dst_rect[j] = 0; + state.instance_data_array[r_index].ninepatch_margins[j] = 0; + } - _bind_canvas_texture(RID(), RID()); + for (uint32_t j = 0; j < surf_count; j++) { + RS::SurfaceData *surface = storage->mesh_get_surface(mesh, j); - _draw_polygon(indices, num_points * 3, num_points + 1, points, NULL, &circle->color, true); - } break; -#endif - case Item::Command::TYPE_POLYGON: { - Item::CommandPolygon *polygon = static_cast<Item::CommandPolygon *>(command); - //const PolyData &pd = _polydata[polygon->polygon.polygon_id]; - - switch (polygon->primitive) { - case RS::PRIMITIVE_TRIANGLES: { - _legacy_draw_poly_triangles(polygon, p_material); - } break; - default: - break; - } - - } break; -#if 0 - case Item::Command::TYPE_MESH: { - Item::CommandMesh *mesh = static_cast<Item::CommandMesh *>(command); - - _set_texture_rect_mode(false); - - if (state.canvas_shader.bind()) { - _set_uniforms(); - state.canvas_shader.use_material((void *)p_material); - } - - RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(mesh->texture, mesh->normal_map); - - if (texture) { - Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height); - state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); - } + RS::PrimitiveType primitive = storage->mesh_surface_get_primitive(surface); + ERR_CONTINUE(primitive < 0 || primitive >= RS::PRIMITIVE_MAX); - RasterizerStorageGLES3::Mesh *mesh_data = storage->mesh_owner.get_or_null(mesh->mesh); - if (mesh_data) { - for (int j = 0; j < mesh_data->surfaces.size(); j++) { - RasterizerStorageGLES3::Surface *s = mesh_data->surfaces[j]; - // materials are ignored in 2D meshes, could be added but many things (ie, lighting mode, reading from screen, etc) would break as they are not meant be set up at this point of drawing - - glBindBuffer(GL_ARRAY_BUFFER, s->vertex_id); - - if (s->index_array_len > 0) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_id); - } - - for (int k = 0; k < RS::ARRAY_MAX - 1; k++) { - if (s->attribs[k].enabled) { - glEnableVertexAttribArray(k); - glVertexAttribPointer(s->attribs[k].index, s->attribs[k].size, s->attribs[k].type, s->attribs[k].normalized, s->attribs[k].stride, CAST_INT_TO_UCHAR_PTR(s->attribs[k].offset)); - } else { - glDisableVertexAttribArray(k); - switch (k) { - case RS::ARRAY_NORMAL: { - glVertexAttrib4f(RS::ARRAY_NORMAL, 0.0, 0.0, 1, 1); - } break; - case RS::ARRAY_COLOR: { - glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1); - - } break; - default: { - } - } - } - } - - if (s->index_array_len > 0) { - glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0); - } else { - glDrawArrays(gl_primitive[s->primitive], 0, s->array_len); - } - } - - for (int j = 1; j < RS::ARRAY_MAX - 1; j++) { - glDisableVertexAttribArray(j); - } - } - - storage->info.render._2d_draw_call_count++; - } break; - case Item::Command::TYPE_MULTIMESH: { - Item::CommandMultiMesh *mmesh = static_cast<Item::CommandMultiMesh *>(command); - - RasterizerStorageGLES3::MultiMesh *multi_mesh = storage->multimesh_owner.get_or_null(mmesh->multimesh); - - if (!multi_mesh) - break; - - RasterizerStorageGLES3::Mesh *mesh_data = storage->mesh_owner.get_or_null(multi_mesh->mesh); - - if (!mesh_data) - break; - - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCE_CUSTOM, multi_mesh->custom_data_format != RS::MULTIMESH_CUSTOM_DATA_NONE); - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, true); - _set_texture_rect_mode(false); - - if (state.canvas_shader.bind()) { - _set_uniforms(); - state.canvas_shader.use_material((void *)p_material); - } - - RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(mmesh->texture, mmesh->normal_map); - - if (texture) { - Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height); - state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); - } - - //reset shader and force rebind - - int amount = MIN(multi_mesh->size, multi_mesh->visible_instances); - - if (amount == -1) { - amount = multi_mesh->size; - } - - int stride = multi_mesh->color_floats + multi_mesh->custom_data_floats + multi_mesh->xform_floats; - - int color_ofs = multi_mesh->xform_floats; - int custom_data_ofs = color_ofs + multi_mesh->color_floats; - - // drawing - - const float *base_buffer = multi_mesh->data.ptr(); - - for (int j = 0; j < mesh_data->surfaces.size(); j++) { - RasterizerStorageGLES3::Surface *s = mesh_data->surfaces[j]; - // materials are ignored in 2D meshes, could be added but many things (ie, lighting mode, reading from screen, etc) would break as they are not meant be set up at this point of drawing - - //bind buffers for mesh surface - glBindBuffer(GL_ARRAY_BUFFER, s->vertex_id); - - if (s->index_array_len > 0) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_id); - } - - for (int k = 0; k < RS::ARRAY_MAX - 1; k++) { - if (s->attribs[k].enabled) { - glEnableVertexAttribArray(k); - glVertexAttribPointer(s->attribs[k].index, s->attribs[k].size, s->attribs[k].type, s->attribs[k].normalized, s->attribs[k].stride, CAST_INT_TO_UCHAR_PTR(s->attribs[k].offset)); - } else { - glDisableVertexAttribArray(k); - switch (k) { - case RS::ARRAY_NORMAL: { - glVertexAttrib4f(RS::ARRAY_NORMAL, 0.0, 0.0, 1, 1); - } break; - case RS::ARRAY_COLOR: { - glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1); - - } break; - default: { - } - } - } - } - - for (int k = 0; k < amount; k++) { - const float *buffer = base_buffer + k * stride; - - { - glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 0, &buffer[0]); - glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 1, &buffer[4]); - if (multi_mesh->transform_format == RS::MULTIMESH_TRANSFORM_3D) { - glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 2, &buffer[8]); - } else { - glVertexAttrib4f(INSTANCE_ATTRIB_BASE + 2, 0.0, 0.0, 1.0, 0.0); - } - } - - if (multi_mesh->color_floats) { - if (multi_mesh->color_format == RS::MULTIMESH_COLOR_8BIT) { - uint8_t *color_data = (uint8_t *)(buffer + color_ofs); - glVertexAttrib4f(INSTANCE_ATTRIB_BASE + 3, color_data[0] / 255.0, color_data[1] / 255.0, color_data[2] / 255.0, color_data[3] / 255.0); - } else { - glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 3, buffer + color_ofs); - } - } else { - glVertexAttrib4f(INSTANCE_ATTRIB_BASE + 3, 1.0, 1.0, 1.0, 1.0); - } - - if (multi_mesh->custom_data_floats) { - if (multi_mesh->custom_data_format == RS::MULTIMESH_CUSTOM_DATA_8BIT) { - uint8_t *custom_data = (uint8_t *)(buffer + custom_data_ofs); - glVertexAttrib4f(INSTANCE_ATTRIB_BASE + 4, custom_data[0] / 255.0, custom_data[1] / 255.0, custom_data[2] / 255.0, custom_data[3] / 255.0); - } else { - glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 4, buffer + custom_data_ofs); - } - } - - if (s->index_array_len > 0) { - glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0); - } else { - glDrawArrays(gl_primitive[s->primitive], 0, s->array_len); - } - } - } - - // LIGHT ANGLE PR replaced USE_INSTANCE_CUSTOM line with below .. think it was a typo, - // but just in case, made this note. - //_set_texture_rect_mode(false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCE_CUSTOM, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, false); - - storage->info.render._2d_draw_call_count++; - } break; - case Item::Command::TYPE_POLYLINE: { - Item::CommandPolyLine *pline = static_cast<Item::CommandPolyLine *>(command); - - _set_texture_rect_mode(false); - - if (state.canvas_shader.bind()) { - _set_uniforms(); - state.canvas_shader.use_material((void *)p_material); - } - - _bind_canvas_texture(RID(), RID()); - - if (pline->triangles.size()) { - _draw_generic(GL_TRIANGLE_STRIP, pline->triangles.size(), pline->triangles.ptr(), NULL, pline->triangle_colors.ptr(), pline->triangle_colors.size() == 1); -#ifdef GLES_OVER_GL - glEnable(GL_LINE_SMOOTH); - if (pline->multiline) { - //needs to be different - } else { - _draw_generic(GL_LINE_LOOP, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1); - } - glDisable(GL_LINE_SMOOTH); -#endif - } else { -#ifdef GLES_OVER_GL - if (pline->antialiased) - glEnable(GL_LINE_SMOOTH); -#endif + glBindVertexArray(surface->vertex_array); + static const GLenum prim[5] = { GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP }; - if (pline->multiline) { - int todo = pline->lines.size() / 2; - int max_per_call = data.polygon_buffer_size / (sizeof(real_t) * 4); - int offset = 0; - - while (todo) { - int to_draw = MIN(max_per_call, todo); - _draw_generic(GL_LINES, to_draw * 2, &pline->lines.ptr()[offset], NULL, pline->line_colors.size() == 1 ? pline->line_colors.ptr() : &pline->line_colors.ptr()[offset], pline->line_colors.size() == 1); - todo -= to_draw; - offset += to_draw * 2; - } - } else { - _draw_generic(GL_LINE_STRIP, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1); - } - -#ifdef GLES_OVER_GL - if (pline->antialiased) - glDisable(GL_LINE_SMOOTH); -#endif - } - } break; - - case Item::Command::TYPE_PRIMITIVE: { - Item::CommandPrimitive *primitive = static_cast<Item::CommandPrimitive *>(command); - _set_texture_rect_mode(false); - - if (state.canvas_shader.bind()) { - _set_uniforms(); - state.canvas_shader.use_material((void *)p_material); - } - - ERR_CONTINUE(primitive->points.size() < 1); - - RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(primitive->texture, primitive->normal_map); - - if (texture) { - Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height); - state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); - } - - // we need a temporary because this must be nulled out - // if only a single color specified - const Color *colors = primitive->colors.ptr(); - if (primitive->colors.size() == 1 && primitive->points.size() > 1) { - Color c = primitive->colors[0]; - glVertexAttrib4f(RS::ARRAY_COLOR, c.r, c.g, c.b, c.a); - colors = nullptr; - } else if (primitive->colors.empty()) { - glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1); - } -#ifdef RASTERIZER_EXTRA_CHECKS - else { - RAST_DEV_DEBUG_ASSERT(primitive->colors.size() == primitive->points.size()); - } - - if (primitive->uvs.ptr()) { - RAST_DEV_DEBUG_ASSERT(primitive->uvs.size() == primitive->points.size()); - } -#endif + // Draw directly, no need to batch + } + */ + } break; + case Item::Command::TYPE_TRANSFORM: { + const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c); + draw_transform = transform->xform; + } break; - _draw_gui_primitive(primitive->points.size(), primitive->points.ptr(), colors, primitive->uvs.ptr()); - } break; -#endif - case Item::Command::TYPE_TRANSFORM: { - Item::CommandTransform *transform = static_cast<Item::CommandTransform *>(command); - state.uniforms.extra_matrix = transform->xform; - state.canvas_shader.set_uniform(CanvasShaderGLES3::EXTRA_MATRIX, state.uniforms.extra_matrix); - } break; - - case Item::Command::TYPE_PARTICLES: { - } break; - case Item::Command::TYPE_CLIP_IGNORE: { - Item::CommandClipIgnore *ci = static_cast<Item::CommandClipIgnore *>(command); - if (p_current_clip) { - if (ci->ignore != r_reclip) { - if (ci->ignore) { - glDisable(GL_SCISSOR_TEST); - r_reclip = true; - } else { - glEnable(GL_SCISSOR_TEST); - - int x = p_current_clip->final_clip_rect.position.x; - int y = storage->frame.current_rt->height - (p_current_clip->final_clip_rect.position.y + p_current_clip->final_clip_rect.size.y); - int w = p_current_clip->final_clip_rect.size.x; - int h = p_current_clip->final_clip_rect.size.y; - - // FTODO - // if (storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_VFLIP]) - // y = p_current_clip->final_clip_rect.position.y; - - glScissor(x, y, w, h); - - r_reclip = false; - } - } - } - - } break; - default: { - // FIXME: Proper error handling if relevant - //print_line("other"); - } break; + case Item::Command::TYPE_CLIP_IGNORE: { + /* + const Item::CommandClipIgnore *ci = static_cast<const Item::CommandClipIgnore *>(c); + if (current_clip) { + if (ci->ignore != reclip) { + if (ci->ignore) { + RD::get_singleton()->draw_list_disable_scissor(p_draw_list); + reclip = true; + } else { + RD::get_singleton()->draw_list_enable_scissor(p_draw_list, current_clip->final_clip_rect); + reclip = false; + } } } + */ + } break; + case Item::Command::TYPE_ANIMATION_SLICE: { + /* + const Item::CommandAnimationSlice *as = static_cast<const Item::CommandAnimationSlice *>(c); + double current_time = RendererCompositorRD::singleton->get_total_time(); + double local_time = Math::fposmod(current_time - as->offset, as->animation_length); + skipping = !(local_time >= as->slice_begin && local_time < as->slice_end); + + RenderingServerDefault::redraw_request(); // animation visible means redraw request + */ + } break; + } - } // default - break; + c = c->next; + } +} + +void RasterizerCanvasGLES3::_render_batch(uint32_t &r_index) { + if (state.end_batch && r_index > 0) { + // If the previous operation is not done yet, allocate a new buffer + GLint syncStatus; + glGetSynciv(state.fences[state.current_buffer], GL_SYNC_STATUS, sizeof(GLint), nullptr, &syncStatus); + if (syncStatus == GL_UNSIGNALED) { + _allocate_instance_data_buffer(); + } else { + glDeleteSync(state.fences[state.current_buffer]); } + + glBindBufferBase(GL_UNIFORM_BUFFER, 3, state.canvas_instance_data_buffers[state.current_buffer]); +#ifdef JAVASCRIPT_ENABLED + //WebGL 2.0 does not support mapping buffers, so use slow glBufferData instead + glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData) * r_index, state.instance_data_array, GL_DYNAMIC_DRAW); +#else + void *ubo = glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(InstanceData) * r_index, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); + memcpy(ubo, state.instance_data_array, sizeof(InstanceData) * r_index); + glUnmapBuffer(GL_UNIFORM_BUFFER); +#endif + glBindVertexArray(data.canvas_quad_array); + if (state.current_primitive_points == 0) { + glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, r_index); + } else { + static const GLenum prim[5] = { GL_POINTS, GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLES }; + glDrawArraysInstanced(prim[state.current_primitive_points], 0, state.current_primitive_points, r_index); + } + glBindBuffer(GL_UNIFORM_BUFFER, 0); + + state.fences[state.current_buffer] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + state.current_buffer = (state.current_buffer + 1) % state.canvas_instance_data_buffers.size(); + state.end_batch = false; + //copy the new data into the base of the batch + for (int i = 0; i < 4; i++) { + state.instance_data_array[0].modulation[i] = state.instance_data_array[r_index].modulation[i]; + state.instance_data_array[0].ninepatch_margins[i] = state.instance_data_array[r_index].ninepatch_margins[i]; + state.instance_data_array[0].src_rect[i] = state.instance_data_array[r_index].src_rect[i]; + state.instance_data_array[0].dst_rect[i] = state.instance_data_array[r_index].dst_rect[i]; + state.instance_data_array[0].lights[i] = state.instance_data_array[r_index].lights[i]; + } + state.instance_data_array[0].flags = state.instance_data_array[r_index].flags; + state.instance_data_array[0].color_texture_pixel_size[0] = state.instance_data_array[r_index].color_texture_pixel_size[0]; + state.instance_data_array[0].color_texture_pixel_size[1] = state.instance_data_array[r_index].color_texture_pixel_size[1]; + + state.instance_data_array[0].pad[0] = state.instance_data_array[r_index].pad[0]; + state.instance_data_array[0].pad[1] = state.instance_data_array[r_index].pad[1]; + for (int i = 0; i < 6; i++) { + state.instance_data_array[0].world[i] = state.instance_data_array[r_index].world[i]; + } + + r_index = 0; } } -void RasterizerCanvasGLES3::canvas_end() { - batch_canvas_end(); - RasterizerCanvasBaseGLES3::canvas_end(); +// TODO maybe dont use +void RasterizerCanvasGLES3::_end_batch(uint32_t &r_index) { + for (int i = 0; i < 4; i++) { + state.instance_data_array[r_index].modulation[i] = 0.0; + state.instance_data_array[r_index].ninepatch_margins[i] = 0.0; + state.instance_data_array[r_index].src_rect[i] = 0.0; + state.instance_data_array[r_index].dst_rect[i] = 0.0; + } + state.instance_data_array[r_index].flags = uint32_t(0); + state.instance_data_array[r_index].color_texture_pixel_size[0] = 0.0; + state.instance_data_array[r_index].color_texture_pixel_size[1] = 0.0; + + state.instance_data_array[r_index].pad[0] = 0.0; + state.instance_data_array[r_index].pad[1] = 0.0; + + state.instance_data_array[r_index].lights[0] = uint32_t(0); + state.instance_data_array[r_index].lights[1] = uint32_t(0); + state.instance_data_array[r_index].lights[2] = uint32_t(0); + state.instance_data_array[r_index].lights[3] = uint32_t(0); } -void RasterizerCanvasGLES3::canvas_begin() { - batch_canvas_begin(); - RasterizerCanvasBaseGLES3::canvas_begin(); +RID RasterizerCanvasGLES3::light_create() { + return RID(); } -void RasterizerCanvasGLES3::canvas_render_items_begin(const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform) { - batch_canvas_render_items_begin(p_modulate, p_light, p_base_transform); +void RasterizerCanvasGLES3::light_set_texture(RID p_rid, RID p_texture) { } -void RasterizerCanvasGLES3::canvas_render_items_end() { - batch_canvas_render_items_end(); +void RasterizerCanvasGLES3::light_set_use_shadow(RID p_rid, bool p_enable) { } -void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) { - storage->frame.current_rt = nullptr; +void RasterizerCanvasGLES3::light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) { +} - // first set the current render target - storage->_set_current_render_target(p_to_render_target); +void RasterizerCanvasGLES3::light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) { +} - // binds the render target (framebuffer) - canvas_begin(); +void RasterizerCanvasGLES3::render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) { +} - canvas_render_items_begin(p_modulate, p_light_list, p_canvas_transform); - canvas_render_items_internal(p_item_list, 0, p_modulate, p_light_list, p_canvas_transform); - canvas_render_items_end(); +RID RasterizerCanvasGLES3::occluder_polygon_create() { + return RID(); +} - canvas_end(); +void RasterizerCanvasGLES3::occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) { +} - // not sure why these are needed to get frame to render? - storage->_set_current_render_target(RID()); - // storage->frame.current_rt = nullptr; - // canvas_begin(); - // canvas_end(); +void RasterizerCanvasGLES3::occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) { } -void RasterizerCanvasGLES3::canvas_render_items_internal(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform) { - batch_canvas_render_items(p_item_list, p_z, p_modulate, p_light, p_base_transform); +void RasterizerCanvasGLES3::set_shadow_texture_size(int p_size) { +} - //glClearColor(Math::randf(), 0, 1, 1); +bool RasterizerCanvasGLES3::free(RID p_rid) { + return true; } -void RasterizerCanvasGLES3::canvas_render_items_implementation(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform) { - // parameters are easier to pass around in a structure - RenderItemState ris; - ris.item_group_z = p_z; - ris.item_group_modulate = p_modulate; - ris.item_group_light = p_light; - ris.item_group_base_transform = p_base_transform; +void RasterizerCanvasGLES3::update() { +} - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SKELETON, false); +void RasterizerCanvasGLES3::canvas_begin() { + state.using_transparent_rt = false; - state.current_tex = RID(); - state.current_tex_ptr = NULL; - state.current_normal = RID(); - state.canvas_texscreen_used = false; + if (storage->frame.current_rt) { + storage->bind_framebuffer(storage->frame.current_rt->fbo); + state.using_transparent_rt = storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]; + } + + if (storage->frame.current_rt && storage->frame.current_rt->clear_requested) { + const Color &col = storage->frame.current_rt->clear_color; + glClearColor(col.r, col.g, col.b, col.a); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + storage->frame.current_rt->clear_requested = false; + } + + reset_canvas(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); +} - while (p_item_list) { - Item *ci = p_item_list; - _legacy_canvas_render_item(ci, ris); - p_item_list = p_item_list->next; +void RasterizerCanvasGLES3::canvas_end() { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_UNIFORM_BUFFER, 0); +} + +void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, uint32_t &r_index, RID &r_last_texture, Size2 &r_texpixel_size) { + if (p_texture == RID()) { + p_texture = default_canvas_texture; } - if (ris.current_clip) { - glDisable(GL_SCISSOR_TEST); + if (r_last_texture == p_texture) { + return; //nothing to do, its the same } - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SKELETON, false); -} + state.end_batch = true; + _render_batch(r_index); -// Legacy non-batched implementation for regression testing. -// Should be removed after testing phase to avoid duplicate codepaths. -void RasterizerCanvasGLES3::_legacy_canvas_render_item(Item *p_ci, RenderItemState &r_ris) { - storage->info.render._2d_item_count++; + RasterizerStorageGLES3::CanvasTexture *ct = nullptr; - // defaults - state.current_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR; - state.current_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; + RasterizerStorageGLES3::Texture *t = storage->texture_owner.get_or_null(p_texture); + + if (t) { + //regular texture + if (!t->canvas_texture) { + t->canvas_texture = memnew(RasterizerStorageGLES3::CanvasTexture); + t->canvas_texture->diffuse = p_texture; + } - if (p_ci->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT) { - state.current_filter = p_ci->texture_filter; + ct = t->canvas_texture; + } else { + ct = storage->canvas_texture_owner.get_or_null(p_texture); } - if (p_ci->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) { - state.current_repeat = p_ci->texture_repeat; + if (!ct) { + // Invalid Texture RID. + _bind_canvas_texture(default_canvas_texture, p_base_filter, p_base_repeat, r_index, r_last_texture, r_texpixel_size); + return; } - if (r_ris.current_clip != p_ci->final_clip_owner) { - r_ris.current_clip = p_ci->final_clip_owner; - - if (r_ris.current_clip) { - glEnable(GL_SCISSOR_TEST); - int y = storage->_dims.rt_height - (r_ris.current_clip->final_clip_rect.position.y + r_ris.current_clip->final_clip_rect.size.y); - // int y = storage->frame.current_rt->height - (r_ris.current_clip->final_clip_rect.position.y + r_ris.current_clip->final_clip_rect.size.y); - // FTODO - // if (storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_VFLIP]) - // y = r_ris.current_clip->final_clip_rect.position.y; - glScissor(r_ris.current_clip->final_clip_rect.position.x, y, r_ris.current_clip->final_clip_rect.size.width, r_ris.current_clip->final_clip_rect.size.height); - - // debug VFLIP - // if ((r_ris.current_clip->final_clip_rect.position.x == 223) - // && (y == 54) - // && (r_ris.current_clip->final_clip_rect.size.width == 1383)) - // { - // glScissor(r_ris.current_clip->final_clip_rect.position.x, y, r_ris.current_clip->final_clip_rect.size.width, r_ris.current_clip->final_clip_rect.size.height); - // } + RS::CanvasItemTextureFilter filter = ct->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? ct->texture_filter : p_base_filter; + ERR_FAIL_COND(filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT); - } else { - glDisable(GL_SCISSOR_TEST); - } + RS::CanvasItemTextureRepeat repeat = ct->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT ? ct->texture_repeat : p_base_repeat; + ERR_FAIL_COND(repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT); + + RasterizerStorageGLES3::Texture *texture = storage->texture_owner.get_or_null(ct->diffuse); + + if (!texture) { + state.current_tex = RID(); + state.current_tex_ptr = NULL; + ct->size_cache = Size2i(1, 1); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); + + } else { + texture = texture->get_ptr(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture->tex_id); + + state.current_tex = ct->diffuse; + state.current_tex_ptr = texture; + ct->size_cache = Size2i(texture->width, texture->height); + + texture->GLSetFilter(GL_TEXTURE_2D, filter); + texture->GLSetRepeat(GL_TEXTURE_2D, repeat); } - // TODO: copy back buffer + RasterizerStorageGLES3::Texture *normal_map = storage->texture_owner.get_or_null(ct->normal_map); - if (p_ci->copy_back_buffer) { - if (p_ci->copy_back_buffer->full) { - _copy_texscreen(Rect2()); - } else { - _copy_texscreen(p_ci->copy_back_buffer->rect); - } + if (!normal_map) { + state.current_normal = RID(); + ct->use_normal_cache = false; + glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 6); + glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex); + + } else { + normal_map = normal_map->get_ptr(); + + glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 6); + glBindTexture(GL_TEXTURE_2D, normal_map->tex_id); + state.current_normal = ct->normal_map; + ct->use_normal_cache = true; + texture->GLSetFilter(GL_TEXTURE_2D, filter); + texture->GLSetRepeat(GL_TEXTURE_2D, repeat); } -#if 0 - RasterizerStorageGLES3::Skeleton *skeleton = NULL; + RasterizerStorageGLES3::Texture *specular_map = storage->texture_owner.get_or_null(ct->specular); - { - //skeleton handling - if (p_ci->skeleton.is_valid() && storage->skeleton_owner.owns(p_ci->skeleton)) { - skeleton = storage->skeleton_owner.get(p_ci->skeleton); - if (!skeleton->use_2d) { - skeleton = NULL; - } else { - state.skeleton_transform = r_ris.item_group_base_transform * skeleton->base_transform_2d; - state.skeleton_transform_inverse = state.skeleton_transform.affine_inverse(); - state.skeleton_texture_size = Vector2(skeleton->size * 2, 0); - } - } + if (!specular_map) { + state.current_specular = RID(); + ct->use_specular_cache = false; + glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 7); + glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); - bool use_skeleton = skeleton != NULL; - if (r_ris.prev_use_skeleton != use_skeleton) { - r_ris.rebind_shader = true; - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SKELETON, use_skeleton); - r_ris.prev_use_skeleton = use_skeleton; - } + } else { + specular_map = specular_map->get_ptr(); + + glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 7); + glBindTexture(GL_TEXTURE_2D, specular_map->tex_id); + state.current_specular = ct->specular; + ct->use_specular_cache = true; + texture->GLSetFilter(GL_TEXTURE_2D, filter); + texture->GLSetRepeat(GL_TEXTURE_2D, repeat); + } - if (skeleton) { - glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3); - glBindTexture(GL_TEXTURE_2D, skeleton->tex_id); - state.using_skeleton = true; - } else { - state.using_skeleton = false; - } + if (ct->use_specular_cache) { + state.instance_data_array[r_index].flags |= FLAGS_DEFAULT_SPECULAR_MAP_USED; + } else { + state.instance_data_array[r_index].flags &= ~FLAGS_DEFAULT_SPECULAR_MAP_USED; } -#endif - Item *material_owner = p_ci->material_owner ? p_ci->material_owner : p_ci; + if (ct->use_normal_cache) { + state.instance_data_array[r_index].flags |= FLAGS_DEFAULT_NORMAL_MAP_USED; + } else { + state.instance_data_array[r_index].flags &= ~FLAGS_DEFAULT_NORMAL_MAP_USED; + } - RID material = material_owner->material; - RasterizerStorageGLES3::Material *material_ptr = storage->material_owner.get_or_null(material); + state.instance_data_array[r_index].specular_shininess = uint32_t(CLAMP(ct->specular_color.a * 255.0, 0, 255)) << 24; + state.instance_data_array[r_index].specular_shininess |= uint32_t(CLAMP(ct->specular_color.b * 255.0, 0, 255)) << 16; + state.instance_data_array[r_index].specular_shininess |= uint32_t(CLAMP(ct->specular_color.g * 255.0, 0, 255)) << 8; + state.instance_data_array[r_index].specular_shininess |= uint32_t(CLAMP(ct->specular_color.r * 255.0, 0, 255)); - if (material != r_ris.canvas_last_material || r_ris.rebind_shader) { - RasterizerStorageGLES3::Shader *shader_ptr = NULL; + r_texpixel_size.x = 1.0 / float(ct->size_cache.x); + r_texpixel_size.y = 1.0 / float(ct->size_cache.y); - if (material_ptr) { - shader_ptr = material_ptr->shader; + state.instance_data_array[r_index].color_texture_pixel_size[0] = r_texpixel_size.x; + state.instance_data_array[r_index].color_texture_pixel_size[1] = r_texpixel_size.y; - if (shader_ptr && shader_ptr->mode != RS::SHADER_CANVAS_ITEM) { - shader_ptr = NULL; // not a canvas item shader, don't use. - } - } + r_last_texture = p_texture; +} - if (shader_ptr) { - if (shader_ptr->canvas_item.uses_screen_texture) { - if (!state.canvas_texscreen_used) { - //copy if not copied before - _copy_texscreen(Rect2()); +void RasterizerCanvasGLES3::_set_uniforms() { +} - // blend mode will have been enabled so make sure we disable it again later on - //last_blend_mode = last_blend_mode != RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_DISABLED ? last_blend_mode : -1; - } +void RasterizerCanvasGLES3::reset_canvas() { + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_SCISSOR_TEST); + glDisable(GL_DITHER); + glEnable(GL_BLEND); - if (storage->frame.current_rt->copy_screen_effect.color) { - glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4); - glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->copy_screen_effect.color); - } + // Default to Mix. + glBlendEquation(GL_FUNC_ADD); + if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) { + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } else { + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE); + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} + +void RasterizerCanvasGLES3::canvas_debug_viewport_shadows(Light *p_lights_with_shadow) { +} + +void RasterizerCanvasGLES3::canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache) { +} + +void RasterizerCanvasGLES3::draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) { +} + +RendererCanvasRender::PolygonID RasterizerCanvasGLES3::request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights) { + // We interleave the vertex data into one big VBO to improve cache coherence + uint32_t vertex_count = p_points.size(); + uint32_t stride = 2; + if ((uint32_t)p_colors.size() == vertex_count) { + stride += 4; + } + if ((uint32_t)p_uvs.size() == vertex_count) { + stride += 2; + } + if ((uint32_t)p_bones.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) { + stride += 4; + } + + PolygonBuffers pb; + glGenBuffers(1, &pb.vertex_buffer); + glGenVertexArrays(1, &pb.vertex_array); + glBindVertexArray(pb.vertex_array); + pb.count = vertex_count; + pb.index_buffer = 0; + + uint32_t buffer_size = stride * p_points.size(); + + Vector<uint8_t> polygon_buffer; + polygon_buffer.resize(buffer_size * sizeof(float)); + { + glBindBuffer(GL_ARRAY_BUFFER, pb.vertex_buffer); + glBufferData(GL_ARRAY_BUFFER, stride * vertex_count * sizeof(float), nullptr, GL_STATIC_DRAW); // TODO may not be necessary + const uint8_t *r = polygon_buffer.ptr(); + float *fptr = (float *)r; + uint32_t *uptr = (uint32_t *)r; + uint32_t base_offset = 0; + { + // Always uses vertex positions + glEnableVertexAttribArray(RS::ARRAY_VERTEX); + glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), NULL); + const Vector2 *points_ptr = p_points.ptr(); + + for (uint32_t i = 0; i < vertex_count; i++) { + fptr[base_offset + i * stride + 0] = points_ptr[i].x; + fptr[base_offset + i * stride + 1] = points_ptr[i].y; } - if (shader_ptr != r_ris.shader_cache) { - if (shader_ptr->canvas_item.uses_time) { - RenderingServerDefault::redraw_request(); - } + base_offset += 2; + } - state.canvas_shader.set_custom_shader(shader_ptr->custom_code_id); - state.canvas_shader.bind(); + // Next add colors + if (p_colors.size() == 1) { + glDisableVertexAttribArray(RS::ARRAY_COLOR); + Color m = p_colors[0]; + glVertexAttrib4f(RS::ARRAY_COLOR, m.r, m.g, m.b, m.a); + } else if ((uint32_t)p_colors.size() == vertex_count) { + glEnableVertexAttribArray(RS::ARRAY_COLOR); + glVertexAttribPointer(RS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(base_offset * sizeof(float))); + + const Color *color_ptr = p_colors.ptr(); + + for (uint32_t i = 0; i < vertex_count; i++) { + fptr[base_offset + i * stride + 0] = color_ptr[i].r; + fptr[base_offset + i * stride + 1] = color_ptr[i].g; + fptr[base_offset + i * stride + 2] = color_ptr[i].b; + fptr[base_offset + i * stride + 3] = color_ptr[i].a; } + base_offset += 4; + } else { + glDisableVertexAttribArray(RS::ARRAY_COLOR); + glVertexAttrib4f(RS::ARRAY_COLOR, 1.0, 1.0, 1.0, 1.0); + } - int tc = material_ptr->textures.size(); - Pair<StringName, RID> *textures = material_ptr->textures.ptrw(); - - ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = shader_ptr->texture_hints.ptrw(); - - for (int i = 0; i < tc; i++) { - glActiveTexture(GL_TEXTURE0 + i); - - RasterizerStorageGLES3::Texture *t = storage->texture_owner.get_or_null(textures[i].second); - - if (!t) { - switch (texture_hints[i]) { - case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO: - case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: { - glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex); - } break; - case ShaderLanguage::ShaderNode::Uniform::HINT_ANISOTROPY: { - glBindTexture(GL_TEXTURE_2D, storage->resources.aniso_tex); - } break; - case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: { - glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex); - } break; - default: { - glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); - } break; - } + if ((uint32_t)p_uvs.size() == vertex_count) { + glEnableVertexAttribArray(RS::ARRAY_TEX_UV); + glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(base_offset * sizeof(float))); - continue; - } + const Vector2 *uv_ptr = p_uvs.ptr(); - if (t->redraw_if_visible) { - RenderingServerDefault::redraw_request(); - } + for (uint32_t i = 0; i < vertex_count; i++) { + fptr[base_offset + i * stride + 0] = uv_ptr[i].x; + fptr[base_offset + i * stride + 1] = uv_ptr[i].y; + } - t = t->get_ptr(); + base_offset += 2; + } else { + glDisableVertexAttribArray(RS::ARRAY_TEX_UV); + } -#ifdef TOOLS_ENABLED - if (t->detect_normal && texture_hints[i] == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL) { - t->detect_normal(t->detect_normal_ud); - } -#endif - if (t->render_target) - t->render_target->used_in_frame = true; + if ((uint32_t)p_indices.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) { + glEnableVertexAttribArray(RS::ARRAY_BONES); + glVertexAttribPointer(RS::ARRAY_BONES, 4, GL_UNSIGNED_INT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(base_offset * sizeof(float))); - glBindTexture(t->target, t->tex_id); + const int *bone_ptr = p_bones.ptr(); + + for (uint32_t i = 0; i < vertex_count; i++) { + uint16_t *bone16w = (uint16_t *)&uptr[base_offset + i * stride]; + + bone16w[0] = bone_ptr[i * 4 + 0]; + bone16w[1] = bone_ptr[i * 4 + 1]; + bone16w[2] = bone_ptr[i * 4 + 2]; + bone16w[3] = bone_ptr[i * 4 + 3]; } + base_offset += 2; } else { - state.canvas_shader.set_custom_shader(0); - state.canvas_shader.bind(); + glDisableVertexAttribArray(RS::ARRAY_BONES); } - state.canvas_shader.use_material((void *)material_ptr); - r_ris.shader_cache = shader_ptr; + if ((uint32_t)p_weights.size() == vertex_count * 4) { + glEnableVertexAttribArray(RS::ARRAY_WEIGHTS); + glVertexAttribPointer(RS::ARRAY_WEIGHTS, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(base_offset * sizeof(float))); - r_ris.canvas_last_material = material; + const float *weight_ptr = p_weights.ptr(); - r_ris.rebind_shader = false; - } + for (uint32_t i = 0; i < vertex_count; i++) { + uint16_t *weight16w = (uint16_t *)&uptr[base_offset + i * stride]; - int blend_mode = r_ris.shader_cache ? r_ris.shader_cache->canvas_item.blend_mode : RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_MIX; - bool unshaded = r_ris.shader_cache && (r_ris.shader_cache->canvas_item.light_mode == RasterizerStorageGLES3::Shader::CanvasItem::LIGHT_MODE_UNSHADED || (blend_mode != RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_MIX && blend_mode != RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_PMALPHA)); - bool reclip = false; + weight16w[0] = CLAMP(weight_ptr[i * 4 + 0] * 65535, 0, 65535); + weight16w[1] = CLAMP(weight_ptr[i * 4 + 1] * 65535, 0, 65535); + weight16w[2] = CLAMP(weight_ptr[i * 4 + 2] * 65535, 0, 65535); + weight16w[3] = CLAMP(weight_ptr[i * 4 + 3] * 65535, 0, 65535); + } - if (r_ris.last_blend_mode != blend_mode) { - switch (blend_mode) { - case RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_MIX: { - glBlendEquation(GL_FUNC_ADD); - if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) { - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } else { - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE); - } + base_offset += 2; + } else { + glDisableVertexAttribArray(RS::ARRAY_WEIGHTS); + } - } break; - case RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_ADD: { - glBlendEquation(GL_FUNC_ADD); - if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) { - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_SRC_ALPHA, GL_ONE); - } else { - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE); - } + ERR_FAIL_COND_V(base_offset != stride, 0); + glBufferData(GL_ARRAY_BUFFER, vertex_count * stride * sizeof(float), polygon_buffer.ptr(), GL_STATIC_DRAW); + } - } break; - case RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_SUB: { - glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); - if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) { - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_SRC_ALPHA, GL_ONE); - } else { - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE); - } - } break; - case RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_MUL: { - glBlendEquation(GL_FUNC_ADD); - if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) { - glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_DST_ALPHA, GL_ZERO); - } else { - glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_ZERO, GL_ONE); - } - } break; - case RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_PMALPHA: { - glBlendEquation(GL_FUNC_ADD); - if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) { - glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } else { - glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE); - } - } break; + if (p_indices.size()) { + //create indices, as indices were requested + Vector<uint8_t> index_buffer; + index_buffer.resize(p_indices.size() * sizeof(int32_t)); + { + uint8_t *w = index_buffer.ptrw(); + memcpy(w, p_indices.ptr(), sizeof(int32_t) * p_indices.size()); } + glGenBuffers(1, &pb.index_buffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pb.index_buffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_indices.size() * 4, nullptr, GL_STATIC_DRAW); // TODO may not be necessary + glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_indices.size() * 4, index_buffer.ptr(), GL_STATIC_DRAW); + pb.count = p_indices.size(); } - state.uniforms.final_modulate = unshaded ? p_ci->final_modulate : Color(p_ci->final_modulate.r * r_ris.item_group_modulate.r, p_ci->final_modulate.g * r_ris.item_group_modulate.g, p_ci->final_modulate.b * r_ris.item_group_modulate.b, p_ci->final_modulate.a * r_ris.item_group_modulate.a); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - state.uniforms.modelview_matrix = p_ci->final_transform; - state.uniforms.extra_matrix = Transform2D(); + PolygonID id = polygon_buffers.last_id++; - _set_uniforms(); + polygon_buffers.polygons[id] = pb; - if (unshaded || (state.uniforms.final_modulate.a > 0.001 && (!r_ris.shader_cache || r_ris.shader_cache->canvas_item.light_mode != RasterizerStorageGLES3::Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY) && !p_ci->light_masked)) - _legacy_canvas_item_render_commands(p_ci, NULL, reclip, material_ptr); + return id; +} +void RasterizerCanvasGLES3::free_polygon(PolygonID p_polygon) { + PolygonBuffers *pb_ptr = polygon_buffers.polygons.getptr(p_polygon); + ERR_FAIL_COND(!pb_ptr); - r_ris.rebind_shader = true; // hacked in for now. + PolygonBuffers &pb = *pb_ptr; - if ((blend_mode == RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_MIX || blend_mode == RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_PMALPHA) && r_ris.item_group_light && !unshaded) { - Light *light = r_ris.item_group_light; - bool light_used = false; - RS::CanvasLightBlendMode bmode = RS::CANVAS_LIGHT_BLEND_MODE_ADD; - state.uniforms.final_modulate = p_ci->final_modulate; // remove the canvas modulate + if (pb.index_buffer != 0) { + glDeleteBuffers(1, &pb.index_buffer); + } - while (light) { - if (p_ci->light_mask & light->item_mask && r_ris.item_group_z >= light->z_min && r_ris.item_group_z <= light->z_max && p_ci->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) { - //intersects this light + glDeleteVertexArrays(1, &pb.vertex_array); + glDeleteBuffers(1, &pb.vertex_buffer); - if (!light_used || bmode != light->blend_mode) { - bmode = light->blend_mode; + polygon_buffers.polygons.erase(p_polygon); +} - switch (bmode) { - case RS::CANVAS_LIGHT_BLEND_MODE_ADD: { - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); +// Creates a new uniform buffer and uses it right away +// This expands the instance buffer continually +// In theory allocations can reach as high as number_of_draw_calls * 3 frames +// because OpenGL can start rendering subsequent frames before finishing the current one +void RasterizerCanvasGLES3::_allocate_instance_data_buffer() { + GLuint new_buffer; + glGenBuffers(1, &new_buffer); + glBindBuffer(GL_UNIFORM_BUFFER, new_buffer); + glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData) * state.max_instances_per_batch, nullptr, GL_DYNAMIC_DRAW); + state.current_buffer = (state.current_buffer + 1); + state.canvas_instance_data_buffers.insert(state.current_buffer, new_buffer); + state.fences.insert(state.current_buffer, GLsync()); + state.current_buffer = state.current_buffer % state.canvas_instance_data_buffers.size(); + glBindBuffer(GL_UNIFORM_BUFFER, 0); +} - } break; - case RS::CANVAS_LIGHT_BLEND_MODE_SUB: { - glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - } break; - case RS::CANVAS_LIGHT_BLEND_MODE_MIX: { - // case RS::CANVAS_LIGHT_MODE_MASK: { - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +void RasterizerCanvasGLES3::initialize() { + // quad buffer + { + glGenBuffers(1, &data.canvas_quad_vertices); + glBindBuffer(GL_ARRAY_BUFFER, data.canvas_quad_vertices); - } break; - } - } + const float qv[8] = { + 0, 0, + 0, 1, + 1, 1, + 1, 0 + }; - if (!light_used) { - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_LIGHTING, true); - light_used = true; - } + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, qv, GL_STATIC_DRAW); - // FTODO - //bool has_shadow = light->shadow_buffer.is_valid() && p_ci->light_mask & light->item_shadow_mask; - bool has_shadow = light->use_shadow && p_ci->light_mask & light->item_shadow_mask; - - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SHADOWS, has_shadow); - if (has_shadow) { - // FTODO - //state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_USE_GRADIENT, light->shadow_gradient_length > 0); - state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_USE_GRADIENT, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_NEAREST, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_NONE); - //state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF3, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF3); - state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF3, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF5, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF5); - state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF7, false); - //state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF7, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF7); - //state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF9, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF9); - state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF9, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF13, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF13); - } + glBindBuffer(GL_ARRAY_BUFFER, 0); - state.canvas_shader.bind(); - state.using_light = light; - state.using_shadow = has_shadow; + glGenVertexArrays(1, &data.canvas_quad_array); + glBindVertexArray(data.canvas_quad_array); + glBindBuffer(GL_ARRAY_BUFFER, data.canvas_quad_vertices); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, nullptr); + glEnableVertexAttribArray(0); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind + } - //always re-set uniforms, since light parameters changed - _set_uniforms(); - state.canvas_shader.use_material((void *)material_ptr); + { + //particle quad buffers + + glGenBuffers(1, &data.particle_quad_vertices); + glBindBuffer(GL_ARRAY_BUFFER, data.particle_quad_vertices); + { + //quad of size 1, with pivot on the center for particles, then regular UVS. Color is general plus fetched from particle + const float qv[16] = { + -0.5, -0.5, + 0.0, 0.0, + -0.5, 0.5, + 0.0, 1.0, + 0.5, 0.5, + 1.0, 1.0, + 0.5, -0.5, + 1.0, 0.0 + }; + + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 16, qv, GL_STATIC_DRAW); + } - glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 6); - RasterizerStorageGLES3::Texture *t = storage->texture_owner.get_or_null(light->texture); - if (!t) { - glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); - } else { - t = t->get_ptr(); + glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind + + glGenVertexArrays(1, &data.particle_quad_array); + glBindVertexArray(data.particle_quad_array); + glBindBuffer(GL_ARRAY_BUFFER, data.particle_quad_vertices); + glEnableVertexAttribArray(RS::ARRAY_VERTEX); + glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, nullptr); + glEnableVertexAttribArray(RS::ARRAY_TEX_UV); + glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, CAST_INT_TO_UCHAR_PTR(8)); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind + } - glBindTexture(t->target, t->tex_id); - } + // ninepatch buffers + { + // array buffer + glGenBuffers(1, &data.ninepatch_vertices); + glBindBuffer(GL_ARRAY_BUFFER, data.ninepatch_vertices); - glActiveTexture(GL_TEXTURE0); - _legacy_canvas_item_render_commands(p_ci, NULL, reclip, material_ptr); //redraw using light + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * (16 + 16) * 2, NULL, GL_DYNAMIC_DRAW); - state.using_light = NULL; - } + glBindBuffer(GL_ARRAY_BUFFER, 0); - light = light->next_ptr; - } + // element buffer + glGenBuffers(1, &data.ninepatch_elements); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ninepatch_elements); - if (light_used) { - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_LIGHTING, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SHADOWS, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_NEAREST, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF3, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF5, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF7, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF9, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF13, false); +#define _EIDX(y, x) (y * 4 + x) + uint8_t elems[3 * 2 * 9] = { + // first row - state.canvas_shader.bind(); + _EIDX(0, 0), _EIDX(0, 1), _EIDX(1, 1), + _EIDX(1, 1), _EIDX(1, 0), _EIDX(0, 0), - r_ris.last_blend_mode = -1; + _EIDX(0, 1), _EIDX(0, 2), _EIDX(1, 2), + _EIDX(1, 2), _EIDX(1, 1), _EIDX(0, 1), -#if 0 - //this is set again, so it should not be needed anyway? - state.canvas_item_modulate = unshaded ? ci->final_modulate : Color(ci->final_modulate.r * p_modulate.r, ci->final_modulate.g * p_modulate.g, ci->final_modulate.b * p_modulate.b, ci->final_modulate.a * p_modulate.a); + _EIDX(0, 2), _EIDX(0, 3), _EIDX(1, 3), + _EIDX(1, 3), _EIDX(1, 2), _EIDX(0, 2), - state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.final_transform); - state.canvas_shader.set_uniform(CanvasShaderGLES3::EXTRA_MATRIX, Transform2D()); - state.canvas_shader.set_uniform(CanvasShaderGLES3::FINAL_MODULATE, state.canvas_item_modulate); + // second row - glBlendEquation(GL_FUNC_ADD); + _EIDX(1, 0), _EIDX(1, 1), _EIDX(2, 1), + _EIDX(2, 1), _EIDX(2, 0), _EIDX(1, 0), - if (storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) { - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } else { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } + // the center one would be here, but we'll put it at the end + // so it's easier to disable the center and be able to use + // one draw call for both - //@TODO RESET canvas_blend_mode -#endif - } + _EIDX(1, 2), _EIDX(1, 3), _EIDX(2, 3), + _EIDX(2, 3), _EIDX(2, 2), _EIDX(1, 2), + + // third row + + _EIDX(2, 0), _EIDX(2, 1), _EIDX(3, 1), + _EIDX(3, 1), _EIDX(3, 0), _EIDX(2, 0), + + _EIDX(2, 1), _EIDX(2, 2), _EIDX(3, 2), + _EIDX(3, 2), _EIDX(3, 1), _EIDX(2, 1), + + _EIDX(2, 2), _EIDX(2, 3), _EIDX(3, 3), + _EIDX(3, 3), _EIDX(3, 2), _EIDX(2, 2), + + // center field + + _EIDX(1, 1), _EIDX(1, 2), _EIDX(2, 2), + _EIDX(2, 2), _EIDX(2, 1), _EIDX(1, 1) + }; +#undef _EIDX + + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elems), elems, GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } - if (reclip) { - glEnable(GL_SCISSOR_TEST); - int y = storage->frame.current_rt->height - (r_ris.current_clip->final_clip_rect.position.y + r_ris.current_clip->final_clip_rect.size.y); - // FTODO - // if (storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_VFLIP]) - // y = r_ris.current_clip->final_clip_rect.position.y; - glScissor(r_ris.current_clip->final_clip_rect.position.x, y, r_ris.current_clip->final_clip_rect.size.width, r_ris.current_clip->final_clip_rect.size.height); + //state.canvas_shadow_shader.init(); + + int uniform_max_size; + glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &uniform_max_size); + if (uniform_max_size < 65536) { + state.max_lights_per_render = 64; + state.max_instances_per_batch = 128; + } else { + state.max_lights_per_render = 256; + state.max_instances_per_batch = 512; } -} -void RasterizerCanvasGLES3::gl_enable_scissor(int p_x, int p_y, int p_width, int p_height) const { - glEnable(GL_SCISSOR_TEST); - glScissor(p_x, p_y, p_width, p_height); -} + // Reserve 64 Uniform Buffers for instance data + state.canvas_instance_data_buffers.resize(64); + state.fences.resize(64); + glGenBuffers(64, state.canvas_instance_data_buffers.ptr()); + for (int i = 0; i < 64; i++) { + glBindBuffer(GL_UNIFORM_BUFFER, state.canvas_instance_data_buffers[i]); + glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData) * state.max_instances_per_batch, nullptr, GL_DYNAMIC_DRAW); + } + glBindBuffer(GL_UNIFORM_BUFFER, 0); -void RasterizerCanvasGLES3::gl_disable_scissor() const { - glDisable(GL_SCISSOR_TEST); -} + state.instance_data_array = memnew_arr(InstanceData, state.max_instances_per_batch); -void RasterizerCanvasGLES3::initialize() { - RasterizerCanvasBaseGLES3::initialize(); + glGenBuffers(1, &state.canvas_state_buffer); + glBindBuffer(GL_UNIFORM_BUFFER, state.canvas_state_buffer); + glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), nullptr, GL_STREAM_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, 0); - batch_initialize(); + String global_defines; + global_defines += "#define MAX_GLOBAL_VARIABLES 256\n"; // TODO: this is arbitrary for now + global_defines += "#define MAX_LIGHTS " + itos(state.max_instances_per_batch) + "\n"; + global_defines += "#define MAX_DRAW_DATA_INSTANCES " + itos(state.max_instances_per_batch) + "\n"; - // just reserve some space (may not be needed as we are orphaning, but hey ho) - glGenBuffers(1, &bdata.gl_vertex_buffer); + state.canvas_shader.initialize(global_defines); + state.canvas_shader_default_version = state.canvas_shader.version_create(); + state.canvas_shader.version_bind_shader(state.canvas_shader_default_version, CanvasShaderGLES3::MODE_QUAD); - if (bdata.vertex_buffer_size_bytes) { - glBindBuffer(GL_ARRAY_BUFFER, bdata.gl_vertex_buffer); - glBufferData(GL_ARRAY_BUFFER, bdata.vertex_buffer_size_bytes, NULL, GL_DYNAMIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); + //state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_RGBA_SHADOWS, storage->config.use_rgba_2d_shadows); - // pre fill index buffer, the indices never need to change so can be static - glGenBuffers(1, &bdata.gl_index_buffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bdata.gl_index_buffer); - - Vector<uint16_t> indices; - indices.resize(bdata.index_buffer_size_units); - - for (unsigned int q = 0; q < bdata.max_quads; q++) { - int i_pos = q * 6; // 6 inds per quad - int q_pos = q * 4; // 4 verts per quad - indices.set(i_pos, q_pos); - indices.set(i_pos + 1, q_pos + 1); - indices.set(i_pos + 2, q_pos + 2); - indices.set(i_pos + 3, q_pos); - indices.set(i_pos + 4, q_pos + 2); - indices.set(i_pos + 5, q_pos + 3); - - // we can only use 16 bit indices in OpenGL! -#ifdef DEBUG_ENABLED - CRASH_COND((q_pos + 3) > 65535); -#endif - } + //state.canvas_shader.bind(); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, bdata.index_buffer_size_bytes, &indices[0], GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + //state.lens_shader.init(); + + //state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/quality/2d/use_pixel_snap", false)); - } // only if there is a vertex buffer (batching is on) + { + default_canvas_group_shader = storage->shader_allocate(); + storage->shader_initialize(default_canvas_group_shader); + + storage->shader_set_code(default_canvas_group_shader, R"( +// Default CanvasGroup shader. + +shader_type canvas_item; + +void fragment() { + vec4 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0); + + if (c.a > 0.0001) { + c.rgb /= c.a; + } + + COLOR *= c; +} +)"); + default_canvas_group_material = storage->material_allocate(); + storage->material_initialize(default_canvas_group_material); + + storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader); + } + + default_canvas_texture = storage->canvas_texture_allocate(); + storage->canvas_texture_initialize(default_canvas_texture); + + state.using_light = NULL; + state.using_transparent_rt = false; + state.using_skeleton = false; + state.current_shader_version = state.canvas_shader_default_version; } RasterizerCanvasGLES3::RasterizerCanvasGLES3() { - batch_constructor(); +} +RasterizerCanvasGLES3::~RasterizerCanvasGLES3() { + state.canvas_shader.version_free(state.canvas_shader_default_version); + storage->free(default_canvas_group_material); + storage->free(default_canvas_group_shader); + storage->free(default_canvas_texture); +} + +void RasterizerCanvasGLES3::finalize() { + glDeleteBuffers(1, &data.canvas_quad_vertices); + glDeleteVertexArrays(1, &data.canvas_quad_array); + + glDeleteBuffers(1, &data.canvas_quad_vertices); + glDeleteVertexArrays(1, &data.canvas_quad_array); } -#endif // GLES3_BACKEND_ENABLED +#endif // GLES3_ENABLED diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h index 5e85f84bde..908d79f9f8 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.h +++ b/drivers/gles3/rasterizer_canvas_gles3.h @@ -31,41 +31,251 @@ #ifndef RASTERIZER_CANVAS_OPENGL_H #define RASTERIZER_CANVAS_OPENGL_H -#include "drivers/gles3/rasterizer_platforms.h" -#ifdef GLES3_BACKEND_ENABLED +#ifdef GLES3_ENABLED -#include "drivers/gles3/rasterizer_canvas_batcher.h" -#include "rasterizer_canvas_base_gles3.h" +#include "rasterizer_scene_gles3.h" +#include "rasterizer_storage_gles3.h" +#include "servers/rendering/renderer_canvas_render.h" +#include "servers/rendering/renderer_compositor.h" + +#include "shaders/canvas.glsl.gen.h" class RasterizerSceneGLES3; -class RasterizerCanvasGLES3 : public RasterizerCanvasBaseGLES3, public RasterizerCanvasBatcher<RasterizerCanvasGLES3, RasterizerStorageGLES3> { - friend class RasterizerCanvasBatcher<RasterizerCanvasGLES3, RasterizerStorageGLES3>; +class RasterizerCanvasGLES3 : public RendererCanvasRender { + _FORCE_INLINE_ void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4); + _FORCE_INLINE_ void _update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3); + + _FORCE_INLINE_ void _update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4); + _FORCE_INLINE_ void _update_transform_to_mat4(const Transform3D &p_transform, float *p_mat4); + + enum { + BASE_UNIFORM_BUFFER_OBJECT = 0, + MATERIAL_UNIFORM_BUFFER_OBJECT = 1, + TRANSFORMS_UNIFORM_BUFFER_OBJECT = 2, + CANVAS_TEXTURE_UNIFORM_BUFFER_OBJECT = 3, + }; + + enum { + + FLAGS_INSTANCING_MASK = 0x7F, + FLAGS_INSTANCING_HAS_COLORS = (1 << 7), + FLAGS_INSTANCING_HAS_CUSTOM_DATA = (1 << 8), + + FLAGS_CLIP_RECT_UV = (1 << 9), + FLAGS_TRANSPOSE_RECT = (1 << 10), -private: - // legacy codepath .. to remove after testing - void _legacy_canvas_render_item(Item *p_ci, RenderItemState &r_ris); + FLAGS_NINEPACH_DRAW_CENTER = (1 << 12), + FLAGS_USING_PARTICLES = (1 << 13), - // high level batch funcs - void canvas_render_items_implementation(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform); - void render_batches(Item::Command *const *p_commands, Item *p_current_clip, bool &r_reclip, RasterizerStorageGLES3::Material *p_material); + FLAGS_USE_SKELETON = (1 << 15), + FLAGS_NINEPATCH_H_MODE_SHIFT = 16, + FLAGS_NINEPATCH_V_MODE_SHIFT = 18, + FLAGS_LIGHT_COUNT_SHIFT = 20, - // funcs used from rasterizer_canvas_batcher template - void gl_enable_scissor(int p_x, int p_y, int p_width, int p_height) const; - void gl_disable_scissor() const; + FLAGS_DEFAULT_NORMAL_MAP_USED = (1 << 26), + FLAGS_DEFAULT_SPECULAR_MAP_USED = (1 << 27), + + FLAGS_USE_MSDF = (1 << 28), + }; + + enum { + LIGHT_FLAGS_TEXTURE_MASK = 0xFFFF, + LIGHT_FLAGS_BLEND_SHIFT = 16, + LIGHT_FLAGS_BLEND_MASK = (3 << 16), + LIGHT_FLAGS_BLEND_MODE_ADD = (0 << 16), + LIGHT_FLAGS_BLEND_MODE_SUB = (1 << 16), + LIGHT_FLAGS_BLEND_MODE_MIX = (2 << 16), + LIGHT_FLAGS_BLEND_MODE_MASK = (3 << 16), + LIGHT_FLAGS_HAS_SHADOW = (1 << 20), + LIGHT_FLAGS_FILTER_SHIFT = 22 + + }; + + enum { + MAX_RENDER_ITEMS = 256 * 1024, + MAX_LIGHT_TEXTURES = 1024, + MAX_LIGHTS_PER_ITEM = 16, + DEFAULT_MAX_LIGHTS_PER_RENDER = 256, + }; public: - void canvas_render_items_begin(const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform); - void canvas_render_items_end(); - void canvas_render_items_internal(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform); - void canvas_begin() override; - void canvas_end() override; + struct StateBuffer { + float canvas_transform[16]; + float screen_transform[16]; + float canvas_normal_transform[16]; + float canvas_modulate[4]; + + float screen_pixel_size[2]; + float time; + uint32_t use_pixel_snap; + + float sdf_to_tex[4]; + float sdf_to_screen[2]; + float screen_to_sdf[2]; + + uint32_t directional_light_count; + float tex_to_sdf; + uint32_t pad1; + uint32_t pad2; + }; + + struct InstanceData { + float world[6]; + float color_texture_pixel_size[2]; + union { + //rect + struct { + float modulation[4]; + union { + float msdf[4]; + float ninepatch_margins[4]; + }; + float dst_rect[4]; + float src_rect[4]; + float pad[2]; + }; + //primitive + struct { + float points[6]; // vec2 points[3] + float uvs[6]; // vec2 points[3] + uint32_t colors[6]; // colors encoded as half + }; + }; + uint32_t flags; + uint32_t specular_shininess; + uint32_t lights[4]; + }; + + struct Data { + GLuint canvas_quad_vertices; + GLuint canvas_quad_array; + + GLuint particle_quad_vertices; + GLuint particle_quad_array; + + GLuint ninepatch_vertices; + GLuint ninepatch_elements; + } data; + + struct State { + GLuint canvas_state_buffer; + LocalVector<GLuint> canvas_instance_data_buffers; + LocalVector<GLsync> fences; + uint32_t current_buffer = 0; + + InstanceData *instance_data_array; + bool canvas_texscreen_used; + CanvasShaderGLES3 canvas_shader; + RID canvas_shader_current_version; + RID canvas_shader_default_version; + //CanvasShadowShaderGLES3 canvas_shadow_shader; + //LensDistortedShaderGLES3 lens_shader; + + bool using_texture_rect; + + bool using_ninepatch; + bool using_skeleton; + + Transform2D skeleton_transform; + Transform2D skeleton_transform_inverse; + Size2i skeleton_texture_size; + + RID current_tex = RID(); + RID current_normal = RID(); + RID current_specular = RID(); + RasterizerStorageGLES3::Texture *current_tex_ptr; + RID current_shader_version = RID(); + RS::PrimitiveType current_primitive = RS::PRIMITIVE_MAX; + uint32_t current_primitive_points = 0; + Item::Command::Type current_command = Item::Command::TYPE_RECT; + + bool end_batch = false; + + Transform3D vp; + Light *using_light; + bool using_shadow; + bool using_transparent_rt; + + // FROM RD Renderer + + uint32_t max_lights_per_render; + uint32_t max_lights_per_item; + uint32_t max_instances_per_batch; + + RS::CanvasItemTextureFilter default_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT; + RS::CanvasItemTextureRepeat default_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT; + } state; + + Item *items[MAX_RENDER_ITEMS]; + + RID default_canvas_texture; + RID default_canvas_group_material; + RID default_canvas_group_shader; + + typedef void Texture; + + RasterizerSceneGLES3 *scene_render; + + RasterizerStorageGLES3 *storage; + + void _set_uniforms(); + + void canvas_begin(); + void canvas_end(); + + //virtual void draw_window_margins(int *black_margin, RID *black_image) override; + void draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample); + + virtual void reset_canvas(); + virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache); + + virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) override; + + RID light_create() override; + void light_set_texture(RID p_rid, RID p_texture) override; + void light_set_use_shadow(RID p_rid, bool p_enable) override; + void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) override; + void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) override; + + void render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) override; + RID occluder_polygon_create() override; + void occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) override; + void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) override; + void set_shadow_texture_size(int p_size) override; + + bool free(RID p_rid) override; + void update() override; + + void _bind_canvas_texture(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, uint32_t &r_index, RID &r_last_texture, Size2 &r_texpixel_size); + + struct PolygonBuffers { + GLuint vertex_buffer; + GLuint vertex_array; + GLuint index_buffer; + int count; + }; + + struct { + HashMap<PolygonID, PolygonBuffers> polygons; + PolygonID last_id; + } polygon_buffers; + + RendererCanvasRender::PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()) override; + void free_polygon(PolygonID p_polygon) override; void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) override; + void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer = false); + void _render_item(RID p_render_target, const Item *p_item, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, uint32_t &r_index); + void _render_batch(uint32_t &p_max_index); + void _end_batch(uint32_t &p_max_index); + void _allocate_instance_data_buffer(); void initialize(); + void finalize(); RasterizerCanvasGLES3(); + ~RasterizerCanvasGLES3(); }; -#endif // GLES3_BACKEND_ENABLED +#endif // GLES3_ENABLED #endif // RASTERIZER_CANVAS_OPENGL_H diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 0840d03e44..32ead8aa7e 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -30,8 +30,7 @@ #include "rasterizer_gles3.h" -#ifdef GLES3_BACKEND_ENABLED -#include "shader_gles3.h" +#ifdef GLES3_ENABLED #include "core/config/project_settings.h" #include "core/os/os.h" @@ -91,21 +90,12 @@ void RasterizerGLES3::begin_frame(double frame_step) { frame++; delta = frame_step; - // from 3.2 - time_total += frame_step * time_scale; - - if (frame_step == 0) { - //to avoid hiccups - frame_step = 0.001; - } + time_total += frame_step; double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs"); time_total = Math::fmod(time_total, time_roll_over); - storage.frame.time[0] = time_total; - storage.frame.time[1] = Math::fmod(time_total, 3600); - storage.frame.time[2] = Math::fmod(time_total, 900); - storage.frame.time[3] = Math::fmod(time_total, 60); + storage.frame.time = time_total; storage.frame.count++; storage.frame.delta = frame_step; @@ -131,10 +121,11 @@ void RasterizerGLES3::end_frame(bool p_swap_buffers) { // glClearColor(1, 0, 0, 1); // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - if (p_swap_buffers) + if (p_swap_buffers) { DisplayServer::get_singleton()->swap_buffers(); - else + } else { glFinish(); + } } #ifdef CAN_DEBUG @@ -272,32 +263,22 @@ RasterizerGLES3::RasterizerGLES3() { void RasterizerGLES3::prepare_for_blitting_render_targets() { } -void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect) { +void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, DisplayServer::WindowID p_screen, const Rect2 &p_screen_rect) { ERR_FAIL_COND(storage.frame.current_rt); - // print_line("_blit_render_target_to_screen " + itos (p_screen) + ", rect " + String(Variant(p_screen_rect))); - RasterizerStorageGLES3::RenderTarget *rt = storage.render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); - canvas._set_texture_rect_mode(true); - canvas.state.canvas_shader.set_custom_shader(0); - canvas.state.canvas_shader.bind(); - - canvas.canvas_begin(); + // TODO: do we need a keep 3d linear option? - glDisable(GL_BLEND); - storage.bind_framebuffer_system(); - glActiveTexture(GL_TEXTURE0 + storage.config.max_texture_image_units - 1); if (rt->external.fbo != 0) { - glBindTexture(GL_TEXTURE_2D, rt->external.color); + glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->external.fbo); } else { - glBindTexture(GL_TEXTURE_2D, rt->color); + glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->fbo); } - canvas.draw_generic_textured_rect(p_screen_rect, Rect2(0, 0, 1, -1)); - glBindTexture(GL_TEXTURE_2D, 0); - - canvas.canvas_end(); + glReadBuffer(GL_COLOR_ATTACHMENT0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo); + glBlitFramebuffer(0, 0, rt->width, rt->height, 0, p_screen_rect.size.y, p_screen_rect.size.x, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST); } // is this p_screen useless in a multi window environment? @@ -313,7 +294,7 @@ void RasterizerGLES3::blit_render_targets_to_screen(DisplayServer::WindowID p_sc RID rid_rt = blit.render_target; Rect2 dst_rect = blit.dst_rect; - _blit_render_target_to_screen(rid_rt, dst_rect); + _blit_render_target_to_screen(rid_rt, p_screen, dst_rect); } } @@ -321,11 +302,10 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c if (p_image.is_null() || p_image->is_empty()) return; - int window_w = 640; //OS::get_singleton()->get_video_mode(0).width; - int window_h = 480; //OS::get_singleton()->get_video_mode(0).height; + Size2i win_size = DisplayServer::get_singleton()->screen_get_size(); glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, window_w, window_h); + glViewport(0, 0, win_size.width, win_size.height); glDisable(GL_BLEND); glDepthMask(GL_FALSE); if (false) { @@ -346,27 +326,26 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c Rect2 imgrect(0, 0, p_image->get_width(), p_image->get_height()); Rect2 screenrect; if (p_scale) { - if (window_w > window_h) { + if (win_size.width > win_size.height) { //scale horizontally - screenrect.size.y = window_h; - screenrect.size.x = imgrect.size.x * window_h / imgrect.size.y; - screenrect.position.x = (window_w - screenrect.size.x) / 2; + screenrect.size.y = win_size.height; + screenrect.size.x = imgrect.size.x * win_size.height / imgrect.size.y; + screenrect.position.x = (win_size.width - screenrect.size.x) / 2; } else { //scale vertically - screenrect.size.x = window_w; - screenrect.size.y = imgrect.size.y * window_w / imgrect.size.x; - screenrect.position.y = (window_h - screenrect.size.y) / 2; + screenrect.size.x = win_size.width; + screenrect.size.y = imgrect.size.y * win_size.width / imgrect.size.x; + screenrect.position.y = (win_size.height - screenrect.size.y) / 2; } } else { screenrect = imgrect; - screenrect.position += ((Size2(window_w, window_h) - screenrect.size) / 2.0).floor(); + screenrect.position += ((Size2(win_size.width, win_size.height) - screenrect.size) / 2.0).floor(); } RasterizerStorageGLES3::Texture *t = storage.texture_owner.get_or_null(texture); glActiveTexture(GL_TEXTURE0 + storage.config.max_texture_image_units - 1); glBindTexture(GL_TEXTURE_2D, t->tex_id); - canvas.draw_generic_textured_rect(screenrect, Rect2(0, 0, 1, 1)); glBindTexture(GL_TEXTURE_2D, 0); canvas.canvas_end(); @@ -375,4 +354,4 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c end_frame(true); } -#endif // GLES3_BACKEND_ENABLED +#endif // GLES3_ENABLED diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h index e2f3e0bdd0..a641e189c5 100644 --- a/drivers/gles3/rasterizer_gles3.h +++ b/drivers/gles3/rasterizer_gles3.h @@ -31,8 +31,7 @@ #ifndef RASTERIZER_OPENGL_H #define RASTERIZER_OPENGL_H -#include "drivers/gles3/rasterizer_platforms.h" -#ifdef GLES3_BACKEND_ENABLED +#ifdef GLES3_ENABLED #include "rasterizer_canvas_gles3.h" #include "rasterizer_scene_gles3.h" @@ -45,14 +44,13 @@ private: float delta = 0; double time_total = 0.0; - double time_scale = 1.0; protected: - RasterizerCanvasGLES3 canvas; RasterizerStorageGLES3 storage; + RasterizerCanvasGLES3 canvas; RasterizerSceneGLES3 scene; - void _blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect); + void _blit_render_target_to_screen(RID p_render_target, DisplayServer::WindowID p_screen, const Rect2 &p_screen_rect); public: RendererStorage *get_storage() { return &storage; } @@ -87,6 +85,6 @@ public: ~RasterizerGLES3() {} }; -#endif // GLES3_BACKEND_ENABLED +#endif // GLES3_ENABLED #endif diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 77e0366f0e..9e7d4f5435 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "rasterizer_scene_gles3.h" -#ifdef GLES3_BACKEND_ENABLED +#ifdef GLES3_ENABLED // TODO: 3D support not implemented yet. @@ -471,4 +471,4 @@ void RasterizerSceneGLES3::light_projectors_set_filter(RS::LightProjectorFilter RasterizerSceneGLES3::RasterizerSceneGLES3() { } -#endif // GLES3_BACKEND_ENABLED +#endif // GLES3_ENABLED diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 9b356f28df..b73c053bc7 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -31,8 +31,7 @@ #ifndef RASTERIZER_SCENE_OPENGL_H #define RASTERIZER_SCENE_OPENGL_H -#include "drivers/gles3/rasterizer_platforms.h" -#ifdef GLES3_BACKEND_ENABLED +#ifdef GLES3_ENABLED #include "core/math/camera_matrix.h" #include "core/templates/rid_owner.h" @@ -41,12 +40,11 @@ #include "servers/rendering/renderer_compositor.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering_server.h" -#include "shaders/scene.glsl.gen.h" class RasterizerSceneGLES3 : public RendererSceneRender { public: struct State { - SceneShaderGLES3 scene_shader; + //SceneShaderGLES3 scene_shader; } state; GeometryInstance *geometry_instance_create(RID p_base) override; @@ -227,6 +225,6 @@ public: RasterizerSceneGLES3(); }; -#endif // GLES3_BACKEND_ENABLED +#endif // GLES3_ENABLED #endif // RASTERIZER_SCENE_OPENGL_H diff --git a/drivers/gles3/rasterizer_storage_common.h b/drivers/gles3/rasterizer_storage_common.h deleted file mode 100644 index d9a756af1f..0000000000 --- a/drivers/gles3/rasterizer_storage_common.h +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************/ -/* rasterizer_storage_common.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef RASTERIZER_STORAGE_COMMON_H -#define RASTERIZER_STORAGE_COMMON_H - -class RasterizerStorageCommon { -public: - enum FVF { - FVF_UNBATCHED, - FVF_REGULAR, - FVF_COLOR, - FVF_LIGHT_ANGLE, - FVF_MODULATED, - FVF_LARGE, - }; - - // these flags are specifically for batching - // some of the logic is thus in rasterizer_storage.cpp - // we could alternatively set bitflags for each 'uses' and test on the fly - enum BatchFlags { - PREVENT_COLOR_BAKING = 1 << 0, - PREVENT_VERTEX_BAKING = 1 << 1, - - // custom vertex shaders using BUILTINS that vary per item - PREVENT_ITEM_JOINING = 1 << 2, - - USE_MODULATE_FVF = 1 << 3, - USE_LARGE_FVF = 1 << 4, - }; - - enum BatchType : uint16_t { - BT_DEFAULT = 0, - BT_RECT = 1, - BT_LINE = 2, - BT_LINE_AA = 3, - BT_POLY = 4, - BT_DUMMY = 5, // dummy batch is just used to keep the batch creation loop simple - }; - - enum BatchTypeFlags { - BTF_DEFAULT = 1 << BT_DEFAULT, - BTF_RECT = 1 << BT_RECT, - BTF_LINE = 1 << BT_LINE, - BTF_LINE_AA = 1 << BT_LINE_AA, - BTF_POLY = 1 << BT_POLY, - }; -}; - -#endif // RASTERIZER_STORAGE_COMMON_H diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index e010e55307..db449b7a08 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -28,14 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -//#define OPENGL_DISABLE_RENDER_TARGETS - #include "rasterizer_storage_gles3.h" -#ifdef GLES3_BACKEND_ENABLED +#ifdef GLES3_ENABLED #include "core/config/project_settings.h" #include "core/math/transform_3d.h" -#include "drivers/gles3/rasterizer_storage_common.h" #include "rasterizer_canvas_gles3.h" #include "rasterizer_scene_gles3.h" #include "servers/rendering/shader_language.h" @@ -1061,12 +1058,12 @@ void RasterizerStorageGLES3::_texture_set_state_from_flags(Texture *p_tex) { if (((p_tex->flags & TEXTURE_FLAG_REPEAT) || (p_tex->flags & TEXTURE_FLAG_MIRRORED_REPEAT)) && p_tex->target != GL_TEXTURE_CUBE_MAP) { if (p_tex->flags & TEXTURE_FLAG_MIRRORED_REPEAT) { - p_tex->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR); + p_tex->GLSetRepeat(p_tex->target, RS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR); } else { - p_tex->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + p_tex->GLSetRepeat(p_tex->target, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); } } else { - p_tex->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + p_tex->GLSetRepeat(p_tex->target, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); } } @@ -1285,21 +1282,43 @@ RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_ } RID RasterizerStorageGLES3::canvas_texture_allocate() { - return RID(); + return canvas_texture_owner.allocate_rid(); } void RasterizerStorageGLES3::canvas_texture_initialize(RID p_rid) { + canvas_texture_owner.initialize_rid(p_rid); } void RasterizerStorageGLES3::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) { + CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); + switch (p_channel) { + case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: { + ct->diffuse = p_texture; + } break; + case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: { + ct->normal_map = p_texture; + } break; + case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: { + ct->specular = p_texture; + } break; + } } -void RasterizerStorageGLES3::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) { +void RasterizerStorageGLES3::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) { + CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); + ct->specular_color.r = p_specular_color.r; + ct->specular_color.g = p_specular_color.g; + ct->specular_color.b = p_specular_color.b; + ct->specular_color.a = p_shininess; } -void RasterizerStorageGLES3::canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) { +void RasterizerStorageGLES3::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) { + CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); + ct->texture_filter = p_filter; } -void RasterizerStorageGLES3::canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) { +void RasterizerStorageGLES3::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) { + CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); + ct->texture_repeat = p_repeat; } RID RasterizerStorageGLES3::sky_create() { @@ -1309,169 +1328,14 @@ RID RasterizerStorageGLES3::sky_create() { } void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size) { - Sky *sky = sky_owner.get_or_null(p_sky); - ERR_FAIL_COND(!sky); - - if (sky->panorama.is_valid()) { - sky->panorama = RID(); - glDeleteTextures(1, &sky->radiance); - sky->radiance = 0; - } - - sky->panorama = p_panorama; - if (!sky->panorama.is_valid()) { - return; // the panorama was cleared - } - - Texture *texture = texture_owner.get_or_null(sky->panorama); - if (!texture) { - sky->panorama = RID(); - ERR_FAIL_COND(!texture); - } - - // glBindVertexArray(0) and more - { - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_BLEND); - - for (int i = 0; i < RS::ARRAY_MAX - 1; i++) { - //glDisableVertexAttribArray(i); - } - } - - glActiveTexture(GL_TEXTURE0); - glBindTexture(texture->target, texture->tex_id); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //need this for proper sampling - - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, resources.radical_inverse_vdc_cache_tex); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - // New cubemap that will hold the mipmaps with different roughness values - glActiveTexture(GL_TEXTURE2); - glGenTextures(1, &sky->radiance); - glBindTexture(GL_TEXTURE_CUBE_MAP, sky->radiance); - - int size = p_radiance_size / 2; //divide by two because its a cubemap (this is an approximation because GLES3 uses a dual paraboloid) - - GLenum internal_format = GL_RGB; - GLenum format = GL_RGB; - GLenum type = GL_UNSIGNED_BYTE; - - // Set the initial (empty) mipmaps - // Mobile hardware (PowerVR specially) prefers this approach, - // the previous approach with manual lod levels kills the game. - for (int i = 0; i < 6; i++) { - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internal_format, size, size, 0, format, type, NULL); - } - - glGenerateMipmap(GL_TEXTURE_CUBE_MAP); - - // No filters for now - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - // Framebuffer - - bind_framebuffer(resources.mipmap_blur_fbo); - - int mipmaps = 6; - int lod = 0; - int mm_level = mipmaps; - size = p_radiance_size / 2; - shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, true); - shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, true); - shaders.cubemap_filter.bind(); - - // third, render to the framebuffer using separate textures, then copy to mipmaps - while (size >= 1) { - //make framebuffer size the texture size, need to use a separate texture for compatibility - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, resources.mipmap_blur_color); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resources.mipmap_blur_color, 0); - - if (lod == 1) { - //bind panorama for smaller lods - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_CUBE_MAP, sky->radiance); - shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false); - shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, false); - shaders.cubemap_filter.bind(); - } - glViewport(0, 0, size, size); - bind_quad_array(); - - glActiveTexture(GL_TEXTURE2); //back to panorama - - for (int i = 0; i < 6; i++) { - shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::FACE_ID, i); - - float roughness = mm_level >= 0 ? lod / (float)(mipmaps - 1) : 1; - roughness = MIN(1.0, roughness); //keep max at 1 - shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::ROUGHNESS, roughness); - shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, false); - - //glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - glCopyTexSubImage2D(_cube_side_enum[i], lod, 0, 0, 0, 0, size, size); - } - - size >>= 1; - - mm_level--; - - lod++; - } - - shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false); - shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, false); - - // restore ranges - glActiveTexture(GL_TEXTURE2); //back to panorama - - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE3); //back to panorama - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, 0); - - //reset flags on Sky Texture that may have changed - texture_set_flags(sky->panorama, texture->flags); - - // Framebuffer did its job. thank mr framebuffer - glActiveTexture(GL_TEXTURE0); //back to panorama - bind_framebuffer_system(); } /* SHADER API */ RID RasterizerStorageGLES3::shader_allocate() { Shader *shader = memnew(Shader); - shader->mode = RS::SHADER_SPATIAL; - shader->shader = &scene->state.scene_shader; + shader->mode = RS::SHADER_CANVAS_ITEM; + //shader->shader = &scene->state.scene_shader; RID rid = shader_owner.make_rid(shader); _shader_make_dirty(shader); shader->self = rid; @@ -1510,16 +1374,22 @@ void RasterizerStorageGLES3::shader_set_code(RID p_shader, const String &p_code) String mode_string = ShaderLanguage::get_shader_type(p_code); RS::ShaderMode mode; - if (mode_string == "canvas_item") + if (mode_string == "canvas_item") { mode = RS::SHADER_CANVAS_ITEM; - else if (mode_string == "particles") + } else if (mode_string == "particles") { mode = RS::SHADER_PARTICLES; - else + } else if (mode_string == "sky") { + mode = RS::SHADER_SKY; + } else if (mode_string == "spatial") { mode = RS::SHADER_SPATIAL; + } else { + mode = RS::SHADER_MAX; + ERR_PRINT("shader type " + mode_string + " not supported in OpenGL renderer"); + } - if (shader->custom_code_id && mode != shader->mode) { - shader->shader->free_custom_shader(shader->custom_code_id); - shader->custom_code_id = 0; + if (shader->version.is_valid() && mode != shader->mode) { + shader->shader->version_free(shader->version); + shader->version = RID(); } shader->mode = mode; @@ -1529,13 +1399,15 @@ void RasterizerStorageGLES3::shader_set_code(RID p_shader, const String &p_code) shader->shader = &canvas->state.canvas_shader; } else if (mode == RS::SHADER_SPATIAL) { - shader->shader = &scene->state.scene_shader; + //shader->shader = &scene->state.scene_shader; + } else if (mode == RS::SHADER_PARTICLES) { + } else if (mode == RS::SHADER_SKY) { } else { return; } - if (shader->custom_code_id == 0) { - shader->custom_code_id = shader->shader->create_custom_shader(); + if (shader->version.is_null() && shader->shader) { + shader->version = shader->shader->version_create(); } _shader_make_dirty(shader); @@ -1559,8 +1431,8 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { return; //just invalid, but no error } - ShaderCompilerGLES3::GeneratedCode gen_code; - ShaderCompilerGLES3::IdentifierActions *actions = NULL; + ShaderCompiler::GeneratedCode gen_code; + ShaderCompiler::IdentifierActions *actions = NULL; switch (p_shader->mode) { case RS::SHADER_CANVAS_ITEM: { @@ -1573,7 +1445,6 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { p_shader->canvas_item.uses_modulate = false; p_shader->canvas_item.uses_color = false; p_shader->canvas_item.uses_vertex = false; - p_shader->canvas_item.batch_flags = 0; p_shader->canvas_item.uses_world_matrix = false; p_shader->canvas_item.uses_extra_matrix = false; @@ -1608,6 +1479,8 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { } break; case RS::SHADER_SPATIAL: { + // TODO remove once 3D is added back + return; p_shader->spatial.blend_mode = Shader::Spatial::BLEND_MODE_MIX; p_shader->spatial.depth_draw_mode = Shader::Spatial::DEPTH_DRAW_OPAQUE; p_shader->spatial.cull_mode = Shader::Spatial::CULL_MODE_BACK; @@ -1670,14 +1543,6 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { actions = &shaders.actions_scene; actions->uniforms = &p_shader->uniforms; - - if (p_shader->spatial.uses_screen_texture && p_shader->spatial.uses_depth_texture) { - ERR_PRINT_ONCE("Using both SCREEN_TEXTURE and DEPTH_TEXTURE is not supported in OpenGL"); - } - - if (p_shader->spatial.uses_depth_texture && !config.support_depth_texture) { - ERR_PRINT_ONCE("Using DEPTH_TEXTURE is not permitted on this hardware, operation will fail."); - } } break; default: { @@ -1690,38 +1555,23 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { return; } - p_shader->shader->set_custom_shader_code(p_shader->custom_code_id, gen_code.vertex, gen_code.vertex_global, gen_code.fragment, gen_code.light, gen_code.fragment_global, gen_code.uniforms, gen_code.texture_uniforms, gen_code.custom_defines); + Vector<StringName> texture_uniform_names; + for (int i = 0; i < gen_code.texture_uniforms.size(); i++) { + texture_uniform_names.push_back(gen_code.texture_uniforms[i].name); + } + + p_shader->shader->version_set_code(p_shader->version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_names); - p_shader->texture_count = gen_code.texture_uniforms.size(); - p_shader->texture_hints = gen_code.texture_hints; + p_shader->texture_uniforms = gen_code.texture_uniforms; p_shader->uses_vertex_time = gen_code.uses_vertex_time; p_shader->uses_fragment_time = gen_code.uses_fragment_time; - // some logic for batching - if (p_shader->mode == RS::SHADER_CANVAS_ITEM) { - if (p_shader->canvas_item.uses_modulate | p_shader->canvas_item.uses_color) { - p_shader->canvas_item.batch_flags |= RasterizerStorageCommon::PREVENT_COLOR_BAKING; - } - if (p_shader->canvas_item.uses_vertex) { - p_shader->canvas_item.batch_flags |= RasterizerStorageCommon::PREVENT_VERTEX_BAKING; - } - if (p_shader->canvas_item.uses_world_matrix | p_shader->canvas_item.uses_extra_matrix | p_shader->canvas_item.uses_projection_matrix | p_shader->canvas_item.uses_instance_custom) { - p_shader->canvas_item.batch_flags |= RasterizerStorageCommon::PREVENT_ITEM_JOINING; - } - } - - p_shader->shader->set_custom_shader(p_shader->custom_code_id); - p_shader->shader->bind(); - - // cache uniform locations - for (SelfList<Material> *E = p_shader->materials.first(); E; E = E->next()) { _material_make_dirty(E->self()); } p_shader->valid = true; - p_shader->version++; } void RasterizerStorageGLES3::update_dirty_shaders() { @@ -1905,31 +1755,6 @@ RID RasterizerStorageGLES3::shader_get_default_texture_param(RID p_shader, const return RID(); } -void RasterizerStorageGLES3::shader_add_custom_define(RID p_shader, const String &p_define) { - Shader *shader = shader_owner.get_or_null(p_shader); - ERR_FAIL_COND(!shader); - - shader->shader->add_custom_define(p_define); - - _shader_make_dirty(shader); -} - -void RasterizerStorageGLES3::shader_get_custom_defines(RID p_shader, Vector<String> *p_defines) const { - Shader *shader = shader_owner.get_or_null(p_shader); - ERR_FAIL_COND(!shader); - - shader->shader->get_custom_defines(p_defines); -} - -void RasterizerStorageGLES3::shader_remove_custom_define(RID p_shader, const String &p_define) { - Shader *shader = shader_owner.get_or_null(p_shader); - ERR_FAIL_COND(!shader); - - shader->shader->remove_custom_define(p_define); - - _shader_make_dirty(shader); -} - /* COMMON MATERIAL API */ void RasterizerStorageGLES3::_material_make_dirty(Material *p_material) const { @@ -2186,8 +2011,8 @@ void RasterizerStorageGLES3::_update_material(Material *p_material) { // uniforms and other things will be set in the use_material method in ShaderGLES3 - if (p_material->shader && p_material->shader->texture_count > 0) { - p_material->textures.resize(p_material->shader->texture_count); + if (p_material->shader && p_material->shader->texture_uniforms.size() > 0) { + p_material->textures.resize(p_material->shader->texture_uniforms.size()); for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_material->shader->uniforms.front(); E; E = E->next()) { if (E->get().texture_order < 0) @@ -2325,7 +2150,7 @@ RS::SurfaceData RasterizerStorageGLES3::mesh_get_surface(RID p_mesh, int p_surfa } int RasterizerStorageGLES3::mesh_get_surface_count(RID p_mesh) const { - return 0; + return 1; } void RasterizerStorageGLES3::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) { @@ -3125,39 +2950,20 @@ bool RasterizerStorageGLES3::particles_is_inactive(RID p_particles) const { /* RENDER TARGET */ void RasterizerStorageGLES3::_set_current_render_target(RID p_render_target) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return; -#endif - RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - // FTODO - // if (!p_render_target.is_valid() && storage->frame.current_rt && storage->frame.clear_request) { - // // pending clear request. Do that first. - // glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); - // glClearColor(storage->frame.clear_request_color.r, - // storage->frame.clear_request_color.g, - // storage->frame.clear_request_color.b, - // storage->frame.clear_request_color.a); - // glClear(GL_COLOR_BUFFER_BIT); - // } - if (rt) { if (rt->allocate_is_dirty) { rt->allocate_is_dirty = false; _render_target_allocate(rt); } - // if (p_render_target.is_valid()) { - // RasterizerStorageGLES3::RenderTarget *rt = storage.render_target_owner.get_or_null(p_render_target); frame.current_rt = rt; ERR_FAIL_COND(!rt); frame.clear_request = false; glViewport(0, 0, rt->width, rt->height); - // print_line("_set_current_render_target w " + itos(rt->width) + " h " + itos(rt->height)); - _dims.rt_width = rt->width; _dims.rt_height = rt->height; _dims.win_width = rt->width; @@ -3166,17 +2972,11 @@ void RasterizerStorageGLES3::_set_current_render_target(RID p_render_target) { } else { frame.current_rt = NULL; frame.clear_request = false; - // FTODO - // glViewport(0, 0, OS::get_singleton()->get_window_size().width, OS::get_singleton()->get_window_size().height); bind_framebuffer_system(); } } void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return; -#endif - // do not allocate a render target with no size if (rt->width <= 0 || rt->height <= 0) return; @@ -3515,10 +3315,6 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) { } void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return; -#endif - // there is nothing to clear when DIRECT_TO_SCREEN is used if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) return; @@ -3599,10 +3395,6 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) { } RID RasterizerStorageGLES3::render_target_create() { -#ifdef OPENGL_DISABLE_RENDER_TARGETS -// return RID(); -#endif - RenderTarget *rt = memnew(RenderTarget); Texture *t = memnew(Texture); @@ -3631,10 +3423,6 @@ RID RasterizerStorageGLES3::render_target_create() { } void RasterizerStorageGLES3::render_target_set_position(RID p_render_target, int p_x, int p_y) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return; -#endif - RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); @@ -3643,10 +3431,6 @@ void RasterizerStorageGLES3::render_target_set_position(RID p_render_target, int } void RasterizerStorageGLES3::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return; -#endif - RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); @@ -3664,11 +3448,15 @@ void RasterizerStorageGLES3::render_target_set_size(RID p_render_target, int p_w //_render_target_allocate(rt); } -RID RasterizerStorageGLES3::render_target_get_texture(RID p_render_target) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return RID(); -#endif +// TODO: convert to Size2i internally +Size2i RasterizerStorageGLES3::render_target_get_size(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND_V(!rt, Size2()); + + return Size2i(rt->width, rt->height); +} +RID RasterizerStorageGLES3::render_target_get_texture(RID p_render_target) { RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, RID()); @@ -3680,10 +3468,6 @@ RID RasterizerStorageGLES3::render_target_get_texture(RID p_render_target) { } void RasterizerStorageGLES3::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return; -#endif - RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); @@ -3789,10 +3573,6 @@ void RasterizerStorageGLES3::render_target_set_external_texture(RID p_render_tar } void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return; -#endif - RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); @@ -3825,10 +3605,6 @@ void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderT } bool RasterizerStorageGLES3::render_target_was_used(RID p_render_target) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return false; -#endif - RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, false); @@ -3836,10 +3612,6 @@ bool RasterizerStorageGLES3::render_target_was_used(RID p_render_target) { } void RasterizerStorageGLES3::render_target_clear_used(RID p_render_target) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return; -#endif - RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); @@ -3847,10 +3619,6 @@ void RasterizerStorageGLES3::render_target_clear_used(RID p_render_target) { } void RasterizerStorageGLES3::render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return; -#endif - RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); @@ -3868,10 +3636,6 @@ void RasterizerStorageGLES3::render_target_set_msaa(RID p_render_target, RS::Vie //} void RasterizerStorageGLES3::render_target_set_use_fxaa(RID p_render_target, bool p_fxaa) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return; -#endif - RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); @@ -3879,10 +3643,6 @@ void RasterizerStorageGLES3::render_target_set_use_fxaa(RID p_render_target, boo } void RasterizerStorageGLES3::render_target_set_use_debanding(RID p_render_target, bool p_debanding) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return; -#endif - RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); @@ -3894,10 +3654,6 @@ void RasterizerStorageGLES3::render_target_set_use_debanding(RID p_render_target } void RasterizerStorageGLES3::render_target_request_clear(RID p_render_target, const Color &p_clear_color) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return; -#endif - RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); rt->clear_requested = true; @@ -3909,55 +3665,23 @@ void RasterizerStorageGLES3::render_target_request_clear(RID p_render_target, co } bool RasterizerStorageGLES3::render_target_is_clear_requested(RID p_render_target) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return false; -#endif RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, false); return rt->clear_requested; } Color RasterizerStorageGLES3::render_target_get_clear_request_color(RID p_render_target) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return Color(); -#endif - RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, Color()); return rt->clear_color; } void RasterizerStorageGLES3::render_target_disable_clear_request(RID p_render_target) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return; -#endif RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); rt->clear_requested = false; } void RasterizerStorageGLES3::render_target_do_clear_request(RID p_render_target) { -#ifdef OPENGL_DISABLE_RENDER_TARGETS - return; -#endif - - // NEW for GLES... - // This is being called at the wrong time. Instead it will be performed - // at canvas begin - return; - - /* - RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - if (!rt->clear_requested) { - return; - } - - const Color &c = rt->clear_color; - - glClearColor(c.r, c.g, c.b, c.a); - // more bits? - glClear(GL_COLOR_BUFFER_BIT); - */ } void RasterizerStorageGLES3::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) { @@ -4160,12 +3884,18 @@ bool RasterizerStorageGLES3::free(RID p_rid) { Texture *t = texture_owner.get_or_null(p_rid); // can't free a render target texture ERR_FAIL_COND_V(t->render_target, true); + if (t->canvas_texture) { + memdelete(t->canvas_texture); + } info.texture_mem -= t->total_data_size; texture_owner.free(p_rid); memdelete(t); return true; + } else if (canvas_texture_owner.owns(p_rid)) { + canvas_texture_owner.free(p_rid); + return true; } else if (sky_owner.owns(p_rid)) { Sky *sky = sky_owner.get_or_null(p_rid); sky_set_texture(p_rid, RID(), 256); @@ -4176,8 +3906,8 @@ bool RasterizerStorageGLES3::free(RID p_rid) { } else if (shader_owner.owns(p_rid)) { Shader *shader = shader_owner.get_or_null(p_rid); - if (shader->shader && shader->custom_code_id) { - shader->shader->free_custom_shader(shader->custom_code_id); + if (shader->shader && shader->version.is_valid()) { + shader->shader->version_free(shader->version); } if (shader->dirty_list.in_list()) { @@ -4482,7 +4212,6 @@ void RasterizerStorageGLES3::initialize() { } } - // FTODO config.keep_original_textures = true; // false config.shrink_textures_x2 = false; config.depth_internalformat = GL_DEPTH_COMPONENT; @@ -4654,10 +4383,12 @@ void RasterizerStorageGLES3::initialize() { // OR max_vertex_texture_image_units is zero config.use_skeleton_software = (config.float_texture_supported == false) || (config.max_vertex_texture_image_units == 0); - shaders.copy.init(); - shaders.cubemap_filter.init(); - bool ggx_hq = false; //GLOBAL_GET("rendering/quality/reflections/high_quality_ggx"); - shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, !ggx_hq); + shaders.copy.initialize(); + shaders.copy_version = shaders.copy.version_create(); //TODO + shaders.copy.version_bind_shader(shaders.copy_version, CopyShaderGLES3::MODE_COPY_SECTION); + //shaders.cubemap_filter.init(); + //bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx"); + //shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, !ggx_hq); { // quad for copying stuff @@ -4831,4 +4562,8 @@ RasterizerStorageGLES3::RasterizerStorageGLES3() { config.should_orphan = true; } -#endif // GLES3_BACKEND_ENABLED +RasterizerStorageGLES3::~RasterizerStorageGLES3() { + shaders.copy.version_free(shaders.copy_version); +} + +#endif // GLES3_ENABLED diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 807789586b..c080d28f94 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -31,21 +31,17 @@ #ifndef RASTERIZER_STORAGE_OPENGL_H #define RASTERIZER_STORAGE_OPENGL_H -#include "drivers/gles3/rasterizer_platforms.h" -#ifdef GLES3_BACKEND_ENABLED +#ifdef GLES3_ENABLED #include "core/templates/local_vector.h" #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" -#include "drivers/gles3/rasterizer_asserts.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering/renderer_storage.h" +#include "servers/rendering/shader_compiler.h" #include "servers/rendering/shader_language.h" -#include "shader_compiler_gles3.h" -#include "shader_gles3.h" #include "shaders/copy.glsl.gen.h" -#include "shaders/cubemap_filter.glsl.gen.h" class RasterizerCanvasGLES3; class RasterizerSceneGLES3; @@ -134,14 +130,15 @@ public: } resources; mutable struct Shaders { - ShaderCompilerGLES3 compiler; + ShaderCompiler compiler; CopyShaderGLES3 copy; - CubemapFilterShaderGLES3 cubemap_filter; + RID copy_version; + //CubemapFilterShaderGLES3 cubemap_filter; - ShaderCompilerGLES3::IdentifierActions actions_canvas; - ShaderCompilerGLES3::IdentifierActions actions_scene; - ShaderCompilerGLES3::IdentifierActions actions_particles; + ShaderCompiler::IdentifierActions actions_canvas; + ShaderCompiler::IdentifierActions actions_scene; + ShaderCompiler::IdentifierActions actions_particles; } shaders; @@ -183,62 +180,6 @@ public: void bind_quad_array() const; ///////////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////DATA/////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////// - - /* - struct Instantiable { - RID self; - - SelfList<InstanceBaseDependency>::List instance_list; - - _FORCE_INLINE_ void instance_change_notify(bool p_aabb, bool p_materials) { - SelfList<InstanceBaseDependency> *instances = instance_list.first(); - while (instances) { - instances->self()->base_changed(p_aabb, p_materials); - instances = instances->next(); - } - } - - _FORCE_INLINE_ void instance_remove_deps() { - SelfList<InstanceBaseDependency> *instances = instance_list.first(); - - while (instances) { - instances->self()->base_removed(); - instances = instances->next(); - } - } - - Instantiable() {} - - ~Instantiable() {} - }; - - struct GeometryOwner : public Instantiable { - }; - - struct Geometry : public Instantiable { - enum Type { - GEOMETRY_INVALID, - GEOMETRY_SURFACE, - GEOMETRY_IMMEDIATE, - GEOMETRY_MULTISURFACE - }; - - Type type; - RID material; - uint64_t last_pass; - uint32_t index; - - void material_changed_notify() {} - - Geometry() { - last_pass = 0; - index = 0; - } - }; -*/ - ///////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////API//////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// @@ -257,6 +198,26 @@ public: TEXTURE_FLAGS_DEFAULT = TEXTURE_FLAG_REPEAT | TEXTURE_FLAG_MIPMAPS | TEXTURE_FLAG_FILTER }; + /* CANVAS TEXTURE API (2D) */ + + struct CanvasTexture { + RID diffuse; + RID normal_map; + RID specular; + Color specular_color = Color(1, 1, 1, 1); + float shininess = 1.0; + + RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT; + RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT; + + Size2i size_cache = Size2i(1, 1); + bool use_normal_cache = false; + bool use_specular_cache = false; + bool cleared_cache = true; + }; + + RID_Owner<CanvasTexture, true> canvas_texture_owner; + struct RenderTarget; struct Texture { @@ -309,6 +270,8 @@ public: RS::TextureDetectCallback detect_normal; void *detect_normal_ud; + CanvasTexture *canvas_texture = nullptr; + // some silly opengl shenanigans where // texture coords start from bottom left, means we need to draw render target textures upside down // to be compatible with vulkan etc. @@ -436,7 +399,7 @@ public: glTexParameteri(p_target, GL_TEXTURE_MIN_FILTER, pmin); glTexParameteri(p_target, GL_TEXTURE_MAG_FILTER, pmag); } - void GLSetRepeat(RS::CanvasItemTextureRepeat p_repeat) { + void GLSetRepeat(GLenum p_target, RS::CanvasItemTextureRepeat p_repeat) { if (p_repeat == state_repeat) return; state_repeat = p_repeat; @@ -451,8 +414,8 @@ public: prep = GL_MIRRORED_REPEAT; } break; } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, prep); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, prep); + glTexParameteri(p_target, GL_TEXTURE_WRAP_S, prep); + glTexParameteri(p_target, GL_TEXTURE_WRAP_T, prep); } private: @@ -540,10 +503,10 @@ public: void canvas_texture_initialize(RID p_rid) override; void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override; - void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override; + void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) override; - void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override; - void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override; + void canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) override; + void canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) override; /* SKY API */ // not sure if used in godot 4? @@ -573,16 +536,13 @@ public: Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; - uint32_t texture_count; - - uint32_t custom_code_id; - uint32_t version; + RID version; SelfList<Shader> dirty_list; Map<StringName, Map<int, RID>> default_textures; - Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints; + Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; bool valid; @@ -610,12 +570,6 @@ public: int light_mode; - // these flags are specifically for batching - // some of the logic is thus in rasterizer_storage.cpp - // we could alternatively set bitflags for each 'uses' and test on the fly - // defined in RasterizerStorageCommon::BatchFlags - unsigned int batch_flags; - bool uses_screen_texture; bool uses_screen_uv; bool uses_time; @@ -686,8 +640,7 @@ public: dirty_list(this) { shader = NULL; valid = false; - custom_code_id = 0; - version = 1; + version = RID(); last_pass = 0; } }; @@ -711,10 +664,6 @@ public: RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); }; - void shader_add_custom_define(RID p_shader, const String &p_define); - void shader_get_custom_defines(RID p_shader, Vector<String> *p_defines) const; - void shader_remove_custom_define(RID p_shader, const String &p_define); - void _update_shader(Shader *p_shader) const; void update_dirty_shaders(); @@ -838,6 +787,44 @@ public: /* MULTIMESH API */ + struct MultiMesh { + RID mesh; + int instances = 0; + RS::MultimeshTransformFormat xform_format = RS::MULTIMESH_TRANSFORM_3D; + bool uses_colors = false; + bool uses_custom_data = false; + int visible_instances = -1; + AABB aabb; + bool aabb_dirty = false; + bool buffer_set = false; + uint32_t stride_cache = 0; + uint32_t color_offset_cache = 0; + uint32_t custom_data_offset_cache = 0; + + Vector<float> data_cache; //used if individual setting is used + bool *data_cache_dirty_regions = nullptr; + uint32_t data_cache_used_dirty_regions = 0; + + RID buffer; //storage buffer + RID uniform_set_3d; + RID uniform_set_2d; + + bool dirty = false; + MultiMesh *dirty_list = nullptr; + + Dependency dependency; + }; + + mutable RID_Owner<MultiMesh, true> multimesh_owner; + + MultiMesh *multimesh_dirty_list = nullptr; + + _FORCE_INLINE_ void _multimesh_make_local(MultiMesh *multimesh) const; + _FORCE_INLINE_ void _multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb); + _FORCE_INLINE_ void _multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb); + _FORCE_INLINE_ void _multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances); + void _update_dirty_multimeshes(); + RID multimesh_allocate() override; void multimesh_initialize(RID p_rid) override; void multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) override; @@ -862,6 +849,29 @@ public: void multimesh_set_visible_instances(RID p_multimesh, int p_visible) override; int multimesh_get_visible_instances(RID p_multimesh) const override; + _FORCE_INLINE_ RS::MultimeshTransformFormat multimesh_get_transform_format(RID p_multimesh) const { + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); + return multimesh->xform_format; + } + + _FORCE_INLINE_ bool multimesh_uses_colors(RID p_multimesh) const { + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); + return multimesh->uses_colors; + } + + _FORCE_INLINE_ bool multimesh_uses_custom_data(RID p_multimesh) const { + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); + return multimesh->uses_custom_data; + } + + _FORCE_INLINE_ uint32_t multimesh_get_instances_to_draw(RID p_multimesh) const { + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); + if (multimesh->visible_instances >= 0) { + return multimesh->visible_instances; + } + return multimesh->instances; + } + /* SKELETON API */ RID skeleton_allocate() override; @@ -1258,6 +1268,7 @@ public: RID render_target_create() override; void render_target_set_position(RID p_render_target, int p_x, int p_y) override; void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) override; + Size2i render_target_get_size(RID p_render_target); RID render_target_get_texture(RID p_render_target) override; void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override; @@ -1330,7 +1341,7 @@ public: bool clear_request; Color clear_request_color; - float time[4]; + float time; float delta; uint64_t count; @@ -1410,6 +1421,7 @@ public: } RasterizerStorageGLES3(); + ~RasterizerStorageGLES3(); }; inline bool RasterizerStorageGLES3::safe_buffer_sub_data(unsigned int p_total_buffer_size, GLenum p_target, unsigned int p_offset, unsigned int p_data_size, const void *p_data, unsigned int &r_offset_after) const { @@ -1445,10 +1457,9 @@ inline void RasterizerStorageGLES3::buffer_orphan_and_upload(unsigned int p_buff } #endif } - RAST_DEV_DEBUG_ASSERT((p_offset + p_data_size) <= p_buffer_size); glBufferSubData(p_target, p_offset, p_data_size, p_data); } -#endif // GLES3_BACKEND_ENABLED +#endif // GLES3_ENABLED #endif // RASTERIZER_STORAGE_OPENGL_H diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp deleted file mode 100644 index 555ed6ebd2..0000000000 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ /dev/null @@ -1,1136 +0,0 @@ -/*************************************************************************/ -/* shader_compiler_gles3.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "shader_compiler_gles3.h" -#ifdef GLES3_BACKEND_ENABLED - -#include "core/config/project_settings.h" -#include "core/os/os.h" -#include "core/string/string_buffer.h" -#include "core/string/string_builder.h" - -#define SL ShaderLanguage - -static String _mktab(int p_level) { - String tb; - for (int i = 0; i < p_level; i++) { - tb += "\t"; - } - - return tb; -} - -static String _typestr(SL::DataType p_type) { - return ShaderLanguage::get_datatype_name(p_type); -} - -static String _prestr(SL::DataPrecision p_pres) { - switch (p_pres) { - case SL::PRECISION_LOWP: - return "lowp "; - case SL::PRECISION_MEDIUMP: - return "mediump "; - case SL::PRECISION_HIGHP: - return "highp "; - case SL::PRECISION_DEFAULT: - return ""; - } - return ""; -} - -static String _constr(bool p_is_const) { - if (p_is_const) { - return "const "; - } - return ""; -} - -static String _qualstr(SL::ArgumentQualifier p_qual) { - switch (p_qual) { - case SL::ARGUMENT_QUALIFIER_IN: - return "in "; - case SL::ARGUMENT_QUALIFIER_OUT: - return "out "; - case SL::ARGUMENT_QUALIFIER_INOUT: - return "inout "; - } - return ""; -} - -static String _opstr(SL::Operator p_op) { - return SL::get_operator_text(p_op); -} - -static String _mkid(const String &p_id) { - String id = "m_" + p_id.replace("__", "_dus_"); - return id.replace("__", "_dus_"); //doubleunderscore is reserved in glsl -} - -static String f2sp0(float p_float) { - String num = rtoss(p_float); - if (num.find(".") == -1 && num.find("e") == -1) { - num += ".0"; - } - return num; -} - -static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNode::Value> &p_values) { - switch (p_type) { - case SL::TYPE_BOOL: - return p_values[0].boolean ? "true" : "false"; - case SL::TYPE_BVEC2: - case SL::TYPE_BVEC3: - case SL::TYPE_BVEC4: { - StringBuffer<> text; - - text += "bvec"; - text += itos(p_type - SL::TYPE_BOOL + 1); - text += "("; - - for (int i = 0; i < p_values.size(); i++) { - if (i > 0) - text += ","; - - text += p_values[i].boolean ? "true" : "false"; - } - text += ")"; - return text.as_string(); - } - - // GLSL ES 2 doesn't support uints, so we just use signed ints instead... - case SL::TYPE_UINT: - return itos(p_values[0].uint); - case SL::TYPE_UVEC2: - case SL::TYPE_UVEC3: - case SL::TYPE_UVEC4: { - StringBuffer<> text; - - text += "ivec"; - text += itos(p_type - SL::TYPE_UINT + 1); - text += "("; - - for (int i = 0; i < p_values.size(); i++) { - if (i > 0) - text += ","; - - text += itos(p_values[i].uint); - } - text += ")"; - return text.as_string(); - - } break; - - case SL::TYPE_INT: - return itos(p_values[0].sint); - case SL::TYPE_IVEC2: - case SL::TYPE_IVEC3: - case SL::TYPE_IVEC4: { - StringBuffer<> text; - - text += "ivec"; - text += itos(p_type - SL::TYPE_INT + 1); - text += "("; - - for (int i = 0; i < p_values.size(); i++) { - if (i > 0) - text += ","; - - text += itos(p_values[i].sint); - } - text += ")"; - return text.as_string(); - - } break; - case SL::TYPE_FLOAT: - return f2sp0(p_values[0].real); - case SL::TYPE_VEC2: - case SL::TYPE_VEC3: - case SL::TYPE_VEC4: { - StringBuffer<> text; - - text += "vec"; - text += itos(p_type - SL::TYPE_FLOAT + 1); - text += "("; - - for (int i = 0; i < p_values.size(); i++) { - if (i > 0) - text += ","; - - text += f2sp0(p_values[i].real); - } - text += ")"; - return text.as_string(); - - } break; - case SL::TYPE_MAT2: - case SL::TYPE_MAT3: - case SL::TYPE_MAT4: { - StringBuffer<> text; - - text += "mat"; - text += itos(p_type - SL::TYPE_MAT2 + 2); - text += "("; - - for (int i = 0; i < p_values.size(); i++) { - if (i > 0) - text += ","; - - text += f2sp0(p_values[i].real); - } - text += ")"; - return text.as_string(); - - } break; - default: - ERR_FAIL_V(String()); - } -} - -void ShaderCompilerGLES3::_dump_function_deps(SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, StringBuilder &r_to_add, Set<StringName> &r_added) { - int fidx = -1; - - for (int i = 0; i < p_node->functions.size(); i++) { - if (p_node->functions[i].name == p_for_func) { - fidx = i; - break; - } - } - - ERR_FAIL_COND(fidx == -1); - - for (Set<StringName>::Element *E = p_node->functions[fidx].uses_function.front(); E; E = E->next()) { - if (r_added.has(E->get())) { - continue; - } - - _dump_function_deps(p_node, E->get(), p_func_code, r_to_add, r_added); - - SL::FunctionNode *fnode = NULL; - - for (int i = 0; i < p_node->functions.size(); i++) { - if (p_node->functions[i].name == E->get()) { - fnode = p_node->functions[i].function; - break; - } - } - - ERR_FAIL_COND(!fnode); - - r_to_add += "\n"; - - StringBuffer<128> header; - - header += _typestr(fnode->return_type); - header += " "; - header += _mkid(fnode->name); - header += "("; - - for (int i = 0; i < fnode->arguments.size(); i++) { - if (i > 0) { - header += ", "; - } - header += _constr(fnode->arguments[i].is_const); - header += _qualstr(fnode->arguments[i].qualifier); - header += _prestr(fnode->arguments[i].precision); - header += _typestr(fnode->arguments[i].type); - header += " "; - header += _mkid(fnode->arguments[i].name); - } - - header += ")\n"; - r_to_add += header.as_string(); - r_to_add += p_func_code[E->get()]; - - r_added.insert(E->get()); - } -} - -String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope) { - StringBuilder code; - - switch (p_node->type) { - default: { - } break; - case SL::Node::TYPE_SHADER: { - SL::ShaderNode *snode = (SL::ShaderNode *)p_node; - - for (int i = 0; i < snode->render_modes.size(); i++) { - if (p_default_actions.render_mode_defines.has(snode->render_modes[i]) && !used_rmode_defines.has(snode->render_modes[i])) { - r_gen_code.custom_defines.push_back(p_default_actions.render_mode_defines[snode->render_modes[i]].utf8()); - used_rmode_defines.insert(snode->render_modes[i]); - } - - if (p_actions.render_mode_flags.has(snode->render_modes[i])) { - *p_actions.render_mode_flags[snode->render_modes[i]] = true; - } - - if (p_actions.render_mode_values.has(snode->render_modes[i])) { - Pair<int *, int> &p = p_actions.render_mode_values[snode->render_modes[i]]; - *p.first = p.second; - } - } - - int max_texture_uniforms = 0; - int max_uniforms = 0; - - for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = snode->uniforms.front(); E; E = E->next()) { - if (SL::is_sampler_type(E->get().type)) - max_texture_uniforms++; - else - max_uniforms++; - } - - r_gen_code.texture_uniforms.resize(max_texture_uniforms); - r_gen_code.texture_hints.resize(max_texture_uniforms); - - r_gen_code.uniforms.resize(max_uniforms + max_texture_uniforms); - - StringBuilder vertex_global; - StringBuilder fragment_global; - - // uniforms - - for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = snode->uniforms.front(); E; E = E->next()) { - StringBuffer<> uniform_code; - - // use highp if no precision is specified to prevent different default values in fragment and vertex shader - SL::DataPrecision precision = E->get().precision; - if (precision == SL::PRECISION_DEFAULT && E->get().type != SL::TYPE_BOOL) { - precision = SL::PRECISION_HIGHP; - } - - uniform_code += "uniform "; - uniform_code += _prestr(precision); - uniform_code += _typestr(E->get().type); - uniform_code += " "; - uniform_code += _mkid(E->key()); - uniform_code += ";\n"; - - if (SL::is_sampler_type(E->get().type)) { - r_gen_code.texture_uniforms.write[E->get().texture_order] = E->key(); - r_gen_code.texture_hints.write[E->get().texture_order] = E->get().hint; - } else { - r_gen_code.uniforms.write[E->get().order] = E->key(); - } - - vertex_global += uniform_code.as_string(); - fragment_global += uniform_code.as_string(); - - p_actions.uniforms->insert(E->key(), E->get()); - } - - // varyings - - for (Map<StringName, SL::ShaderNode::Varying>::Element *E = snode->varyings.front(); E; E = E->next()) { - StringBuffer<> varying_code; - - varying_code += "varying "; - varying_code += _prestr(E->get().precision); - varying_code += _typestr(E->get().type); - varying_code += " "; - varying_code += _mkid(E->key()); - if (E->get().array_size > 0) { - varying_code += "["; - varying_code += itos(E->get().array_size); - varying_code += "]"; - } - varying_code += ";\n"; - - String final_code = varying_code.as_string(); - - vertex_global += final_code; - fragment_global += final_code; - } - - // constants - - for (int i = 0; i < snode->vconstants.size(); i++) { - String gcode; - gcode += _constr(true); - gcode += _prestr(snode->vconstants[i].precision); - gcode += _typestr(snode->vconstants[i].type); - gcode += " " + _mkid(String(snode->vconstants[i].name)); - gcode += "="; - gcode += _dump_node_code(snode->vconstants[i].initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - gcode += ";\n"; - vertex_global += gcode; - fragment_global += gcode; - } - - // functions - - Map<StringName, String> function_code; - - for (int i = 0; i < snode->functions.size(); i++) { - SL::FunctionNode *fnode = snode->functions[i].function; - current_func_name = fnode->name; - function_code[fnode->name] = _dump_node_code(fnode->body, 1, r_gen_code, p_actions, p_default_actions, p_assigning); - } - - Set<StringName> added_vertex; - Set<StringName> added_fragment; - - for (int i = 0; i < snode->functions.size(); i++) { - SL::FunctionNode *fnode = snode->functions[i].function; - - current_func_name = fnode->name; - - if (fnode->name == vertex_name) { - _dump_function_deps(snode, fnode->name, function_code, vertex_global, added_vertex); - r_gen_code.vertex = function_code[vertex_name]; - - } else if (fnode->name == fragment_name) { - _dump_function_deps(snode, fnode->name, function_code, fragment_global, added_fragment); - r_gen_code.fragment = function_code[fragment_name]; - - } else if (fnode->name == light_name) { - _dump_function_deps(snode, fnode->name, function_code, fragment_global, added_fragment); - r_gen_code.light = function_code[light_name]; - } - } - - r_gen_code.vertex_global = vertex_global.as_string(); - r_gen_code.fragment_global = fragment_global.as_string(); - - } break; - - case SL::Node::TYPE_FUNCTION: { - } break; - - case SL::Node::TYPE_BLOCK: { - SL::BlockNode *bnode = (SL::BlockNode *)p_node; - - if (!bnode->single_statement) { - code += _mktab(p_level - 1); - code += "{\n"; - } - - for (int i = 0; i < bnode->statements.size(); i++) { - String statement_code = _dump_node_code(bnode->statements[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - - if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW || bnode->single_statement) { - code += statement_code; - } else { - code += _mktab(p_level); - code += statement_code; - code += ";\n"; - } - } - - if (!bnode->single_statement) { - code += _mktab(p_level - 1); - code += "}\n"; - } - } break; - - case SL::Node::TYPE_VARIABLE_DECLARATION: { - SL::VariableDeclarationNode *var_dec_node = (SL::VariableDeclarationNode *)p_node; - - StringBuffer<> declaration; - declaration += _constr(var_dec_node->is_const); - declaration += _prestr(var_dec_node->precision); - declaration += _typestr(var_dec_node->datatype); - - for (int i = 0; i < var_dec_node->declarations.size(); i++) { - if (i > 0) { - declaration += ","; - } - - declaration += " "; - - declaration += _mkid(var_dec_node->declarations[i].name); - - if (var_dec_node->declarations[i].initializer) { - declaration += " = "; - declaration += _dump_node_code(var_dec_node->declarations[i].initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - } - } - - code += declaration.as_string(); - } break; - - case SL::Node::TYPE_VARIABLE: { - SL::VariableNode *var_node = (SL::VariableNode *)p_node; - - if (p_assigning && p_actions.write_flag_pointers.has(var_node->name)) { - *p_actions.write_flag_pointers[var_node->name] = true; - } - - if (p_default_actions.usage_defines.has(var_node->name) && !used_name_defines.has(var_node->name)) { - String define = p_default_actions.usage_defines[var_node->name]; - String node_name = define.substr(1, define.length()); - - if (define.begins_with("@")) { - define = p_default_actions.usage_defines[node_name]; - } - - if (!used_name_defines.has(node_name)) { - r_gen_code.custom_defines.push_back(define.utf8()); - } - used_name_defines.insert(var_node->name); - } - - if (p_actions.usage_flag_pointers.has(var_node->name) && !used_flag_pointers.has(var_node->name)) { - *p_actions.usage_flag_pointers[var_node->name] = true; - used_flag_pointers.insert(var_node->name); - } - - if (p_default_actions.renames.has(var_node->name)) { - code += p_default_actions.renames[var_node->name]; - } else { - code += _mkid(var_node->name); - } - - if (var_node->name == time_name) { - if (current_func_name == vertex_name) { - r_gen_code.uses_vertex_time = true; - } - if (current_func_name == fragment_name || current_func_name == light_name) { - r_gen_code.uses_fragment_time = true; - } - } - } break; - case SL::Node::TYPE_ARRAY_DECLARATION: { - SL::ArrayDeclarationNode *arr_dec_node = (SL::ArrayDeclarationNode *)p_node; - - StringBuffer<> declaration; - declaration += _prestr(arr_dec_node->precision); - declaration += _typestr(arr_dec_node->datatype); - - for (int i = 0; i < arr_dec_node->declarations.size(); i++) { - if (i > 0) { - declaration += ","; - } - - declaration += " "; - - declaration += _mkid(arr_dec_node->declarations[i].name); - declaration += "["; - declaration += itos(arr_dec_node->declarations[i].size); - declaration += "]"; - } - - code += declaration.as_string(); - } break; - case SL::Node::TYPE_ARRAY: { - SL::ArrayNode *arr_node = (SL::ArrayNode *)p_node; - - if (p_assigning && p_actions.write_flag_pointers.has(arr_node->name)) { - *p_actions.write_flag_pointers[arr_node->name] = true; - } - - if (p_default_actions.usage_defines.has(arr_node->name) && !used_name_defines.has(arr_node->name)) { - String define = p_default_actions.usage_defines[arr_node->name]; - String node_name = define.substr(1, define.length()); - - if (define.begins_with("@")) { - define = p_default_actions.usage_defines[node_name]; - } - - if (!used_name_defines.has(node_name)) { - r_gen_code.custom_defines.push_back(define.utf8()); - } - used_name_defines.insert(arr_node->name); - } - - if (p_actions.usage_flag_pointers.has(arr_node->name) && !used_flag_pointers.has(arr_node->name)) { - *p_actions.usage_flag_pointers[arr_node->name] = true; - used_flag_pointers.insert(arr_node->name); - } - - if (p_default_actions.renames.has(arr_node->name)) { - code += p_default_actions.renames[arr_node->name]; - } else { - code += _mkid(arr_node->name); - } - - if (arr_node->call_expression != NULL) { - code += "."; - code += _dump_node_code(arr_node->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning, false); - } - - if (arr_node->index_expression != NULL) { - code += "["; - code += _dump_node_code(arr_node->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += "]"; - } - - if (arr_node->name == time_name) { - if (current_func_name == vertex_name) { - r_gen_code.uses_vertex_time = true; - } - if (current_func_name == fragment_name || current_func_name == light_name) { - r_gen_code.uses_fragment_time = true; - } - } - - } break; - case SL::Node::TYPE_CONSTANT: { - SL::ConstantNode *const_node = (SL::ConstantNode *)p_node; - - return get_constant_text(const_node->datatype, const_node->values); - } break; - - case SL::Node::TYPE_OPERATOR: { - SL::OperatorNode *op_node = (SL::OperatorNode *)p_node; - - switch (op_node->op) { - case SL::OP_ASSIGN: - case SL::OP_ASSIGN_ADD: - case SL::OP_ASSIGN_SUB: - case SL::OP_ASSIGN_MUL: - case SL::OP_ASSIGN_DIV: - case SL::OP_ASSIGN_SHIFT_LEFT: - case SL::OP_ASSIGN_SHIFT_RIGHT: - case SL::OP_ASSIGN_BIT_AND: - case SL::OP_ASSIGN_BIT_OR: - case SL::OP_ASSIGN_BIT_XOR: { - code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, true); - code += " "; - code += _opstr(op_node->op); - code += " "; - code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - } break; - - case SL::OP_ASSIGN_MOD: { - String a = _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - String n = _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += a + " = " + n + " == 0 ? 0 : "; - code += a + " - " + n + " * (" + a + " / " + n + ")"; - } break; - - case SL::OP_BIT_INVERT: - case SL::OP_NEGATE: - case SL::OP_NOT: - case SL::OP_DECREMENT: - case SL::OP_INCREMENT: { - code += _opstr(op_node->op); - code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - } break; - - case SL::OP_POST_DECREMENT: - case SL::OP_POST_INCREMENT: { - code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += _opstr(op_node->op); - } break; - - case SL::OP_CALL: - case SL::OP_CONSTRUCT: { - ERR_FAIL_COND_V(op_node->arguments[0]->type != SL::Node::TYPE_VARIABLE, String()); - - SL::VariableNode *var_node = (SL::VariableNode *)op_node->arguments[0]; - - if (op_node->op == SL::OP_CONSTRUCT) { - code += var_node->name; - } else { - if (var_node->name == "texture") { - // emit texture call - - if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLER2D) { // || - // op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLEREXT) { - code += "texture"; - } else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLERCUBE) { - code += "textureCube"; - } - - } else if (var_node->name == "textureLod") { - // emit texture call - - if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLER2D) { - code += "textureLod"; - } else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLERCUBE) { - code += "textureCubeLod"; - } - - } else if (var_node->name == "mix") { - switch (op_node->arguments[3]->get_datatype()) { - case SL::TYPE_BVEC2: { - code += "select2"; - } break; - - case SL::TYPE_BVEC3: { - code += "select3"; - } break; - - case SL::TYPE_BVEC4: { - code += "select4"; - } break; - - case SL::TYPE_VEC2: - case SL::TYPE_VEC3: - case SL::TYPE_VEC4: - case SL::TYPE_FLOAT: { - code += "mix"; - } break; - - default: { - SL::DataType type = op_node->arguments[3]->get_datatype(); - // FIXME: Proper error print or graceful handling - print_line(String("uhhhh invalid mix with type: ") + itos(type)); - } break; - } - - } else if (p_default_actions.renames.has(var_node->name)) { - code += p_default_actions.renames[var_node->name]; - } else if (internal_functions.has(var_node->name)) { - code += var_node->name; - } else { - code += _mkid(var_node->name); - } - } - - code += "("; - - for (int i = 1; i < op_node->arguments.size(); i++) { - if (i > 1) { - code += ", "; - } - - code += _dump_node_code(op_node->arguments[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - } - - code += ")"; - - if (p_default_actions.usage_defines.has(var_node->name) && !used_name_defines.has(var_node->name)) { - String define = p_default_actions.usage_defines[var_node->name]; - String node_name = define.substr(1, define.length()); - - if (define.begins_with("@")) { - define = p_default_actions.usage_defines[node_name]; - } - - if (!used_name_defines.has(node_name)) { - r_gen_code.custom_defines.push_back(define.utf8()); - } - used_name_defines.insert(var_node->name); - } - - } break; - - case SL::OP_INDEX: { - code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += "["; - code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += "]"; - } break; - - case SL::OP_SELECT_IF: { - code += "("; - code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += " ? "; - code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += " : "; - code += _dump_node_code(op_node->arguments[2], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += ")"; - } break; - - case SL::OP_MOD: { - String a = _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - String n = _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += "(" + n + " == 0 ? 0 : "; - code += a + " - " + n + " * (" + a + " / " + n + "))"; - } break; - - case SL::OP_EMPTY: { - // Semicolon (or empty statement) - ignored. - } break; - - default: { - if (p_use_scope) { - code += "("; - } - code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += " "; - code += _opstr(op_node->op); - code += " "; - code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - if (p_use_scope) { - code += ")"; - } - } break; - } - } break; - - case SL::Node::TYPE_CONTROL_FLOW: { - SL::ControlFlowNode *cf_node = (SL::ControlFlowNode *)p_node; - - if (cf_node->flow_op == SL::FLOW_OP_IF) { - code += _mktab(p_level); - code += "if ("; - code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += ")\n"; - code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); - - if (cf_node->blocks.size() == 2) { - code += _mktab(p_level); - code += "else\n"; - code += _dump_node_code(cf_node->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); - } - } else if (cf_node->flow_op == SL::FLOW_OP_DO) { - code += _mktab(p_level); - code += "do"; - code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); - code += _mktab(p_level); - code += "while ("; - code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += ");"; - } else if (cf_node->flow_op == SL::FLOW_OP_WHILE) { - code += _mktab(p_level); - code += "while ("; - code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += ")\n"; - code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); - } else if (cf_node->flow_op == SL::FLOW_OP_FOR) { - code += _mktab(p_level); - code += "for ("; - code += _dump_node_code(cf_node->blocks[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += "; "; - code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += "; "; - code += _dump_node_code(cf_node->expressions[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += ")\n"; - - code += _dump_node_code(cf_node->blocks[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - - } else if (cf_node->flow_op == SL::FLOW_OP_RETURN) { - code += _mktab(p_level); - code += "return"; - - if (cf_node->expressions.size()) { - code += " "; - code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - } - code += ";\n"; - } else if (cf_node->flow_op == SL::FLOW_OP_DISCARD) { - if (p_actions.usage_flag_pointers.has("DISCARD") && !used_flag_pointers.has("DISCARD")) { - *p_actions.usage_flag_pointers["DISCARD"] = true; - used_flag_pointers.insert("DISCARD"); - } - code += "discard;"; - } else if (cf_node->flow_op == SL::FLOW_OP_CONTINUE) { - code += "continue;"; - } else if (cf_node->flow_op == SL::FLOW_OP_BREAK) { - code += "break;"; - } - } break; - - case SL::Node::TYPE_MEMBER: { - SL::MemberNode *member_node = (SL::MemberNode *)p_node; - code += _dump_node_code(member_node->owner, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - code += "."; - code += member_node->name; - } break; - } - - return code.as_string(); -} - -ShaderLanguage::DataType ShaderCompilerGLES3::_get_variable_type(const StringName &p_type) { - // RS::GlobalVariableType gvt = ((RasterizerStorageRD *)(RendererStorage::base_singleton))->global_variable_get_type_internal(p_type); - RS::GlobalVariableType gvt = RS::GLOBAL_VAR_TYPE_MAX; - return RS::global_variable_type_get_shader_datatype(gvt); -} - -Error ShaderCompilerGLES3::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) { - ShaderLanguage::VaryingFunctionNames var_names; - - ShaderLanguage::ShaderCompileInfo info; - info.functions = ShaderTypes::get_singleton()->get_functions(p_mode); - info.render_modes = ShaderTypes::get_singleton()->get_modes(p_mode); - info.shader_types = ShaderTypes::get_singleton()->get_types(); - info.global_variable_type_func = _get_variable_type; - - Error err = parser.compile(p_code, info); - - // Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func) { - if (err != OK) { - Vector<String> shader = p_code.split("\n"); - for (int i = 0; i < shader.size(); i++) { - print_line(itos(i + 1) + " " + shader[i]); - } - - _err_print_error(NULL, p_path.utf8().get_data(), parser.get_error_line(), parser.get_error_text().utf8().get_data(), false, ERR_HANDLER_SHADER); - return err; - } - - r_gen_code.custom_defines.clear(); - r_gen_code.uniforms.clear(); - r_gen_code.texture_uniforms.clear(); - r_gen_code.texture_hints.clear(); - r_gen_code.vertex = String(); - r_gen_code.vertex_global = String(); - r_gen_code.fragment = String(); - r_gen_code.fragment_global = String(); - r_gen_code.light = String(); - r_gen_code.uses_fragment_time = false; - r_gen_code.uses_vertex_time = false; - - used_name_defines.clear(); - used_rmode_defines.clear(); - used_flag_pointers.clear(); - - _dump_node_code(parser.get_shader(), 1, r_gen_code, *p_actions, actions[p_mode], false); - - return OK; -} - -ShaderCompilerGLES3::ShaderCompilerGLES3() { - /** CANVAS ITEM SHADER **/ - - actions[RS::SHADER_CANVAS_ITEM].renames["VERTEX"] = "outvec.xy"; - actions[RS::SHADER_CANVAS_ITEM].renames["UV"] = "uv"; - actions[RS::SHADER_CANVAS_ITEM].renames["POINT_SIZE"] = "point_size"; - - actions[RS::SHADER_CANVAS_ITEM].renames["WORLD_MATRIX"] = "modelview_matrix"; - actions[RS::SHADER_CANVAS_ITEM].renames["PROJECTION_MATRIX"] = "projection_matrix"; - actions[RS::SHADER_CANVAS_ITEM].renames["EXTRA_MATRIX"] = "extra_matrix_instance"; - actions[RS::SHADER_CANVAS_ITEM].renames["TIME"] = "time"; - actions[RS::SHADER_CANVAS_ITEM].renames["PI"] = _MKSTR(Math_PI); - actions[RS::SHADER_CANVAS_ITEM].renames["TAU"] = _MKSTR(Math_TAU); - actions[RS::SHADER_CANVAS_ITEM].renames["E"] = _MKSTR(Math_E); - actions[RS::SHADER_CANVAS_ITEM].renames["AT_LIGHT_PASS"] = "at_light_pass"; - actions[RS::SHADER_CANVAS_ITEM].renames["INSTANCE_CUSTOM"] = "instance_custom"; - - actions[RS::SHADER_CANVAS_ITEM].renames["COLOR"] = "color"; - actions[RS::SHADER_CANVAS_ITEM].renames["MODULATE"] = "final_modulate"; - actions[RS::SHADER_CANVAS_ITEM].renames["NORMAL"] = "normal"; - actions[RS::SHADER_CANVAS_ITEM].renames["NORMALMAP"] = "normal_map"; - actions[RS::SHADER_CANVAS_ITEM].renames["NORMALMAP_DEPTH"] = "normal_depth"; - actions[RS::SHADER_CANVAS_ITEM].renames["TEXTURE"] = "color_texture"; - actions[RS::SHADER_CANVAS_ITEM].renames["TEXTURE_PIXEL_SIZE"] = "color_texpixel_size"; - actions[RS::SHADER_CANVAS_ITEM].renames["NORMAL_TEXTURE"] = "normal_texture"; - actions[RS::SHADER_CANVAS_ITEM].renames["SCREEN_UV"] = "screen_uv"; - actions[RS::SHADER_CANVAS_ITEM].renames["SCREEN_TEXTURE"] = "screen_texture"; - actions[RS::SHADER_CANVAS_ITEM].renames["SCREEN_PIXEL_SIZE"] = "screen_pixel_size"; - actions[RS::SHADER_CANVAS_ITEM].renames["FRAGCOORD"] = "gl_FragCoord"; - actions[RS::SHADER_CANVAS_ITEM].renames["POINT_COORD"] = "gl_PointCoord"; - - actions[RS::SHADER_CANVAS_ITEM].renames["LIGHT_VEC"] = "light_vec"; - actions[RS::SHADER_CANVAS_ITEM].renames["LIGHT_HEIGHT"] = "light_height"; - actions[RS::SHADER_CANVAS_ITEM].renames["LIGHT_COLOR"] = "light_color"; - actions[RS::SHADER_CANVAS_ITEM].renames["LIGHT_UV"] = "light_uv"; - actions[RS::SHADER_CANVAS_ITEM].renames["LIGHT"] = "light"; - actions[RS::SHADER_CANVAS_ITEM].renames["SHADOW_COLOR"] = "shadow_color"; - actions[RS::SHADER_CANVAS_ITEM].renames["SHADOW_VEC"] = "shadow_vec"; - - actions[RS::SHADER_CANVAS_ITEM].usage_defines["COLOR"] = "#define COLOR_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["MODULATE"] = "#define MODULATE_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_PIXEL_SIZE"] = "@SCREEN_UV"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["NORMAL"] = "#define NORMAL_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; - actions[RS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["SHADOW_VEC"] = "#define SHADOW_VEC_USED\n"; - - // Ported from GLES3 - - actions[RS::SHADER_CANVAS_ITEM].usage_defines["sinh"] = "#define SINH_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["cosh"] = "#define COSH_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["tanh"] = "#define TANH_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["asinh"] = "#define ASINH_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["acosh"] = "#define ACOSH_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["atanh"] = "#define ATANH_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["determinant"] = "#define DETERMINANT_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["transpose"] = "#define TRANSPOSE_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["outerProduct"] = "#define OUTER_PRODUCT_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["round"] = "#define ROUND_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["roundEven"] = "#define ROUND_EVEN_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["inverse"] = "#define INVERSE_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["isinf"] = "#define IS_INF_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["isnan"] = "#define IS_NAN_USED\n"; - actions[RS::SHADER_CANVAS_ITEM].usage_defines["trunc"] = "#define TRUNC_USED\n"; - - /** SPATIAL SHADER **/ - - actions[RS::SHADER_SPATIAL].renames["WORLD_MATRIX"] = "world_transform"; - actions[RS::SHADER_SPATIAL].renames["INV_CAMERA_MATRIX"] = "camera_inverse_matrix"; - actions[RS::SHADER_SPATIAL].renames["CAMERA_MATRIX"] = "camera_matrix"; - actions[RS::SHADER_SPATIAL].renames["PROJECTION_MATRIX"] = "projection_matrix"; - actions[RS::SHADER_SPATIAL].renames["INV_PROJECTION_MATRIX"] = "projection_inverse_matrix"; - actions[RS::SHADER_SPATIAL].renames["MODELVIEW_MATRIX"] = "modelview"; - - actions[RS::SHADER_SPATIAL].renames["VERTEX"] = "vertex.xyz"; - actions[RS::SHADER_SPATIAL].renames["NORMAL"] = "normal"; - actions[RS::SHADER_SPATIAL].renames["TANGENT"] = "tangent"; - actions[RS::SHADER_SPATIAL].renames["BINORMAL"] = "binormal"; - actions[RS::SHADER_SPATIAL].renames["POSITION"] = "position"; - actions[RS::SHADER_SPATIAL].renames["UV"] = "uv_interp"; - actions[RS::SHADER_SPATIAL].renames["UV2"] = "uv2_interp"; - actions[RS::SHADER_SPATIAL].renames["COLOR"] = "color_interp"; - actions[RS::SHADER_SPATIAL].renames["POINT_SIZE"] = "point_size"; - // gl_InstanceID is not available in OpenGL ES 2.0 - actions[RS::SHADER_SPATIAL].renames["INSTANCE_ID"] = "0"; - - //builtins - - actions[RS::SHADER_SPATIAL].renames["TIME"] = "time"; - actions[RS::SHADER_SPATIAL].renames["PI"] = _MKSTR(Math_PI); - actions[RS::SHADER_SPATIAL].renames["TAU"] = _MKSTR(Math_TAU); - actions[RS::SHADER_SPATIAL].renames["E"] = _MKSTR(Math_E); - actions[RS::SHADER_SPATIAL].renames["VIEWPORT_SIZE"] = "viewport_size"; - - actions[RS::SHADER_SPATIAL].renames["FRAGCOORD"] = "gl_FragCoord"; - actions[RS::SHADER_SPATIAL].renames["FRONT_FACING"] = "gl_FrontFacing"; - actions[RS::SHADER_SPATIAL].renames["NORMALMAP"] = "normalmap"; - actions[RS::SHADER_SPATIAL].renames["NORMALMAP_DEPTH"] = "normaldepth"; - actions[RS::SHADER_SPATIAL].renames["ALBEDO"] = "albedo"; - actions[RS::SHADER_SPATIAL].renames["ALPHA"] = "alpha"; - actions[RS::SHADER_SPATIAL].renames["METALLIC"] = "metallic"; - actions[RS::SHADER_SPATIAL].renames["SPECULAR"] = "specular"; - actions[RS::SHADER_SPATIAL].renames["ROUGHNESS"] = "roughness"; - actions[RS::SHADER_SPATIAL].renames["RIM"] = "rim"; - actions[RS::SHADER_SPATIAL].renames["RIM_TINT"] = "rim_tint"; - actions[RS::SHADER_SPATIAL].renames["CLEARCOAT"] = "clearcoat"; - actions[RS::SHADER_SPATIAL].renames["CLEARCOAT_GLOSS"] = "clearcoat_gloss"; - actions[RS::SHADER_SPATIAL].renames["ANISOTROPY"] = "anisotropy"; - actions[RS::SHADER_SPATIAL].renames["ANISOTROPY_FLOW"] = "anisotropy_flow"; - actions[RS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength"; - actions[RS::SHADER_SPATIAL].renames["TRANSMISSION"] = "transmission"; - actions[RS::SHADER_SPATIAL].renames["AO"] = "ao"; - actions[RS::SHADER_SPATIAL].renames["AO_LIGHT_AFFECT"] = "ao_light_affect"; - actions[RS::SHADER_SPATIAL].renames["EMISSION"] = "emission"; - actions[RS::SHADER_SPATIAL].renames["POINT_COORD"] = "gl_PointCoord"; - actions[RS::SHADER_SPATIAL].renames["INSTANCE_CUSTOM"] = "instance_custom"; - actions[RS::SHADER_SPATIAL].renames["SCREEN_UV"] = "screen_uv"; - actions[RS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture"; - actions[RS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_texture"; - // Defined in GLES3, but not available in GLES2 - //actions[RS::SHADER_SPATIAL].renames["DEPTH"] = "gl_FragDepth"; - actions[RS::SHADER_SPATIAL].renames["ALPHA_SCISSOR"] = "alpha_scissor"; - actions[RS::SHADER_SPATIAL].renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB"; - - //for light - actions[RS::SHADER_SPATIAL].renames["VIEW"] = "view"; - actions[RS::SHADER_SPATIAL].renames["LIGHT_COLOR"] = "light_color"; - actions[RS::SHADER_SPATIAL].renames["LIGHT"] = "light"; - actions[RS::SHADER_SPATIAL].renames["ATTENUATION"] = "attenuation"; - actions[RS::SHADER_SPATIAL].renames["DIFFUSE_LIGHT"] = "diffuse_light"; - actions[RS::SHADER_SPATIAL].renames["SPECULAR_LIGHT"] = "specular_light"; - - actions[RS::SHADER_SPATIAL].usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n"; - actions[RS::SHADER_SPATIAL].usage_defines["BINORMAL"] = "@TANGENT"; - actions[RS::SHADER_SPATIAL].usage_defines["RIM"] = "#define LIGHT_USE_RIM\n"; - actions[RS::SHADER_SPATIAL].usage_defines["RIM_TINT"] = "@RIM"; - actions[RS::SHADER_SPATIAL].usage_defines["CLEARCOAT"] = "#define LIGHT_USE_CLEARCOAT\n"; - actions[RS::SHADER_SPATIAL].usage_defines["CLEARCOAT_GLOSS"] = "@CLEARCOAT"; - actions[RS::SHADER_SPATIAL].usage_defines["ANISOTROPY"] = "#define LIGHT_USE_ANISOTROPY\n"; - actions[RS::SHADER_SPATIAL].usage_defines["ANISOTROPY_FLOW"] = "@ANISOTROPY"; - actions[RS::SHADER_SPATIAL].usage_defines["AO"] = "#define ENABLE_AO\n"; - actions[RS::SHADER_SPATIAL].usage_defines["AO_LIGHT_AFFECT"] = "#define ENABLE_AO\n"; - actions[RS::SHADER_SPATIAL].usage_defines["UV"] = "#define ENABLE_UV_INTERP\n"; - actions[RS::SHADER_SPATIAL].usage_defines["UV2"] = "#define ENABLE_UV2_INTERP\n"; - actions[RS::SHADER_SPATIAL].usage_defines["NORMALMAP"] = "#define ENABLE_NORMALMAP\n"; - actions[RS::SHADER_SPATIAL].usage_defines["NORMALMAP_DEPTH"] = "@NORMALMAP"; - actions[RS::SHADER_SPATIAL].usage_defines["COLOR"] = "#define ENABLE_COLOR_INTERP\n"; - actions[RS::SHADER_SPATIAL].usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n"; - actions[RS::SHADER_SPATIAL].usage_defines["ALPHA_SCISSOR"] = "#define ALPHA_SCISSOR_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n"; - - actions[RS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n"; - actions[RS::SHADER_SPATIAL].usage_defines["TRANSMISSION"] = "#define TRANSMISSION_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["DEPTH_TEXTURE"] = "#define DEPTH_TEXTURE_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n"; - - actions[RS::SHADER_SPATIAL].usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; - actions[RS::SHADER_SPATIAL].usage_defines["SPECULAR_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; - - // Ported from GLES3 - - actions[RS::SHADER_SPATIAL].usage_defines["sinh"] = "#define SINH_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["cosh"] = "#define COSH_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["tanh"] = "#define TANH_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["asinh"] = "#define ASINH_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["acosh"] = "#define ACOSH_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["atanh"] = "#define ATANH_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["determinant"] = "#define DETERMINANT_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["transpose"] = "#define TRANSPOSE_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["outerProduct"] = "#define OUTER_PRODUCT_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["round"] = "#define ROUND_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["roundEven"] = "#define ROUND_EVEN_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["inverse"] = "#define INVERSE_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["isinf"] = "#define IS_INF_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["isnan"] = "#define IS_NAN_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["trunc"] = "#define TRUNC_USED\n"; - - actions[RS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n"; - - // Defined in GLES3, could be implemented in GLES2 too if there's a need for it - //actions[RS::SHADER_SPATIAL].render_mode_defines["ensure_correct_normals"] = "#define ENSURE_CORRECT_NORMALS\n"; - // Defined in GLES3, might not be possible in GLES2 as gl_FrontFacing is not available - //actions[RS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n"; - //actions[RS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n"; - - bool force_lambert = GLOBAL_GET("rendering/quality/shading/force_lambert_over_burley"); - - if (!force_lambert) { - actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n"; - } - - actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n"; - - bool force_blinn = GLOBAL_GET("rendering/quality/shading/force_blinn_over_ggx"); - - if (!force_blinn) { - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n"; - } else { - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_BLINN\n"; - } - - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n"; - - // No defines for particle shaders in OpenGL, there are no GPU particles - - vertex_name = "vertex"; - fragment_name = "fragment"; - light_name = "light"; - time_name = "TIME"; - - List<String> func_list; - - ShaderLanguage::get_builtin_funcs(&func_list); - - for (List<String>::Element *E = func_list.front(); E; E = E->next()) { - internal_functions.insert(E->get()); - } -} - -#endif // GLES3_BACKEND_ENABLED diff --git a/drivers/gles3/shader_compiler_gles3.h b/drivers/gles3/shader_compiler_gles3.h deleted file mode 100644 index 7ed882d03d..0000000000 --- a/drivers/gles3/shader_compiler_gles3.h +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************************************/ -/* shader_compiler_gles3.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef SHADER_COMPILER_OPENGL_H -#define SHADER_COMPILER_OPENGL_H - -#include "drivers/gles3/rasterizer_platforms.h" -#ifdef GLES3_BACKEND_ENABLED - -#include "core/string/string_builder.h" -#include "core/templates/pair.h" -#include "servers/rendering/shader_language.h" -#include "servers/rendering/shader_types.h" -#include "servers/rendering_server.h" - -class ShaderCompilerGLES3 { -public: - struct IdentifierActions { - Map<StringName, Pair<int *, int>> render_mode_values; - Map<StringName, bool *> render_mode_flags; - Map<StringName, bool *> usage_flag_pointers; - Map<StringName, bool *> write_flag_pointers; - - Map<StringName, ShaderLanguage::ShaderNode::Uniform> *uniforms; - }; - - struct GeneratedCode { - Vector<CharString> custom_defines; - Vector<StringName> uniforms; - Vector<StringName> texture_uniforms; - Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints; - - String vertex_global; - String vertex; - String fragment_global; - String fragment; - String light; - - bool uses_fragment_time; - bool uses_vertex_time; - }; - -private: - ShaderLanguage parser; - - struct DefaultIdentifierActions { - Map<StringName, String> renames; - Map<StringName, String> render_mode_defines; - Map<StringName, String> usage_defines; - }; - - void _dump_function_deps(ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, StringBuilder &r_to_add, Set<StringName> &r_added); - String _dump_node_code(ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope = true); - - StringName current_func_name; - StringName vertex_name; - StringName fragment_name; - StringName light_name; - StringName time_name; - - Set<StringName> used_name_defines; - Set<StringName> used_flag_pointers; - Set<StringName> used_rmode_defines; - Set<StringName> internal_functions; - - DefaultIdentifierActions actions[RS::SHADER_MAX]; - - // compatibility with godot 4 - static ShaderLanguage::DataType _get_variable_type(const StringName &p_type); - -public: - Error compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code); - - ShaderCompilerGLES3(); -}; - -#endif // GLES3_BACKEND_ENABLED - -#endif // SHADER_COMPILER_OPENGL_H diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp index 474a80aca1..7ae8b4e3bf 100644 --- a/drivers/gles3/shader_gles3.cpp +++ b/drivers/gles3/shader_gles3.cpp @@ -29,378 +29,305 @@ /*************************************************************************/ #include "shader_gles3.h" -#include "drivers/gles3/rasterizer_platforms.h" -#ifdef GLES3_BACKEND_ENABLED +#ifdef GLES3_ENABLED -#include "rasterizer_gles3.h" -#include "rasterizer_storage_gles3.h" +#include "core/io/compression.h" +#include "core/io/dir_access.h" +#include "core/io/file_access.h" -#include "core/config/project_settings.h" -#include "core/os/memory.h" -#include "core/string/print_string.h" -#include "core/string/string_builder.h" +void ShaderGLES3::_add_stage(const char *p_code, StageType p_stage_type) { + Vector<String> lines = String(p_code).split("\n"); -// #define DEBUG_OPENGL + String text; -// #include "shaders/copy.glsl.gen.h" + for (int i = 0; i < lines.size(); i++) { + String l = lines[i]; + bool push_chunk = false; -#ifdef DEBUG_OPENGL + StageTemplate::Chunk chunk; -#define DEBUG_TEST_ERROR(m_section) \ - { \ - uint32_t err = glGetError(); \ - if (err) { \ - print_line("OpenGL Error #" + itos(err) + " at: " + m_section); \ - } \ - } -#else - -#define DEBUG_TEST_ERROR(m_section) - -#endif - -ShaderGLES3 *ShaderGLES3::active = NULL; - -//#define DEBUG_SHADER - -#ifdef DEBUG_SHADER - -#define DEBUG_PRINT(m_text) print_line(m_text); - -#else - -#define DEBUG_PRINT(m_text) - -#endif - -GLint ShaderGLES3::get_uniform_location(int p_index) const { - ERR_FAIL_COND_V(!version, -1); - - return version->uniform_location[p_index]; -} + if (l.begins_with("#GLOBALS")) { + switch (p_stage_type) { + case STAGE_TYPE_VERTEX: + chunk.type = StageTemplate::Chunk::TYPE_VERTEX_GLOBALS; + break; + case STAGE_TYPE_FRAGMENT: + chunk.type = StageTemplate::Chunk::TYPE_FRAGMENT_GLOBALS; + break; + default: { + } + } -bool ShaderGLES3::bind() { - if (active != this || !version || new_conditional_version.key != conditional_version.key) { - conditional_version = new_conditional_version; - version = get_current_version(); - } else { - return false; - } + push_chunk = true; + } else if (l.begins_with("#MATERIAL_UNIFORMS")) { + chunk.type = StageTemplate::Chunk::TYPE_MATERIAL_UNIFORMS; + push_chunk = true; + } else if (l.begins_with("#CODE")) { + chunk.type = StageTemplate::Chunk::TYPE_CODE; + push_chunk = true; + chunk.code = l.replace_first("#CODE", String()).replace(":", "").strip_edges().to_upper(); + } else { + text += l + "\n"; + } - ERR_FAIL_COND_V(!version, false); + if (push_chunk) { + if (text != String()) { + StageTemplate::Chunk text_chunk; + text_chunk.type = StageTemplate::Chunk::TYPE_TEXT; + text_chunk.text = text.utf8(); + stage_templates[p_stage_type].chunks.push_back(text_chunk); + text = String(); + } + stage_templates[p_stage_type].chunks.push_back(chunk); + } - if (!version->ok) { //broken, unable to bind (do not throw error, you saw it before already when it failed compilation). - glUseProgram(0); - return false; + if (text != String()) { + StageTemplate::Chunk text_chunk; + text_chunk.type = StageTemplate::Chunk::TYPE_TEXT; + text_chunk.text = text.utf8(); + stage_templates[p_stage_type].chunks.push_back(text_chunk); + text = String(); + } } - - glUseProgram(version->id); - - DEBUG_TEST_ERROR("use program"); - - active = this; - uniforms_dirty = true; - - return true; } -void ShaderGLES3::unbind() { - version = NULL; - glUseProgram(0); - uniforms_dirty = true; - active = NULL; -} - -static void _display_error_with_code(const String &p_error, const Vector<const char *> &p_code) { - int line = 1; - String total_code; +void ShaderGLES3::_setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_name, int p_uniform_count, const char **p_uniform_names, int p_ubo_count, const UBOPair *p_ubos, int p_texture_count, const TexUnitPair *p_tex_units, int p_specialization_count, const Specialization *p_specializations, int p_variant_count, const char **p_variants) { + name = p_name; - for (int i = 0; i < p_code.size(); i++) { - total_code += String(p_code[i]); - } - - Vector<String> lines = String(total_code).split("\n"); - - for (int j = 0; j < lines.size(); j++) { - print_line(itos(line) + ": " + lines[j]); - line++; + if (p_vertex_code) { + _add_stage(p_vertex_code, STAGE_TYPE_VERTEX); } - - ERR_PRINT(p_error); -} - -static String _mkid(const String &p_id) { - String id = "m_" + p_id; - return id.replace("__", "_dus_"); //doubleunderscore is reserved in glsl -} - -ShaderGLES3::Version *ShaderGLES3::get_current_version() { - if (!valid) - return nullptr; - - Version *_v = version_map.getptr(conditional_version); - - if (_v) { - if (conditional_version.code_version != 0) { - CustomCode *cc = custom_code_map.getptr(conditional_version.code_version); - ERR_FAIL_COND_V(!cc, _v); - if (cc->version == _v->code_version) - return _v; - } else { - return _v; - } + if (p_fragment_code) { + _add_stage(p_fragment_code, STAGE_TYPE_FRAGMENT); } - if (!_v) - version_map[conditional_version] = Version(); - - Version &v = version_map[conditional_version]; - - if (!_v) { - v.uniform_location = memnew_arr(GLint, uniform_count); - } else { - if (v.ok) { - glDeleteShader(v.vert_id); - glDeleteShader(v.frag_id); - glDeleteProgram(v.id); - v.id = 0; + uniform_names = p_uniform_names; + uniform_count = p_uniform_count; + ubo_pairs = p_ubos; + ubo_count = p_ubo_count; + texunit_pairs = p_tex_units; + texunit_pair_count = p_texture_count; + specializations = p_specializations; + specialization_count = p_specialization_count; + specialization_default_mask = 0; + for (int i = 0; i < specialization_count; i++) { + if (specializations[i].default_value) { + specialization_default_mask |= (uint64_t(1) << uint64_t(i)); } } + variant_defines = p_variants; + variant_count = p_variant_count; + + StringBuilder tohash; + /* + tohash.append("[SpirvCacheKey]"); + tohash.append(RenderingDevice::get_singleton()->shader_get_spirv_cache_key()); + tohash.append("[BinaryCacheKey]"); + tohash.append(RenderingDevice::get_singleton()->shader_get_binary_cache_key()); + */ + tohash.append("[Vertex]"); + tohash.append(p_vertex_code ? p_vertex_code : ""); + tohash.append("[Fragment]"); + tohash.append(p_fragment_code ? p_fragment_code : ""); + + base_sha256 = tohash.as_string().sha256_text(); +} - v.ok = false; +RID ShaderGLES3::version_create() { + //initialize() was never called + ERR_FAIL_COND_V(variant_count == 0, RID()); - Vector<const char *> strings; + Version version; + return version_owner.make_rid(version); +} +void ShaderGLES3::_build_variant_code(StringBuilder &builder, uint32_t p_variant, const Version *p_version, const StageTemplate &p_template, uint64_t p_specialization) { #ifdef GLES_OVER_GL - strings.push_back("#version 330\n"); - strings.push_back("#define USE_GLES_OVER_GL\n"); + builder.append("#version 330\n"); + builder.append("#define USE_GLES_OVER_GL\n"); #else - strings.push_back("#version 300 es\n"); -//angle does not like -#ifdef JAVASCRIPT_ENABLED - strings.push_back("#define USE_HIGHP_PRECISION\n"); -#endif - - //if (GLOBAL_GET("rendering/opengl/compatibility/enable_high_float.Android")) { - // enable USE_HIGHP_PRECISION but safeguarded by an availability check as highp support is optional in OpenGL - // see Section 4.5.4 of the GLSL_ES_Specification_1.00 - //strings.push_back("#ifdef GL_FRAGMENT_PRECISION_HIGH\n #define USE_HIGHP_PRECISION\n#endif\n"); - //} - + builder.append("#version 300 es\n"); #endif -#ifdef ANDROID_ENABLED - strings.push_back("#define ANDROID_ENABLED\n"); -#endif - - for (int i = 0; i < custom_defines.size(); i++) { - strings.push_back(custom_defines[i].get_data()); - strings.push_back("\n"); - } - - for (int j = 0; j < conditional_count; j++) { - bool enable = (conditional_version.version & (1 << j)) > 0; - - if (enable) { - strings.push_back(conditional_defines[j]); - DEBUG_PRINT(conditional_defines[j]); + for (int i = 0; i < specialization_count; i++) { + if (p_specialization & (uint64_t(1) << uint64_t(i))) { + builder.append("#define " + String(specializations[i].name) + "\n"); } } - - // keep them around during the function - CharString code_string; - CharString code_string2; - CharString code_globals; - - CustomCode *cc = NULL; - - if (conditional_version.code_version > 0) { - cc = custom_code_map.getptr(conditional_version.code_version); - - ERR_FAIL_COND_V(!cc, NULL); - v.code_version = cc->version; - } - - // program - - v.id = glCreateProgram(); - ERR_FAIL_COND_V(v.id == 0, NULL); - - if (cc) { - for (int i = 0; i < cc->custom_defines.size(); i++) { - strings.push_back(cc->custom_defines.write[i]); - DEBUG_PRINT("CD #" + itos(i) + ": " + String(cc->custom_defines[i].get_data())); + if (p_version->uniforms.size()) { + builder.append("#define MATERIAL_UNIFORMS_USED\n"); + } + for (const KeyValue<StringName, CharString> &E : p_version->code_sections) { + builder.append(String("#define ") + String(E.key) + "_CODE_USED\n"); + } + + builder.append("\n"); //make sure defines begin at newline + builder.append(general_defines.get_data()); + builder.append(variant_defines[p_variant]); + for (int j = 0; j < p_version->custom_defines.size(); j++) { + builder.append(p_version->custom_defines[j].get_data()); + } + builder.append("\n"); //make sure defines begin at newline + + for (uint32_t i = 0; i < p_template.chunks.size(); i++) { + const StageTemplate::Chunk &chunk = p_template.chunks[i]; + switch (chunk.type) { + case StageTemplate::Chunk::TYPE_MATERIAL_UNIFORMS: { + builder.append(p_version->uniforms.get_data()); //uniforms (same for vertex and fragment) + } break; + case StageTemplate::Chunk::TYPE_VERTEX_GLOBALS: { + builder.append(p_version->vertex_globals.get_data()); // vertex globals + } break; + case StageTemplate::Chunk::TYPE_FRAGMENT_GLOBALS: { + builder.append(p_version->fragment_globals.get_data()); // fragment globals + } break; + case StageTemplate::Chunk::TYPE_CODE: { + if (p_version->code_sections.has(chunk.code)) { + builder.append(p_version->code_sections[chunk.code].get_data()); + } + } break; + case StageTemplate::Chunk::TYPE_TEXT: { + builder.append(chunk.text.get_data()); + } break; } } +} - // vertex shader - - int string_base_size = strings.size(); - - strings.push_back(vertex_code0.get_data()); - - if (cc) { - code_globals = cc->vertex_globals.ascii(); - strings.push_back(code_globals.get_data()); - } - - strings.push_back(vertex_code1.get_data()); +static void _display_error_with_code(const String &p_error, const String &p_code) { + int line = 1; + Vector<String> lines = p_code.split("\n"); - if (cc) { - code_string = cc->vertex.ascii(); - strings.push_back(code_string.get_data()); + for (int j = 0; j < lines.size(); j++) { + print_line(itos(line) + ": " + lines[j]); + line++; } - strings.push_back(vertex_code2.get_data()); - -#ifdef DEBUG_SHADER - - DEBUG_PRINT("\nVertex Code:\n\n" + String(code_string.get_data())); - -#endif - - v.vert_id = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(v.vert_id, strings.size(), &strings[0], NULL); - glCompileShader(v.vert_id); + ERR_PRINT(p_error); +} +void ShaderGLES3::_compile_specialization(Version::Specialization &spec, uint32_t p_variant, Version *p_version, uint64_t p_specialization) { + spec.id = glCreateProgram(); + spec.ok = false; GLint status; - glGetShaderiv(v.vert_id, GL_COMPILE_STATUS, &status); - if (status == GL_FALSE) { - GLsizei iloglen; - glGetShaderiv(v.vert_id, GL_INFO_LOG_LENGTH, &iloglen); - - if (iloglen < 0) { - glDeleteShader(v.vert_id); - glDeleteProgram(v.id); - v.id = 0; + //vertex stage + { + StringBuilder builder; + _build_variant_code(builder, p_variant, p_version, stage_templates[STAGE_TYPE_VERTEX], p_specialization); + + spec.vert_id = glCreateShader(GL_VERTEX_SHADER); + String builder_string = builder.as_string(); + CharString cs = builder_string.utf8(); + const char *cstr = cs.ptr(); + glShaderSource(spec.vert_id, 1, &cstr, nullptr); + glCompileShader(spec.vert_id); + + glGetShaderiv(spec.vert_id, GL_COMPILE_STATUS, &status); + if (status == GL_FALSE) { + GLsizei iloglen; + glGetShaderiv(spec.vert_id, GL_INFO_LOG_LENGTH, &iloglen); + + if (iloglen < 0) { + glDeleteShader(spec.vert_id); + glDeleteProgram(spec.id); + spec.id = 0; + + ERR_PRINT("No OpenGL vertex shader compiler log."); + } else { + if (iloglen == 0) { + iloglen = 4096; // buggy driver (Adreno 220+) + } - ERR_PRINT("No OpenGL vertex shader compiler log. What the frick?"); - } else { - if (iloglen == 0) { - iloglen = 4096; // buggy driver (Adreno 220+) - } + char *ilogmem = (char *)Memory::alloc_static(iloglen + 1); + ilogmem[iloglen] = '\0'; + glGetShaderInfoLog(spec.vert_id, iloglen, &iloglen, ilogmem); - char *ilogmem = (char *)Memory::alloc_static(iloglen + 1); - ilogmem[iloglen] = '\0'; - glGetShaderInfoLog(v.vert_id, iloglen, &iloglen, ilogmem); + String err_string = name + ": Vertex shader compilation failed:\n"; - String err_string = get_shader_name() + ": Vertex shader compilation failed:\n"; + err_string += ilogmem; - err_string += ilogmem; + _display_error_with_code(err_string, builder_string); - _display_error_with_code(err_string, strings); + Memory::free_static(ilogmem); + glDeleteShader(spec.vert_id); + glDeleteProgram(spec.id); + spec.id = 0; + } - Memory::free_static(ilogmem); - glDeleteShader(v.vert_id); - glDeleteProgram(v.id); - v.id = 0; + ERR_FAIL(); } - - ERR_FAIL_V(NULL); - } - - strings.resize(string_base_size); - - // fragment shader - - strings.push_back(fragment_code0.get_data()); - - if (cc) { - code_globals = cc->fragment_globals.ascii(); - strings.push_back(code_globals.get_data()); - } - - strings.push_back(fragment_code1.get_data()); - - if (cc) { - code_string = cc->light.ascii(); - strings.push_back(code_string.get_data()); - } - - strings.push_back(fragment_code2.get_data()); - - if (cc) { - code_string2 = cc->fragment.ascii(); - strings.push_back(code_string2.get_data()); } - strings.push_back(fragment_code3.get_data()); - -#ifdef DEBUG_SHADER + //fragment stage + { + StringBuilder builder; + _build_variant_code(builder, p_variant, p_version, stage_templates[STAGE_TYPE_FRAGMENT], p_specialization); + + spec.frag_id = glCreateShader(GL_FRAGMENT_SHADER); + String builder_string = builder.as_string(); + CharString cs = builder_string.utf8(); + const char *cstr = cs.ptr(); + glShaderSource(spec.frag_id, 1, &cstr, nullptr); + glCompileShader(spec.frag_id); + + glGetShaderiv(spec.frag_id, GL_COMPILE_STATUS, &status); + if (status == GL_FALSE) { + GLsizei iloglen; + glGetShaderiv(spec.frag_id, GL_INFO_LOG_LENGTH, &iloglen); + + if (iloglen < 0) { + glDeleteShader(spec.frag_id); + glDeleteProgram(spec.id); + spec.id = 0; + + ERR_PRINT("No OpenGL fragment shader compiler log."); + } else { + if (iloglen == 0) { + iloglen = 4096; // buggy driver (Adreno 220+) + } - if (cc) { - DEBUG_PRINT("\nFragment Code:\n\n" + String(cc->fragment_globals)); - } - DEBUG_PRINT("\nFragment Code:\n\n" + String(code_string.get_data())); -#endif + char *ilogmem = (char *)Memory::alloc_static(iloglen + 1); + ilogmem[iloglen] = '\0'; + glGetShaderInfoLog(spec.frag_id, iloglen, &iloglen, ilogmem); - v.frag_id = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(v.frag_id, strings.size(), &strings[0], NULL); - glCompileShader(v.frag_id); + String err_string = name + ": Fragment shader compilation failed:\n"; - glGetShaderiv(v.frag_id, GL_COMPILE_STATUS, &status); - if (status == GL_FALSE) { - GLsizei iloglen; - glGetShaderiv(v.frag_id, GL_INFO_LOG_LENGTH, &iloglen); + err_string += ilogmem; - if (iloglen < 0) { - glDeleteShader(v.frag_id); - glDeleteShader(v.vert_id); - glDeleteProgram(v.id); - v.id = 0; + _display_error_with_code(err_string, builder_string); - ERR_PRINT("No OpenGL fragment shader compiler log. What the frick?"); - } else { - if (iloglen == 0) { - iloglen = 4096; // buggy driver (Adreno 220+) + Memory::free_static(ilogmem); + glDeleteShader(spec.frag_id); + glDeleteProgram(spec.id); + spec.id = 0; } - char *ilogmem = (char *)Memory::alloc_static(iloglen + 1); - ilogmem[iloglen] = '\0'; - glGetShaderInfoLog(v.frag_id, iloglen, &iloglen, ilogmem); - - String err_string = get_shader_name() + ": Fragment shader compilation failed:\n"; - - err_string += ilogmem; - - _display_error_with_code(err_string, strings); - - Memory::free_static(ilogmem); - glDeleteShader(v.frag_id); - glDeleteShader(v.vert_id); - glDeleteProgram(v.id); - v.id = 0; + ERR_FAIL(); } - - ERR_FAIL_V(NULL); } - glAttachShader(v.id, v.frag_id); - glAttachShader(v.id, v.vert_id); + glAttachShader(spec.id, spec.frag_id); + glAttachShader(spec.id, spec.vert_id); - // bind the attribute locations. This has to be done before linking so that the - // linker doesn't assign some random indices - - for (int i = 0; i < attribute_pair_count; i++) { - glBindAttribLocation(v.id, attribute_pairs[i].index, attribute_pairs[i].name); - } + //for (int i = 0; i < attribute_pair_count; i++) { + // glBindAttribLocation(v.id, attribute_pairs[i].index, attribute_pairs[i].name); + //} - glLinkProgram(v.id); + glLinkProgram(spec.id); - glGetProgramiv(v.id, GL_LINK_STATUS, &status); + glGetProgramiv(spec.id, GL_LINK_STATUS, &status); if (status == GL_FALSE) { GLsizei iloglen; - glGetProgramiv(v.id, GL_INFO_LOG_LENGTH, &iloglen); + glGetProgramiv(spec.id, GL_INFO_LOG_LENGTH, &iloglen); if (iloglen < 0) { - glDeleteShader(v.frag_id); - glDeleteShader(v.vert_id); - glDeleteProgram(v.id); - v.id = 0; + glDeleteShader(spec.frag_id); + glDeleteShader(spec.vert_id); + glDeleteProgram(spec.id); + spec.id = 0; ERR_PRINT("No OpenGL program link log. What the frick?"); - ERR_FAIL_V(NULL); + ERR_FAIL(); } if (iloglen == 0) { @@ -409,33 +336,34 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() { char *ilogmem = (char *)Memory::alloc_static(iloglen + 1); ilogmem[iloglen] = '\0'; - glGetProgramInfoLog(v.id, iloglen, &iloglen, ilogmem); + glGetProgramInfoLog(spec.id, iloglen, &iloglen, ilogmem); - String err_string = get_shader_name() + ": Program linking failed:\n"; + String err_string = name + ": Program linking failed:\n"; err_string += ilogmem; - _display_error_with_code(err_string, strings); + _display_error_with_code(err_string, String()); Memory::free_static(ilogmem); - glDeleteShader(v.frag_id); - glDeleteShader(v.vert_id); - glDeleteProgram(v.id); - v.id = 0; + glDeleteShader(spec.frag_id); + glDeleteShader(spec.vert_id); + glDeleteProgram(spec.id); + spec.id = 0; - ERR_FAIL_V(NULL); + ERR_FAIL(); } // get uniform locations - glUseProgram(v.id); + glUseProgram(spec.id); + spec.uniform_location.resize(uniform_count); for (int i = 0; i < uniform_count; i++) { - v.uniform_location[i] = glGetUniformLocation(v.id, uniform_names[i]); + spec.uniform_location[i] = glGetUniformLocation(spec.id, uniform_names[i]); } for (int i = 0; i < texunit_pair_count; i++) { - GLint loc = glGetUniformLocation(v.id, texunit_pairs[i].name); + GLint loc = glGetUniformLocation(spec.id, texunit_pairs[i].name); if (loc >= 0) { if (texunit_pairs[i].index < 0) { glUniform1i(loc, max_image_units + texunit_pairs[i].index); @@ -445,672 +373,330 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() { } } - if (cc) { - // uniforms - for (int i = 0; i < cc->custom_uniforms.size(); i++) { - String native_uniform_name = _mkid(cc->custom_uniforms[i]); - GLint location = glGetUniformLocation(v.id, (native_uniform_name).ascii().get_data()); - v.custom_uniform_locations[cc->custom_uniforms[i]] = location; - } - - // textures - for (int i = 0; i < cc->texture_uniforms.size(); i++) { - String native_uniform_name = _mkid(cc->texture_uniforms[i]); - GLint location = glGetUniformLocation(v.id, (native_uniform_name).ascii().get_data()); - v.custom_uniform_locations[cc->texture_uniforms[i]] = location; - glUniform1i(location, i); + for (int i = 0; i < ubo_count; i++) { + GLint loc = glGetUniformBlockIndex(spec.id, ubo_pairs[i].name); + if (loc >= 0) { + glUniformBlockBinding(spec.id, loc, ubo_pairs[i].index); } } - - glUseProgram(0); - v.ok = true; - - if (cc) { - cc->versions.insert(conditional_version.version); + // textures + for (int i = 0; i < p_version->texture_uniforms.size(); i++) { + String native_uniform_name = p_version->texture_uniforms[i]; + GLint location = glGetUniformLocation(spec.id, (native_uniform_name).ascii().get_data()); + glUniform1i(location, i + base_texture_index); } - return &v; + glUseProgram(0); + spec.ok = true; } -GLint ShaderGLES3::get_uniform_location(const String &p_name) const { - ERR_FAIL_COND_V(!version, -1); - return glGetUniformLocation(version->id, p_name.ascii().get_data()); -} +RS::ShaderNativeSourceCode ShaderGLES3::version_get_native_source_code(RID p_version) { + Version *version = version_owner.get_or_null(p_version); + RS::ShaderNativeSourceCode source_code; + ERR_FAIL_COND_V(!version, source_code); -void ShaderGLES3::setup( - const char **p_conditional_defines, - int p_conditional_count, - const char **p_uniform_names, - int p_uniform_count, - const AttributePair *p_attribute_pairs, - int p_attribute_count, - const TexUnitPair *p_texunit_pairs, - int p_texunit_pair_count, - const char *p_vertex_code, - const char *p_fragment_code, - int p_vertex_code_start, - int p_fragment_code_start) { - ERR_FAIL_COND(version); - - conditional_version.key = 0; - new_conditional_version.key = 0; - uniform_count = p_uniform_count; - conditional_count = p_conditional_count; - conditional_defines = p_conditional_defines; - uniform_names = p_uniform_names; - vertex_code = p_vertex_code; - fragment_code = p_fragment_code; - texunit_pairs = p_texunit_pairs; - texunit_pair_count = p_texunit_pair_count; - vertex_code_start = p_vertex_code_start; - fragment_code_start = p_fragment_code_start; - attribute_pairs = p_attribute_pairs; - attribute_pair_count = p_attribute_count; + source_code.versions.resize(variant_count); - { - String globals_tag = "\nVERTEX_SHADER_GLOBALS"; - String code_tag = "\nVERTEX_SHADER_CODE"; - String code = vertex_code; - int cpos = code.find(globals_tag); - if (cpos == -1) { - vertex_code0 = code.ascii(); - } else { - vertex_code0 = code.substr(0, cpos).ascii(); - code = code.substr(cpos + globals_tag.length(), code.length()); + for (int i = 0; i < source_code.versions.size(); i++) { + //vertex stage - cpos = code.find(code_tag); + { + StringBuilder builder; + _build_variant_code(builder, i, version, stage_templates[STAGE_TYPE_VERTEX], specialization_default_mask); - if (cpos == -1) { - vertex_code1 = code.ascii(); - } else { - vertex_code1 = code.substr(0, cpos).ascii(); - vertex_code2 = code.substr(cpos + code_tag.length(), code.length()).ascii(); - } - } - } - - { - String globals_tag = "\nFRAGMENT_SHADER_GLOBALS"; - String code_tag = "\nFRAGMENT_SHADER_CODE"; - String light_code_tag = "\nLIGHT_SHADER_CODE"; - String code = fragment_code; - int cpos = code.find(globals_tag); - if (cpos == -1) { - fragment_code0 = code.ascii(); - } else { - fragment_code0 = code.substr(0, cpos).ascii(); - code = code.substr(cpos + globals_tag.length(), code.length()); + RS::ShaderNativeSourceCode::Version::Stage stage; + stage.name = "vertex"; + stage.code = builder.as_string(); - cpos = code.find(light_code_tag); + source_code.versions.write[i].stages.push_back(stage); + } - String code2; + //fragment stage + { + StringBuilder builder; + _build_variant_code(builder, i, version, stage_templates[STAGE_TYPE_FRAGMENT], specialization_default_mask); - if (cpos != -1) { - fragment_code1 = code.substr(0, cpos).ascii(); - code2 = code.substr(cpos + light_code_tag.length(), code.length()); - } else { - code2 = code; - } + RS::ShaderNativeSourceCode::Version::Stage stage; + stage.name = "fragment"; + stage.code = builder.as_string(); - cpos = code2.find(code_tag); - if (cpos == -1) { - fragment_code2 = code2.ascii(); - } else { - fragment_code2 = code2.substr(0, cpos).ascii(); - fragment_code3 = code2.substr(cpos + code_tag.length(), code2.length()).ascii(); - } + source_code.versions.write[i].stages.push_back(stage); } } - glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_image_units); - - valid = true; + return source_code; } -void ShaderGLES3::finish() { - const VersionKey *V = NULL; +String ShaderGLES3::_version_get_sha1(Version *p_version) const { + StringBuilder hash_build; - while ((V = version_map.next(V))) { - Version &v = version_map[*V]; - glDeleteShader(v.vert_id); - glDeleteShader(v.frag_id); - glDeleteProgram(v.id); + hash_build.append("[uniforms]"); + hash_build.append(p_version->uniforms.get_data()); + hash_build.append("[vertex_globals]"); + hash_build.append(p_version->vertex_globals.get_data()); + hash_build.append("[fragment_globals]"); + hash_build.append(p_version->fragment_globals.get_data()); - if (v.uniform_location) - memdelete_arr(v.uniform_location); + Vector<StringName> code_sections; + for (const KeyValue<StringName, CharString> &E : p_version->code_sections) { + code_sections.push_back(E.key); } -} - -void ShaderGLES3::clear_caches() { - const VersionKey *V = NULL; + code_sections.sort_custom<StringName::AlphCompare>(); - while ((V = version_map.next(V))) { - Version &v = version_map[*V]; - glDeleteShader(v.vert_id); - glDeleteShader(v.frag_id); - glDeleteProgram(v.id); - memdelete_arr(v.uniform_location); + for (int i = 0; i < code_sections.size(); i++) { + hash_build.append(String("[code:") + String(code_sections[i]) + "]"); + hash_build.append(p_version->code_sections[code_sections[i]].get_data()); } - - version_map.clear(); - - custom_code_map.clear(); - version = NULL; - last_custom_code = 1; - uniforms_dirty = true; -} - -uint32_t ShaderGLES3::create_custom_shader() { - custom_code_map[last_custom_code] = CustomCode(); - custom_code_map[last_custom_code].version = 1; - return last_custom_code++; -} - -void ShaderGLES3::set_custom_shader_code(uint32_t p_code_id, - const String &p_vertex, - const String &p_vertex_globals, - const String &p_fragment, - const String &p_light, - const String &p_fragment_globals, - const Vector<StringName> &p_uniforms, - const Vector<StringName> &p_texture_uniforms, - const Vector<CharString> &p_custom_defines) { - CustomCode *cc = custom_code_map.getptr(p_code_id); - ERR_FAIL_COND(!cc); - - cc->vertex = p_vertex; - cc->vertex_globals = p_vertex_globals; - cc->fragment = p_fragment; - cc->fragment_globals = p_fragment_globals; - cc->light = p_light; - cc->custom_uniforms = p_uniforms; - cc->custom_defines = p_custom_defines; - cc->texture_uniforms = p_texture_uniforms; - cc->version++; -} - -void ShaderGLES3::set_custom_shader(uint32_t p_code_id) { - new_conditional_version.code_version = p_code_id; -} - -void ShaderGLES3::free_custom_shader(uint32_t p_code_id) { - ERR_FAIL_COND(!custom_code_map.has(p_code_id)); - if (conditional_version.code_version == p_code_id) { - conditional_version.code_version = 0; //do not keep using a version that is going away - unbind(); + for (int i = 0; i < p_version->custom_defines.size(); i++) { + hash_build.append("[custom_defines:" + itos(i) + "]"); + hash_build.append(p_version->custom_defines[i].get_data()); } - VersionKey key; - key.code_version = p_code_id; - for (Set<uint32_t>::Element *E = custom_code_map[p_code_id].versions.front(); E; E = E->next()) { - key.version = E->get(); - ERR_CONTINUE(!version_map.has(key)); - Version &v = version_map[key]; - - glDeleteShader(v.vert_id); - glDeleteShader(v.frag_id); - glDeleteProgram(v.id); - memdelete_arr(v.uniform_location); - v.id = 0; - - version_map.erase(key); - } - - custom_code_map.erase(p_code_id); + return hash_build.as_string().sha1_text(); } -void ShaderGLES3::use_material(void *p_material) { - RasterizerStorageGLES3::Material *material = (RasterizerStorageGLES3::Material *)p_material; +//static const char *shader_file_header = "GLSC"; +//static const uint32_t cache_file_version = 2; - if (!material) { - return; - } +bool ShaderGLES3::_load_from_cache(Version *p_version) { +#if 0 + String sha1 = _version_get_sha1(p_version); + String path = shader_cache_dir.plus_file(name).plus_file(base_sha256).plus_file(sha1) + ".cache"; - if (!material->shader) { - return; + FileAccessRef f = FileAccess::open(path, FileAccess::READ); + if (!f) { + return false; } - Version *v = version_map.getptr(conditional_version); - - // bind uniforms - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = material->shader->uniforms.front(); E; E = E->next()) { - if (E->get().texture_order >= 0) - continue; // this is a texture, doesn't go here - - Map<StringName, GLint>::Element *L = v->custom_uniform_locations.find(E->key()); - if (!L || L->get() < 0) - continue; //uniform not valid - - GLuint location = L->get(); - - Map<StringName, Variant>::Element *V = material->params.find(E->key()); - - if (V) { - switch (E->get().type) { - case ShaderLanguage::TYPE_BOOL: { - bool boolean = V->get(); - glUniform1i(location, boolean ? 1 : 0); - } break; - - case ShaderLanguage::TYPE_BVEC2: { - int flags = V->get(); - glUniform2i(location, (flags & 1) ? 1 : 0, (flags & 2) ? 1 : 0); - } break; - - case ShaderLanguage::TYPE_BVEC3: { - int flags = V->get(); - glUniform3i(location, (flags & 1) ? 1 : 0, (flags & 2) ? 1 : 0, (flags & 4) ? 1 : 0); - - } break; - - case ShaderLanguage::TYPE_BVEC4: { - int flags = V->get(); - glUniform4i(location, (flags & 1) ? 1 : 0, (flags & 2) ? 1 : 0, (flags & 4) ? 1 : 0, (flags & 8) ? 1 : 0); - - } break; - - case ShaderLanguage::TYPE_INT: - case ShaderLanguage::TYPE_UINT: { - int value = V->get(); - glUniform1i(location, value); - } break; - - case ShaderLanguage::TYPE_IVEC2: - case ShaderLanguage::TYPE_UVEC2: { - Array r = V->get(); - const int count = 2; - if (r.size() == count) { - int values[count]; - for (int i = 0; i < count; i++) { - values[i] = r[i]; - } - glUniform2i(location, values[0], values[1]); - } - - } break; - - case ShaderLanguage::TYPE_IVEC3: - case ShaderLanguage::TYPE_UVEC3: { - Array r = V->get(); - const int count = 3; - if (r.size() == count) { - int values[count]; - for (int i = 0; i < count; i++) { - values[i] = r[i]; - } - glUniform3i(location, values[0], values[1], values[2]); - } - - } break; - - case ShaderLanguage::TYPE_IVEC4: - case ShaderLanguage::TYPE_UVEC4: { - Array r = V->get(); - const int count = 4; - if (r.size() == count) { - int values[count]; - for (int i = 0; i < count; i++) { - values[i] = r[i]; - } - glUniform4i(location, values[0], values[1], values[2], values[3]); - } - - } break; - - case ShaderLanguage::TYPE_FLOAT: { - float value = V->get(); - glUniform1f(location, value); - - } break; - - case ShaderLanguage::TYPE_VEC2: { - Vector2 value = V->get(); - glUniform2f(location, value.x, value.y); - } break; - - case ShaderLanguage::TYPE_VEC3: { - Vector3 value = V->get(); - glUniform3f(location, value.x, value.y, value.z); - } break; - - case ShaderLanguage::TYPE_VEC4: { - if (V->get().get_type() == Variant::COLOR) { - Color value = V->get(); - glUniform4f(location, value.r, value.g, value.b, value.a); - } else if (V->get().get_type() == Variant::QUATERNION) { - Quaternion value = V->get(); - glUniform4f(location, value.x, value.y, value.z, value.w); - } else { - Plane value = V->get(); - glUniform4f(location, value.normal.x, value.normal.y, value.normal.z, value.d); - } - - } break; - - case ShaderLanguage::TYPE_MAT2: { - Transform2D tr = V->get(); - GLfloat matrix[4] = { - /* build a 16x16 matrix */ - (GLfloat)tr.elements[0][0], - (GLfloat)tr.elements[0][1], - (GLfloat)tr.elements[1][0], - (GLfloat)tr.elements[1][1], - }; - glUniformMatrix2fv(location, 1, GL_FALSE, matrix); - - } break; - - case ShaderLanguage::TYPE_MAT3: { - Basis val = V->get(); - - GLfloat mat[9] = { - (GLfloat)val.elements[0][0], - (GLfloat)val.elements[1][0], - (GLfloat)val.elements[2][0], - (GLfloat)val.elements[0][1], - (GLfloat)val.elements[1][1], - (GLfloat)val.elements[2][1], - (GLfloat)val.elements[0][2], - (GLfloat)val.elements[1][2], - (GLfloat)val.elements[2][2], - }; - - glUniformMatrix3fv(location, 1, GL_FALSE, mat); - - } break; - - case ShaderLanguage::TYPE_MAT4: { - Transform2D tr = V->get(); - GLfloat matrix[16] = { /* build a 16x16 matrix */ - (GLfloat)tr.elements[0][0], - (GLfloat)tr.elements[0][1], - (GLfloat)0, - (GLfloat)0, - (GLfloat)tr.elements[1][0], - (GLfloat)tr.elements[1][1], - (GLfloat)0, - (GLfloat)0, - (GLfloat)0, - (GLfloat)0, - (GLfloat)1, - (GLfloat)0, - (GLfloat)tr.elements[2][0], - (GLfloat)tr.elements[2][1], - (GLfloat)0, - (GLfloat)1 - }; - - glUniformMatrix4fv(location, 1, GL_FALSE, matrix); - - } break; - - default: { - ERR_PRINT("ShaderNode type missing, bug?"); - } break; - } - } else if (E->get().default_value.size()) { - const Vector<ShaderLanguage::ConstantNode::Value> &values = E->get().default_value; - switch (E->get().type) { - case ShaderLanguage::TYPE_BOOL: { - glUniform1i(location, values[0].boolean); - } break; - - case ShaderLanguage::TYPE_BVEC2: { - glUniform2i(location, values[0].boolean, values[1].boolean); - } break; - - case ShaderLanguage::TYPE_BVEC3: { - glUniform3i(location, values[0].boolean, values[1].boolean, values[2].boolean); - } break; - - case ShaderLanguage::TYPE_BVEC4: { - glUniform4i(location, values[0].boolean, values[1].boolean, values[2].boolean, values[3].boolean); - } break; - - case ShaderLanguage::TYPE_INT: { - glUniform1i(location, values[0].sint); - } break; - - case ShaderLanguage::TYPE_IVEC2: { - glUniform2i(location, values[0].sint, values[1].sint); - } break; - - case ShaderLanguage::TYPE_IVEC3: { - glUniform3i(location, values[0].sint, values[1].sint, values[2].sint); - } break; - - case ShaderLanguage::TYPE_IVEC4: { - glUniform4i(location, values[0].sint, values[1].sint, values[2].sint, values[3].sint); - } break; - - case ShaderLanguage::TYPE_UINT: { - glUniform1i(location, values[0].uint); - } break; - - case ShaderLanguage::TYPE_UVEC2: { - glUniform2i(location, values[0].uint, values[1].uint); - } break; - - case ShaderLanguage::TYPE_UVEC3: { - glUniform3i(location, values[0].uint, values[1].uint, values[2].uint); - } break; - - case ShaderLanguage::TYPE_UVEC4: { - glUniform4i(location, values[0].uint, values[1].uint, values[2].uint, values[3].uint); - } break; - - case ShaderLanguage::TYPE_FLOAT: { - glUniform1f(location, values[0].real); - } break; - - case ShaderLanguage::TYPE_VEC2: { - glUniform2f(location, values[0].real, values[1].real); - } break; + char header[5] = { 0, 0, 0, 0, 0 }; + f->get_buffer((uint8_t *)header, 4); + ERR_FAIL_COND_V(header != String(shader_file_header), false); - case ShaderLanguage::TYPE_VEC3: { - glUniform3f(location, values[0].real, values[1].real, values[2].real); - } break; - - case ShaderLanguage::TYPE_VEC4: { - glUniform4f(location, values[0].real, values[1].real, values[2].real, values[3].real); - } break; - - case ShaderLanguage::TYPE_MAT2: { - GLfloat mat[4]; - - for (int i = 0; i < 4; i++) { - mat[i] = values[i].real; - } - - glUniformMatrix2fv(location, 1, GL_FALSE, mat); - } break; - - case ShaderLanguage::TYPE_MAT3: { - GLfloat mat[9]; - - for (int i = 0; i < 9; i++) { - mat[i] = values[i].real; - } - - glUniformMatrix3fv(location, 1, GL_FALSE, mat); - - } break; - - case ShaderLanguage::TYPE_MAT4: { - GLfloat mat[16]; - - for (int i = 0; i < 16; i++) { - mat[i] = values[i].real; - } - - glUniformMatrix4fv(location, 1, GL_FALSE, mat); + uint32_t file_version = f->get_32(); + if (file_version != cache_file_version) { + return false; // wrong version + } - } break; + uint32_t variant_count = f->get_32(); - case ShaderLanguage::TYPE_SAMPLER2D: { - } break; + ERR_FAIL_COND_V(variant_count != (uint32_t)variant_count, false); //should not happen but check - /* - case ShaderLanguage::TYPE_SAMPLEREXT: { - } break; -*/ - case ShaderLanguage::TYPE_ISAMPLER2D: { - } break; + for (uint32_t i = 0; i < variant_count; i++) { + uint32_t variant_size = f->get_32(); + ERR_FAIL_COND_V(variant_size == 0 && variants_enabled[i], false); + if (!variants_enabled[i]) { + continue; + } + Vector<uint8_t> variant_bytes; + variant_bytes.resize(variant_size); - case ShaderLanguage::TYPE_USAMPLER2D: { - } break; + uint32_t br = f->get_buffer(variant_bytes.ptrw(), variant_size); - case ShaderLanguage::TYPE_SAMPLERCUBE: { - } break; + ERR_FAIL_COND_V(br != variant_size, false); - case ShaderLanguage::TYPE_SAMPLER2DARRAY: - case ShaderLanguage::TYPE_ISAMPLER2DARRAY: - case ShaderLanguage::TYPE_USAMPLER2DARRAY: - case ShaderLanguage::TYPE_SAMPLER3D: - case ShaderLanguage::TYPE_ISAMPLER3D: - case ShaderLanguage::TYPE_USAMPLER3D: { - // Not implemented in OpenGL - } break; + p_version->variant_data[i] = variant_bytes; + } - case ShaderLanguage::TYPE_VOID: { - // Nothing to do? - } break; - default: { - ERR_PRINT("ShaderNode type missing, bug?"); - } break; + for (uint32_t i = 0; i < variant_count; i++) { + if (!variants_enabled[i]) { + MutexLock lock(variant_set_mutex); + p_version->variants[i] = RID(); + continue; + } + RID shader = GLES3::get_singleton()->shader_create_from_bytecode(p_version->variant_data[i]); + if (shader.is_null()) { + for (uint32_t j = 0; j < i; j++) { + GLES3::get_singleton()->free(p_version->variants[i]); } - } else { //zero + ERR_FAIL_COND_V(shader.is_null(), false); + } + { + MutexLock lock(variant_set_mutex); + p_version->variants[i] = shader; + } + } - switch (E->get().type) { - case ShaderLanguage::TYPE_BOOL: { - glUniform1i(location, GL_FALSE); - } break; + memdelete_arr(p_version->variant_data); //clear stages + p_version->variant_data = nullptr; + p_version->valid = true; + return true; +#endif + return false; +} - case ShaderLanguage::TYPE_BVEC2: { - glUniform2i(location, GL_FALSE, GL_FALSE); - } break; +void ShaderGLES3::_save_to_cache(Version *p_version) { +#if 0 + String sha1 = _version_get_sha1(p_version); + String path = shader_cache_dir.plus_file(name).plus_file(base_sha256).plus_file(sha1) + ".cache"; - case ShaderLanguage::TYPE_BVEC3: { - glUniform3i(location, GL_FALSE, GL_FALSE, GL_FALSE); - } break; + FileAccessRef f = FileAccess::open(path, FileAccess::WRITE); + ERR_FAIL_COND(!f); + f->store_buffer((const uint8_t *)shader_file_header, 4); + f->store_32(cache_file_version); //file version + uint32_t variant_count = variant_count; + f->store_32(variant_count); //variant count - case ShaderLanguage::TYPE_BVEC4: { - glUniform4i(location, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - } break; + for (uint32_t i = 0; i < variant_count; i++) { + f->store_32(p_version->variant_data[i].size()); //stage count + f->store_buffer(p_version->variant_data[i].ptr(), p_version->variant_data[i].size()); + } - case ShaderLanguage::TYPE_INT: { - glUniform1i(location, 0); - } break; + f->close(); +#endif +} - case ShaderLanguage::TYPE_IVEC2: { - glUniform2i(location, 0, 0); - } break; +void ShaderGLES3::_clear_version(Version *p_version) { + // Variants not compiled yet, just return + if (p_version->variants.size() == 0) { + return; + } - case ShaderLanguage::TYPE_IVEC3: { - glUniform3i(location, 0, 0, 0); - } break; + for (int i = 0; i < variant_count; i++) { + for (OAHashMap<uint64_t, Version::Specialization>::Iterator it = p_version->variants[i].iter(); it.valid; it = p_version->variants[i].next_iter(it)) { + if (it.valid) { + glDeleteShader(it.value->vert_id); + glDeleteShader(it.value->frag_id); + glDeleteProgram(it.value->id); + } + } + } - case ShaderLanguage::TYPE_IVEC4: { - glUniform4i(location, 0, 0, 0, 0); - } break; + p_version->variants.clear(); +} - case ShaderLanguage::TYPE_UINT: { - glUniform1i(location, 0); - } break; +void ShaderGLES3::_initialize_version(Version *p_version) { + ERR_FAIL_COND(p_version->variants.size() > 0); + p_version->variants.reserve(variant_count); + for (int i = 0; i < variant_count; i++) { + OAHashMap<uint64_t, Version::Specialization> variant; + p_version->variants.push_back(variant); + Version::Specialization spec; + _compile_specialization(spec, i, p_version, specialization_default_mask); + p_version->variants[i].insert(specialization_default_mask, spec); + } +} - case ShaderLanguage::TYPE_UVEC2: { - glUniform2i(location, 0, 0); - } break; +void ShaderGLES3::version_set_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines, const Vector<StringName> &p_texture_uniforms, bool p_initialize) { + Version *version = version_owner.get_or_null(p_version); + ERR_FAIL_COND(!version); - case ShaderLanguage::TYPE_UVEC3: { - glUniform3i(location, 0, 0, 0); - } break; + _clear_version(version); //clear if existing - case ShaderLanguage::TYPE_UVEC4: { - glUniform4i(location, 0, 0, 0, 0); - } break; + version->vertex_globals = p_vertex_globals.utf8(); + version->fragment_globals = p_fragment_globals.utf8(); + version->uniforms = p_uniforms.utf8(); + version->code_sections.clear(); + version->texture_uniforms = p_texture_uniforms; + for (const KeyValue<String, String> &E : p_code) { + version->code_sections[StringName(E.key.to_upper())] = E.value.utf8(); + } - case ShaderLanguage::TYPE_FLOAT: { - glUniform1f(location, 0); - } break; + version->custom_defines.clear(); + for (int i = 0; i < p_custom_defines.size(); i++) { + version->custom_defines.push_back(p_custom_defines[i].utf8()); + } - case ShaderLanguage::TYPE_VEC2: { - glUniform2f(location, 0, 0); - } break; + if (p_initialize) { + _initialize_version(version); + } +} - case ShaderLanguage::TYPE_VEC3: { - glUniform3f(location, 0, 0, 0); - } break; +bool ShaderGLES3::version_is_valid(RID p_version) { + Version *version = version_owner.get_or_null(p_version); + return version != nullptr; +} - case ShaderLanguage::TYPE_VEC4: { - glUniform4f(location, 0, 0, 0, 0); - } break; +bool ShaderGLES3::version_free(RID p_version) { + if (version_owner.owns(p_version)) { + Version *version = version_owner.get_or_null(p_version); + _clear_version(version); + version_owner.free(p_version); + } else { + return false; + } - case ShaderLanguage::TYPE_MAT2: { - GLfloat mat[4] = { 0, 0, 0, 0 }; + return true; +} - glUniformMatrix2fv(location, 1, GL_FALSE, mat); - } break; +bool ShaderGLES3::shader_cache_cleanup_on_start = false; - case ShaderLanguage::TYPE_MAT3: { - GLfloat mat[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +ShaderGLES3::ShaderGLES3() { +} - glUniformMatrix3fv(location, 1, GL_FALSE, mat); +void ShaderGLES3::initialize(const String &p_general_defines, int p_base_texture_index) { + general_defines = p_general_defines.utf8(); + base_texture_index = p_base_texture_index; - } break; + _init(); - case ShaderLanguage::TYPE_MAT4: { - GLfloat mat[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + if (shader_cache_dir != String()) { + StringBuilder hash_build; - glUniformMatrix4fv(location, 1, GL_FALSE, mat); + hash_build.append("[base_hash]"); + hash_build.append(base_sha256); + hash_build.append("[general_defines]"); + hash_build.append(general_defines.get_data()); + for (int i = 0; i < variant_count; i++) { + hash_build.append("[variant_defines:" + itos(i) + "]"); + hash_build.append(variant_defines[i]); + } - } break; + base_sha256 = hash_build.as_string().sha256_text(); - case ShaderLanguage::TYPE_SAMPLER2D: { - } break; + DirAccessRef d = DirAccess::open(shader_cache_dir); + ERR_FAIL_COND(!d); + if (d->change_dir(name) != OK) { + Error err = d->make_dir(name); + ERR_FAIL_COND(err != OK); + d->change_dir(name); + } - /* - case ShaderLanguage::TYPE_SAMPLEREXT: { - } break; -*/ + //erase other versions? + if (shader_cache_cleanup_on_start) { + } + // + if (d->change_dir(base_sha256) != OK) { + Error err = d->make_dir(base_sha256); + ERR_FAIL_COND(err != OK); + } + shader_cache_dir_valid = true; - case ShaderLanguage::TYPE_ISAMPLER2D: { - } break; + print_verbose("Shader '" + name + "' SHA256: " + base_sha256); + } - case ShaderLanguage::TYPE_USAMPLER2D: { - } break; + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_image_units); +} - case ShaderLanguage::TYPE_SAMPLERCUBE: { - } break; +void ShaderGLES3::set_shader_cache_dir(const String &p_dir) { + shader_cache_dir = p_dir; +} - case ShaderLanguage::TYPE_SAMPLER2DARRAY: - case ShaderLanguage::TYPE_ISAMPLER2DARRAY: - case ShaderLanguage::TYPE_USAMPLER2DARRAY: - case ShaderLanguage::TYPE_SAMPLER3D: - case ShaderLanguage::TYPE_ISAMPLER3D: - case ShaderLanguage::TYPE_USAMPLER3D: { - // Not implemented in OpenGL - } break; +void ShaderGLES3::set_shader_cache_save_compressed(bool p_enable) { + shader_cache_save_compressed = p_enable; +} - case ShaderLanguage::TYPE_VOID: { - // Nothing to do? - } break; - default: { - ERR_PRINT("ShaderNode type missing, bug?"); - } break; - } - } - } +void ShaderGLES3::set_shader_cache_save_compressed_zstd(bool p_enable) { + shader_cache_save_compressed_zstd = p_enable; } -ShaderGLES3::ShaderGLES3() { - version = NULL; - last_custom_code = 1; - uniforms_dirty = true; +void ShaderGLES3::set_shader_cache_save_debug(bool p_enable) { + shader_cache_save_debug = p_enable; } +String ShaderGLES3::shader_cache_dir; +bool ShaderGLES3::shader_cache_save_compressed = true; +bool ShaderGLES3::shader_cache_save_compressed_zstd = true; +bool ShaderGLES3::shader_cache_save_debug = true; + ShaderGLES3::~ShaderGLES3() { - finish(); + List<RID> remaining; + version_owner.get_owned_list(&remaining); + if (remaining.size()) { + ERR_PRINT(itos(remaining.size()) + " shaders of type " + name + " were never freed"); + while (remaining.size()) { + version_free(remaining.front()->get()); + remaining.pop_front(); + } + } } - -#endif // GLES3_BACKEND_ENABLED +#endif diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h index 3b9177b4eb..f344ea047f 100644 --- a/drivers/gles3/shader_gles3.h +++ b/drivers/gles3/shader_gles3.h @@ -31,8 +31,16 @@ #ifndef SHADER_OPENGL_H #define SHADER_OPENGL_H -#include "drivers/gles3/rasterizer_platforms.h" -#ifdef GLES3_BACKEND_ENABLED +#include "core/os/mutex.h" +#include "core/string/string_builder.h" +#include "core/templates/hash_map.h" +#include "core/templates/local_vector.h" +#include "core/templates/map.h" +#include "core/templates/rid_owner.h" +#include "core/variant/variant.h" +#include "servers/rendering_server.h" + +#ifdef GLES3_ENABLED // This must come first to avoid windows.h mess #include "platform_config.h" @@ -42,236 +50,197 @@ #include OPENGL_INCLUDE_H #endif -#include "core/math/camera_matrix.h" -#include "core/templates/hash_map.h" -#include "core/templates/map.h" -#include "core/templates/pair.h" -#include "core/variant/variant.h" -#include "servers/rendering/shader_language.h" - #include <stdio.h> -class RasterizerStorageGLES3; - class ShaderGLES3 { protected: - struct Enum { - uint64_t mask; - uint64_t shift; - const char *defines[16]; - }; - - struct EnumValue { - uint64_t set_mask; - uint64_t clear_mask; - }; - - struct AttributePair { + struct TexUnitPair { const char *name; int index; }; - struct UniformPair { + struct UBOPair { const char *name; - Variant::Type type_hint; + int index; }; - struct TexUnitPair { + struct Specialization { const char *name; - int index; + bool default_value = false; }; - bool uniforms_dirty; - private: - bool valid = false; - - //@TODO Optimize to a fixed set of shader pools and use a LRU - int uniform_count; - int texunit_pair_count; - int conditional_count; - int vertex_code_start; - int fragment_code_start; - int attribute_pair_count; - - struct CustomCode { - String vertex; - String vertex_globals; - String fragment; - String fragment_globals; - String light; - uint32_t version; - Vector<StringName> texture_uniforms; - Vector<StringName> custom_uniforms; - Vector<CharString> custom_defines; - Set<uint32_t> versions; - }; + //versions + CharString general_defines; + // A version is a high-level construct which is a combination of built-in and user-defined shader code + // Variants use #idefs to toggle behaviour on and off to change behaviour of the shader + // Specializations use #ifdefs to toggle behaviour on and off for performance, on supporting hardware, they will compile a version with everything enabled, and then compile more copies to improve performance + // Use specializations to enable and disabled advanced features, use variants to toggle behaviour when different data may be used (e.g. using a samplerArray vs a sampler) struct Version { - GLuint id; - GLuint vert_id; - GLuint frag_id; - GLint *uniform_location; - Vector<GLint> texture_uniform_locations; - Map<StringName, GLint> custom_uniform_locations; - uint32_t code_version; - bool ok; - Version() { - id = 0; - vert_id = 0; - frag_id = 0; - uniform_location = NULL; - code_version = 0; - ok = false; - } - }; - - Version *version; + Vector<StringName> texture_uniforms; + CharString uniforms; + CharString vertex_globals; + CharString fragment_globals; + Map<StringName, CharString> code_sections; + Vector<CharString> custom_defines; - union VersionKey { - struct { - uint32_t version; - uint32_t code_version; + struct Specialization { + GLuint id; + GLuint vert_id; + GLuint frag_id; + LocalVector<GLint> uniform_location; + LocalVector<GLint> texture_uniform_locations; + Map<StringName, GLint> custom_uniform_locations; + bool build_queued = false; + bool ok = false; + Specialization() { + id = 0; + vert_id = 0; + frag_id = 0; + } }; - uint64_t key; - bool operator==(const VersionKey &p_key) const { return key == p_key.key; } - bool operator<(const VersionKey &p_key) const { return key < p_key.key; } - }; - struct VersionKeyHash { - static _FORCE_INLINE_ uint32_t hash(const VersionKey &p_key) { return HashMapHasherDefault::hash(p_key.key); } + LocalVector<OAHashMap<uint64_t, Specialization>> variants; }; - //this should use a way more cachefriendly version.. - HashMap<VersionKey, Version, VersionKeyHash> version_map; - - HashMap<uint32_t, CustomCode> custom_code_map; - uint32_t last_custom_code; + Mutex variant_set_mutex; - VersionKey conditional_version; - VersionKey new_conditional_version; + void _compile_specialization(Version::Specialization &spec, uint32_t p_variant, Version *p_version, uint64_t p_specialization); - virtual String get_shader_name() const = 0; + void _clear_version(Version *p_version); + void _initialize_version(Version *p_version); - const char **conditional_defines; - const char **uniform_names; - const AttributePair *attribute_pairs; - const TexUnitPair *texunit_pairs; - const char *vertex_code; - const char *fragment_code; - CharString fragment_code0; - CharString fragment_code1; - CharString fragment_code2; - CharString fragment_code3; + RID_Owner<Version> version_owner; - CharString vertex_code0; - CharString vertex_code1; - CharString vertex_code2; + struct StageTemplate { + struct Chunk { + enum Type { + TYPE_MATERIAL_UNIFORMS, + TYPE_VERTEX_GLOBALS, + TYPE_FRAGMENT_GLOBALS, + TYPE_CODE, + TYPE_TEXT + }; - Vector<CharString> custom_defines; + Type type; + StringName code; + CharString text; + }; + LocalVector<Chunk> chunks; + }; - Version *get_current_version(); + String name; - static ShaderGLES3 *active; + String base_sha256; - int max_image_units; + static String shader_cache_dir; + static bool shader_cache_cleanup_on_start; + static bool shader_cache_save_compressed; + static bool shader_cache_save_compressed_zstd; + static bool shader_cache_save_debug; + bool shader_cache_dir_valid = false; - Map<StringName, Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value>>> uniform_values; + GLint max_image_units; -protected: - _FORCE_INLINE_ int _get_uniform(int p_which) const; - _FORCE_INLINE_ void _set_conditional(int p_which, bool p_value); - - void setup(const char **p_conditional_defines, - int p_conditional_count, - const char **p_uniform_names, - int p_uniform_count, - const AttributePair *p_attribute_pairs, - int p_attribute_count, - const TexUnitPair *p_texunit_pairs, - int p_texunit_pair_count, - const char *p_vertex_code, - const char *p_fragment_code, - int p_vertex_code_start, - int p_fragment_code_start); + enum StageType { + STAGE_TYPE_VERTEX, + STAGE_TYPE_FRAGMENT, + STAGE_TYPE_MAX, + }; - ShaderGLES3(); + StageTemplate stage_templates[STAGE_TYPE_MAX]; -public: - enum { - CUSTOM_SHADER_DISABLED = 0 - }; + void _build_variant_code(StringBuilder &p_builder, uint32_t p_variant, const Version *p_version, const StageTemplate &p_template, uint64_t p_specialization); - GLint get_uniform_location(const String &p_name) const; - GLint get_uniform_location(int p_index) const; + void _add_stage(const char *p_code, StageType p_stage_type); - static _FORCE_INLINE_ ShaderGLES3 *get_active() { return active; } - bool bind(); - void unbind(); + String _version_get_sha1(Version *p_version) const; + bool _load_from_cache(Version *p_version); + void _save_to_cache(Version *p_version); - inline GLuint get_program() const { return version ? version->id : 0; } + const char **uniform_names = nullptr; + int uniform_count = 0; + const UBOPair *ubo_pairs = nullptr; + int ubo_count = 0; + const TexUnitPair *texunit_pairs = nullptr; + int texunit_pair_count = 0; + int specialization_count = 0; + const Specialization *specializations = nullptr; + uint64_t specialization_default_mask = 0; + const char **variant_defines = nullptr; + int variant_count = 0; - void clear_caches(); + int base_texture_index = 0; + Version::Specialization *current_shader = nullptr; - uint32_t create_custom_shader(); - void set_custom_shader_code(uint32_t p_code_id, - const String &p_vertex, - const String &p_vertex_globals, - const String &p_fragment, - const String &p_light, - const String &p_fragment_globals, - const Vector<StringName> &p_uniforms, - const Vector<StringName> &p_texture_uniforms, - const Vector<CharString> &p_custom_defines); +protected: + ShaderGLES3(); + void _setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_name, int p_uniform_count, const char **p_uniform_names, int p_ubo_count, const UBOPair *p_ubos, int p_texture_count, const TexUnitPair *p_tex_units, int p_specialization_count, const Specialization *p_specializations, int p_variant_count, const char **p_variants); - void set_custom_shader(uint32_t p_code_id); - void free_custom_shader(uint32_t p_code_id); + _FORCE_INLINE_ void _version_bind_shader(RID p_version, int p_variant, uint64_t p_specialization) { + ERR_FAIL_INDEX(p_variant, variant_count); - uint32_t get_version_key() const { return conditional_version.version; } + Version *version = version_owner.get_or_null(p_version); + ERR_FAIL_COND(!version); - // this void* is actually a RasterizerStorageGLES3::Material, but C++ doesn't - // like forward declared nested classes. - void use_material(void *p_material); + if (version->variants.size() == 0) { + _initialize_version(version); //may lack initialization + } - _FORCE_INLINE_ uint32_t get_version() const { return new_conditional_version.version; } - _FORCE_INLINE_ bool is_version_valid() const { return version && version->ok; } + Version::Specialization *spec = version->variants[p_variant].lookup_ptr(p_specialization); + if (!spec) { + if (false) { + // Queue load this specialization and use defaults in the meantime (TODO) + + spec = version->variants[p_variant].lookup_ptr(specialization_default_mask); + } else { + // Compile on the spot + Version::Specialization s; + _compile_specialization(s, p_variant, version, p_specialization); + version->variants[p_variant].insert(p_specialization, s); + spec = version->variants[p_variant].lookup_ptr(p_specialization); + } + } else if (spec->build_queued) { + // Still queued, wait + spec = version->variants[p_variant].lookup_ptr(specialization_default_mask); + } - virtual void init() = 0; - void finish(); + ERR_FAIL_COND(!spec); // Should never happen + ERR_FAIL_COND(!spec->ok); // Should never happen - void add_custom_define(const String &p_define) { - custom_defines.push_back(p_define.utf8()); + glUseProgram(spec->id); + current_shader = spec; } - void get_custom_defines(Vector<String> *p_defines) { - for (int i = 0; i < custom_defines.size(); i++) { - p_defines->push_back(custom_defines[i].get_data()); - } + _FORCE_INLINE_ int _version_get_uniform(int p_which, RID p_version, int p_variant, uint64_t p_specialization) { + ERR_FAIL_INDEX_V(p_which, uniform_count, -1); + Version *version = version_owner.get_or_null(p_version); + ERR_FAIL_COND_V(!version, -1); + return version->variants[p_variant].lookup_ptr(p_specialization)->uniform_location[p_which]; } - void remove_custom_define(const String &p_define) { - custom_defines.erase(p_define.utf8()); - } + virtual void _init() = 0; - virtual ~ShaderGLES3(); -}; +public: + RID version_create(); + + void version_set_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines, const Vector<StringName> &p_texture_uniforms, bool p_initialize = false); + + bool version_is_valid(RID p_version); -// called a lot, made inline + bool version_free(RID p_version); -int ShaderGLES3::_get_uniform(int p_which) const { - ERR_FAIL_INDEX_V(p_which, uniform_count, -1); - ERR_FAIL_COND_V(!version, -1); - return version->uniform_location[p_which]; -} + static void set_shader_cache_dir(const String &p_dir); + static void set_shader_cache_save_compressed(bool p_enable); + static void set_shader_cache_save_compressed_zstd(bool p_enable); + static void set_shader_cache_save_debug(bool p_enable); -void ShaderGLES3::_set_conditional(int p_which, bool p_value) { - ERR_FAIL_INDEX(p_which, conditional_count); - if (p_value) - new_conditional_version.version |= (1 << p_which); - else - new_conditional_version.version &= ~(1 << p_which); -} + RS::ShaderNativeSourceCode version_get_native_source_code(RID p_version); -#endif // GLES3_BACKEND_ENABLED + void initialize(const String &p_general_defines = "", int p_base_texture_index = 0); + virtual ~ShaderGLES3(); +}; #endif // SHADER_OPENGL_H +#endif diff --git a/drivers/gles3/shaders/SCsub b/drivers/gles3/shaders/SCsub index 47d56b9947..2f56b77bdc 100644 --- a/drivers/gles3/shaders/SCsub +++ b/drivers/gles3/shaders/SCsub @@ -3,12 +3,5 @@ Import("env") if "GLES3_GLSL" in env["BUILDERS"]: - env.GLES3_GLSL("copy.glsl") env.GLES3_GLSL("canvas.glsl") - env.GLES3_GLSL("canvas_shadow.glsl") - env.GLES3_GLSL("scene.glsl") - env.GLES3_GLSL("cubemap_filter.glsl") - env.GLES3_GLSL("cube_to_dp.glsl") - env.GLES3_GLSL("effect_blur.glsl") - env.GLES3_GLSL("tonemap.glsl") - env.GLES3_GLSL("lens_distorted.glsl") + env.GLES3_GLSL("copy.glsl") diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index f2b141252a..a18c451858 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -1,665 +1,753 @@ /* clang-format off */ -[vertex] +#[modes] -#ifdef USE_GLES_OVER_GL -#define lowp -#define mediump -#define highp -#else -precision highp float; -precision highp int; -#endif +mode_quad = +mode_ninepatch = #define USE_NINEPATCH +mode_primitive = #define USE_PRIMITIVE +mode_attributes = #define USE_ATTRIBUTES -uniform highp mat4 projection_matrix; -/* clang-format on */ +#[specializations] -uniform highp mat4 modelview_matrix; -uniform highp mat4 extra_matrix; -layout(location = 0) in highp vec2 vertex; +DISABLE_LIGHTING = false -#ifdef USE_ATTRIB_LIGHT_ANGLE -// shared with tangent, not used in canvas shader -layout(location = 2) in highp float light_angle; -#endif +#[vertex] +#ifdef USE_ATTRIBUTES +layout(location = 0) in vec2 vertex_attrib; layout(location = 3) in vec4 color_attrib; layout(location = 4) in vec2 uv_attrib; -#ifdef USE_ATTRIB_MODULATE -layout(location = 5) in highp vec4 modulate_attrib; -#endif +layout(location = 10) in uvec4 bone_attrib; +layout(location = 11) in vec4 weight_attrib; -#ifdef USE_ATTRIB_LARGE_VERTEX -// shared with skeleton attributes, not used in batched shader -layout(location = 6) in highp vec2 translate_attrib; -layout(location = 7) in highp vec4 basis_attrib; #endif +/* clang-format on */ +#include "canvas_uniforms_inc.glsl" +#include "stdlib_inc.glsl" -#ifdef USE_SKELETON -layout(location = 6) in highp vec4 bone_indices; -layout(location = 7) in highp vec4 bone_weights; -#endif +uniform sampler2D transforms_texture; //texunit:-1 -#ifdef USE_INSTANCING +out vec2 uv_interp; +out vec4 color_interp; +out vec2 vertex_interp; +flat out int draw_data_instance; -layout(location = 8) in highp vec4 instance_xform0; -layout(location = 9) in highp vec4 instance_xform1; -layout(location = 10) in highp vec4 instance_xform2; -layout(location = 11) in highp vec4 instance_color; +#ifdef USE_NINEPATCH -#ifdef USE_INSTANCE_CUSTOM -layout(location = 12) in highp vec4 instance_custom_data; -#endif +out vec2 pixel_size_interp; #endif -#ifdef USE_SKELETON -uniform highp sampler2D skeleton_texture; // texunit:-3 -uniform highp ivec2 skeleton_texture_size; -uniform highp mat4 skeleton_transform; -uniform highp mat4 skeleton_transform_inverse; -#endif +#ifdef MATERIAL_UNIFORMS_USED +layout(std140) uniform MaterialUniforms{ +//ubo:4 -out vec2 uv_interp; -out vec4 color_interp; +#MATERIAL_UNIFORMS -#ifdef USE_ATTRIB_MODULATE -// modulate doesn't need interpolating but we need to send it to the fragment shader -flat out vec4 modulate_interp; +}; #endif -#ifdef MODULATE_USED -uniform vec4 final_modulate; -#endif - -uniform highp vec2 color_texpixel_size; +#GLOBALS -#ifdef USE_TEXTURE_RECT +void main() { + vec4 instance_custom = vec4(0.0); + draw_data_instance = gl_InstanceID; +#ifdef USE_PRIMITIVE -uniform vec4 dst_rect; -uniform vec4 src_rect; + //weird bug, + //this works + vec2 vertex; + vec2 uv; + vec4 color; + + if (gl_VertexID == 0) { + vertex = draw_data[draw_data_instance].point_a; + uv = draw_data[draw_data_instance].uv_a; + color = vec4(unpackHalf2x16(draw_data[draw_data_instance].color_a_rg), unpackHalf2x16(draw_data[draw_data_instance].color_a_ba)); + } else if (gl_VertexID == 1) { + vertex = draw_data[draw_data_instance].point_b; + uv = draw_data[draw_data_instance].uv_b; + color = vec4(unpackHalf2x16(draw_data[draw_data_instance].color_b_rg), unpackHalf2x16(draw_data[draw_data_instance].color_b_ba)); + } else { + vertex = draw_data[draw_data_instance].point_c; + uv = draw_data[draw_data_instance].uv_c; + color = vec4(unpackHalf2x16(draw_data[draw_data_instance].color_c_rg), unpackHalf2x16(draw_data[draw_data_instance].color_c_ba)); + } + uvec4 bones = uvec4(0, 0, 0, 0); + vec4 bone_weights = vec4(0.0); -#endif +#elif defined(USE_ATTRIBUTES) -uniform highp float time; - -#ifdef USE_LIGHTING - -// light matrices -uniform highp mat4 light_matrix; -uniform highp mat4 light_matrix_inverse; -uniform highp mat4 light_local_matrix; -uniform highp mat4 shadow_matrix; -uniform highp vec4 light_color; -uniform highp vec4 light_shadow_color; -uniform highp vec2 light_pos; -uniform highp float shadowpixel_size; -uniform highp float shadow_gradient; -uniform highp float light_height; -uniform highp float light_outside_alpha; -uniform highp float shadow_distance_mult; - -out vec4 light_uv_interp; -out vec2 transformed_light_uv; -out vec4 local_rot; - -#ifdef USE_SHADOWS -out highp vec2 pos; -#endif + vec2 vertex = vertex_attrib; + vec4 color = color_attrib * draw_data[draw_data_instance].modulation; + vec2 uv = uv_attrib; -const bool at_light_pass = true; + uvec4 bones = bone_attrib; + vec4 bone_weights = weight_attrib; #else -const bool at_light_pass = false; -#endif -/* clang-format off */ + vec2 vertex_base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); + vec2 vertex_base = vertex_base_arr[gl_VertexID]; -VERTEX_SHADER_GLOBALS + vec2 uv = draw_data[draw_data_instance].src_rect.xy + abs(draw_data[draw_data_instance].src_rect.zw) * ((draw_data[draw_data_instance].flags & FLAGS_TRANSPOSE_RECT) != uint(0) ? vertex_base.yx : vertex_base.xy); + vec4 color = draw_data[draw_data_instance].modulation; + vec2 vertex = draw_data[draw_data_instance].dst_rect.xy + abs(draw_data[draw_data_instance].dst_rect.zw) * mix(vertex_base, vec2(1.0, 1.0) - vertex_base, lessThan(draw_data[draw_data_instance].src_rect.zw, vec2(0.0, 0.0))); + uvec4 bones = uvec4(0, 0, 0, 0); -/* clang-format on */ +#endif -vec2 select(vec2 a, vec2 b, bvec2 c) { - vec2 ret; + mat4 world_matrix = mat4(vec4(draw_data[draw_data_instance].world_x, 0.0, 0.0), vec4(draw_data[draw_data_instance].world_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(draw_data[draw_data_instance].world_ofs, 0.0, 1.0)); - ret.x = c.x ? b.x : a.x; - ret.y = c.y ? b.y : a.y; + // MultiMeshes don't batch, so always read from draw_data[0] + uint instancing = draw_data[0].flags & FLAGS_INSTANCING_MASK; - return ret; -} +#ifdef USE_ATTRIBUTES +/* + if (instancing > 1) { + // trails -void main() { - vec4 color = color_attrib; - vec2 uv; + uint stride = 2 + 1 + 1; //particles always uses this format -#ifdef USE_INSTANCING - mat4 extra_matrix_instance = extra_matrix * transpose(mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0))); - color *= instance_color; + uint trail_size = instancing; -#ifdef USE_INSTANCE_CUSTOM - vec4 instance_custom = instance_custom_data; -#else - vec4 instance_custom = vec4(0.0); -#endif + uint offset = trail_size * stride * gl_InstanceID; -#else - mat4 extra_matrix_instance = extra_matrix; - vec4 instance_custom = vec4(0.0); -#endif + vec4 pcolor; + vec2 new_vertex; + { + uint boffset = offset + bone_attrib.x * stride; + new_vertex = (vec4(vertex, 0.0, 1.0) * mat4(transforms.data[boffset + 0], transforms.data[boffset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy * weight_attrib.x; + pcolor = transforms.data[boffset + 2] * weight_attrib.x; + } + if (weight_attrib.y > 0.001) { + uint boffset = offset + bone_attrib.y * stride; + new_vertex += (vec4(vertex, 0.0, 1.0) * mat4(transforms.data[boffset + 0], transforms.data[boffset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy * weight_attrib.y; + pcolor += transforms.data[boffset + 2] * weight_attrib.y; + } + if (weight_attrib.z > 0.001) { + uint boffset = offset + bone_attrib.z * stride; + new_vertex += (vec4(vertex, 0.0, 1.0) * mat4(transforms.data[boffset + 0], transforms.data[boffset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy * weight_attrib.z; + pcolor += transforms.data[boffset + 2] * weight_attrib.z; + } + if (weight_attrib.w > 0.001) { + uint boffset = offset + bone_attrib.w * stride; + new_vertex += (vec4(vertex, 0.0, 1.0) * mat4(transforms.data[boffset + 0], transforms.data[boffset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy * weight_attrib.w; + pcolor += transforms.data[boffset + 2] * weight_attrib.w; + } -#ifdef USE_TEXTURE_RECT + instance_custom = transforms.data[offset + 3]; - if (dst_rect.z < 0.0) { // Transpose is encoded as negative dst_rect.z - uv = src_rect.xy + abs(src_rect.zw) * vertex.yx; - } else { - uv = src_rect.xy + abs(src_rect.zw) * vertex; + vertex = new_vertex; + color *= pcolor; + } else*/ +#endif // USE_ATTRIBUTES +/* + { + if (instancing == 1) { + uint stride = 2; + { + if (bool(draw_data[0].flags & FLAGS_INSTANCING_HAS_COLORS)) { + stride += 1; + } + if (bool(draw_data[0].flags & FLAGS_INSTANCING_HAS_CUSTOM_DATA)) { + stride += 1; + } + } + + uint offset = stride * gl_InstanceID; + + mat4 matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)); + offset += 2; + + if (bool(draw_data[0].flags & FLAGS_INSTANCING_HAS_COLORS)) { + color *= transforms.data[offset]; + offset += 1; + } + + if (bool(draw_data[0].flags & FLAGS_INSTANCING_HAS_CUSTOM_DATA)) { + instance_custom = transforms.data[offset]; + } + + matrix = transpose(matrix); + world_matrix = world_matrix * matrix; + } + } +*/ +#if !defined(USE_ATTRIBUTES) && !defined(USE_PRIMITIVE) + if (bool(draw_data[draw_data_instance].flags & FLAGS_USING_PARTICLES)) { + //scale by texture size + vertex /= draw_data[draw_data_instance].color_texture_pixel_size; } - - vec4 outvec = vec4(0.0, 0.0, 0.0, 1.0); - - // This is what is done in the GLES 3 bindings and should - // take care of flipped rects. - // - // But it doesn't. - // I don't know why, will need to investigate further. - - outvec.xy = dst_rect.xy + abs(dst_rect.zw) * select(vertex, vec2(1.0, 1.0) - vertex, lessThan(src_rect.zw, vec2(0.0, 0.0))); - - // outvec.xy = dst_rect.xy + abs(dst_rect.zw) * vertex; -#else - vec4 outvec = vec4(vertex.xy, 0.0, 1.0); - - uv = uv_attrib; #endif +#ifdef USE_POINT_SIZE float point_size = 1.0; - +#endif { - vec2 src_vtx = outvec.xy; - /* clang-format off */ - -VERTEX_SHADER_CODE - - /* clang-format on */ +#CODE : VERTEX } - gl_PointSize = point_size; +#ifdef USE_NINEPATCH + pixel_size_interp = abs(draw_data[draw_data_instance].dst_rect.zw) * vertex_base; +#endif -#ifdef USE_ATTRIB_MODULATE - // modulate doesn't need interpolating but we need to send it to the fragment shader - modulate_interp = modulate_attrib; +#if !defined(SKIP_TRANSFORM_USED) + vertex = (world_matrix * vec4(vertex, 0.0, 1.0)).xy; #endif -#ifdef USE_ATTRIB_LARGE_VERTEX - // transform is in attributes - vec2 temp; + color_interp = color; - temp = outvec.xy; - temp.x = (outvec.x * basis_attrib.x) + (outvec.y * basis_attrib.z); - temp.y = (outvec.x * basis_attrib.y) + (outvec.y * basis_attrib.w); + if (use_pixel_snap) { + vertex = floor(vertex + 0.5); + // precision issue on some hardware creates artifacts within texture + // offset uv by a small amount to avoid + uv += 1e-5; + } - temp += translate_attrib; - outvec.xy = temp; +#ifdef USE_ATTRIBUTES +#if 0 + if (bool(draw_data[draw_data_instance].flags & FLAGS_USE_SKELETON) && bone_weights != vec4(0.0)) { //must be a valid bone + //skeleton transform + ivec4 bone_indicesi = ivec4(bone_indices); -#else + uvec2 tex_ofs = bone_indicesi.x * 2; - // transform is in uniforms -#if !defined(SKIP_TRANSFORM_USED) - outvec = extra_matrix_instance * outvec; - outvec = modelview_matrix * outvec; -#endif + mat2x4 m; + m = mat2x4( + texelFetch(skeleton_buffer, tex_ofs + 0), + texelFetch(skeleton_buffer, tex_ofs + 1)) * + bone_weights.x; -#endif // not large integer + tex_ofs = bone_indicesi.y * 2; - color_interp = color; + m += mat2x4( + texelFetch(skeleton_buffer, tex_ofs + 0), + texelFetch(skeleton_buffer, tex_ofs + 1)) * + bone_weights.y; -#ifdef USE_PIXEL_SNAP - outvec.xy = floor(outvec + 0.5).xy; - // precision issue on some hardware creates artifacts within texture - // offset uv by a small amount to avoid - uv += 1e-5; -#endif + tex_ofs = bone_indicesi.z * 2; -#ifdef USE_SKELETON + m += mat2x4( + texelFetch(skeleton_buffer, tex_ofs + 0), + texelFetch(skeleton_buffer, tex_ofs + 1)) * + bone_weights.z; - // look up transform from the "pose texture" - if (bone_weights != vec4(0.0)) { - highp mat4 bone_transform = mat4(0.0); + tex_ofs = bone_indicesi.w * 2; - for (int i = 0; i < 4; i++) { - ivec2 tex_ofs = ivec2(int(bone_indices[i]) * 2, 0); + m += mat2x4( + texelFetch(skeleton_buffer, tex_ofs + 0), + texelFetch(skeleton_buffer, tex_ofs + 1)) * + bone_weights.w; - highp mat4 b = mat4( - texel2DFetch(skeleton_texture, skeleton_texture_size, tex_ofs + ivec2(0, 0)), - texel2DFetch(skeleton_texture, skeleton_texture_size, tex_ofs + ivec2(1, 0)), - vec4(0.0, 0.0, 1.0, 0.0), - vec4(0.0, 0.0, 0.0, 1.0)); + mat4 bone_matrix = skeleton_data.skeleton_transform * transpose(mat4(m[0], m[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))) * skeleton_data.skeleton_transform_inverse; - bone_transform += b * bone_weights[i]; - } - - mat4 bone_matrix = skeleton_transform * transpose(bone_transform) * skeleton_transform_inverse; - - outvec = bone_matrix * outvec; + //outvec = bone_matrix * outvec; } - #endif +#endif + + vertex = (canvas_transform * vec4(vertex, 0.0, 1.0)).xy; + vertex_interp = vertex; uv_interp = uv; - gl_Position = projection_matrix * outvec; -#ifdef USE_LIGHTING + gl_Position = screen_transform * vec4(vertex, 0.0, 1.0); - light_uv_interp.xy = (light_matrix * outvec).xy; - light_uv_interp.zw = (light_local_matrix * outvec).xy; +#ifdef USE_POINT_SIZE + gl_PointSize = point_size; +#endif +} - transformed_light_uv = (mat3(light_matrix_inverse) * vec3(light_uv_interp.zw, 0.0)).xy; //for normal mapping +#[fragment] -#ifdef USE_SHADOWS - pos = outvec.xy; -#endif +#include "canvas_uniforms_inc.glsl" +#include "stdlib_inc.glsl" -#ifdef USE_ATTRIB_LIGHT_ANGLE - // we add a fixed offset because we are using the sign later, - // and don't want floating point error around 0.0 - float la = abs(light_angle) - 1.0; - - // vector light angle - vec4 vla; - vla.xy = vec2(cos(la), sin(la)); - vla.zw = vec2(-vla.y, vla.x); - - // vertical flip encoded in the sign - vla.zw *= sign(light_angle); - - // apply the transform matrix. - // The rotate will be encoded in the transform matrix for single rects, - // and just the flips in the light angle. - // For batching we will encode the rotation and the flips - // in the light angle, and can use the same shader. - local_rot.xy = normalize((modelview_matrix * (extra_matrix_instance * vec4(vla.xy, 0.0, 0.0))).xy); - local_rot.zw = normalize((modelview_matrix * (extra_matrix_instance * vec4(vla.zw, 0.0, 0.0))).xy); -#else - local_rot.xy = normalize((modelview_matrix * (extra_matrix_instance * vec4(1.0, 0.0, 0.0, 0.0))).xy); - local_rot.zw = normalize((modelview_matrix * (extra_matrix_instance * vec4(0.0, 1.0, 0.0, 0.0))).xy); -#ifdef USE_TEXTURE_RECT - local_rot.xy *= sign(src_rect.z); - local_rot.zw *= sign(src_rect.w); -#endif -#endif // not using light angle +uniform sampler2D atlas_texture; //texunit:-2 +uniform sampler2D shadow_atlas_texture; //texunit:-3 +uniform sampler2D screen_texture; //texunit:-4 +uniform sampler2D sdf_texture; //texunit:-5 +uniform sampler2D normal_texture; //texunit:-6 +uniform sampler2D specular_texture; //texunit:-7 -#endif -} +uniform sampler2D color_texture; //texunit:0 -/* clang-format off */ -[fragment] +in vec2 uv_interp; +in vec4 color_interp; +in vec2 vertex_interp; +flat in int draw_data_instance; + +#ifdef USE_NINEPATCH + +in vec2 pixel_size_interp; -#ifdef USE_GLES_OVER_GL -#define lowp -#define mediump -#define highp -#else -#if defined(USE_HIGHP_PRECISION) -precision highp float; -precision highp int; -#else -precision mediump float; -precision mediump int; -#endif #endif -uniform sampler2D color_texture; // texunit:-1 -/* clang-format on */ -uniform highp vec2 color_texpixel_size; -uniform mediump sampler2D normal_texture; // texunit:-2 +layout(location = 0) out vec4 frag_color; + +#ifdef MATERIAL_UNIFORMS_USED +uniform MaterialUniforms{ +//ubo:4 -in mediump vec2 uv_interp; -in mediump vec4 color_interp; +#MATERIAL_UNIFORMS -#ifdef USE_ATTRIB_MODULATE -in mediump vec4 modulate_interp; +}; #endif -uniform highp float time; +vec2 screen_uv_to_sdf(vec2 p_uv) { + return screen_to_sdf * p_uv; +} -uniform vec4 final_modulate; +float texture_sdf(vec2 p_sdf) { + vec2 uv = p_sdf * sdf_to_tex.xy + sdf_to_tex.zw; + float d = texture(sdf_texture, uv).r; + d *= SDF_MAX_LENGTH; + return d * tex_to_sdf; +} -#ifdef SCREEN_TEXTURE_USED +vec2 texture_sdf_normal(vec2 p_sdf) { + vec2 uv = p_sdf * sdf_to_tex.xy + sdf_to_tex.zw; -uniform sampler2D screen_texture; // texunit:-4 + const float EPSILON = 0.001; + return normalize(vec2( + texture(sdf_texture, uv + vec2(EPSILON, 0.0)).r - texture(sdf_texture, uv - vec2(EPSILON, 0.0)).r, + texture(sdf_texture, uv + vec2(0.0, EPSILON)).r - texture(sdf_texture, uv - vec2(0.0, EPSILON)).r)); +} -#endif +vec2 sdf_to_screen_uv(vec2 p_sdf) { + return p_sdf * sdf_to_screen; +} -#ifdef SCREEN_UV_USED +#GLOBALS -uniform vec2 screen_pixel_size; +#ifdef LIGHT_CODE_USED -#endif +vec4 light_compute( + vec3 light_vertex, + vec3 light_position, + vec3 normal, + vec4 light_color, + float light_energy, + vec4 specular_shininess, + inout vec4 shadow_modulate, + vec2 screen_uv, + vec2 uv, + vec4 color, bool is_directional) { + vec4 light = vec4(0.0); -#ifdef USE_LIGHTING +#CODE : LIGHT -uniform highp mat4 light_matrix; -uniform highp mat4 light_local_matrix; -uniform highp mat4 shadow_matrix; -uniform highp vec4 light_color; -uniform highp vec4 light_shadow_color; -uniform highp vec2 light_pos; -uniform highp float shadowpixel_size; -uniform highp float shadow_gradient; -uniform highp float light_height; -uniform highp float light_outside_alpha; -uniform highp float shadow_distance_mult; + return light; +} -uniform lowp sampler2D light_texture; // texunit:-6 -in vec4 light_uv_interp; -in vec2 transformed_light_uv; +#endif -in vec4 local_rot; +#ifdef USE_NINEPATCH -#ifdef USE_SHADOWS +float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, float margin_begin, float margin_end, int np_repeat, inout int draw_center) { + float tex_size = 1.0 / tex_pixel_size; -uniform highp sampler2D shadow_texture; // texunit:-5 -in highp vec2 pos; + if (pixel < margin_begin) { + return pixel * tex_pixel_size; + } else if (pixel >= draw_size - margin_end) { + return (tex_size - (draw_size - pixel)) * tex_pixel_size; + } else { + if (!bool(draw_data[draw_data_instance].flags & FLAGS_NINEPACH_DRAW_CENTER)) { + draw_center--; + } -#endif + // np_repeat is passed as uniform using NinePatchRect::AxisStretchMode enum. + if (np_repeat == 0) { // Stretch. + // Convert to ratio. + float ratio = (pixel - margin_begin) / (draw_size - margin_begin - margin_end); + // Scale to source texture. + return (margin_begin + ratio * (tex_size - margin_begin - margin_end)) * tex_pixel_size; + } else if (np_repeat == 1) { // Tile. + // Convert to offset. + float ofs = mod((pixel - margin_begin), tex_size - margin_begin - margin_end); + // Scale to source texture. + return (margin_begin + ofs) * tex_pixel_size; + } else if (np_repeat == 2) { // Tile Fit. + // Calculate scale. + float src_area = draw_size - margin_begin - margin_end; + float dst_area = tex_size - margin_begin - margin_end; + float scale = max(1.0, floor(src_area / max(dst_area, 0.0000001) + 0.5)); + // Convert to ratio. + float ratio = (pixel - margin_begin) / src_area; + ratio = mod(ratio * scale, 1.0); + // Scale to source texture. + return (margin_begin + ratio * dst_area) * tex_pixel_size; + } else { // Shouldn't happen, but silences compiler warning. + return 0.0; + } + } +} -const bool at_light_pass = true; -#else -const bool at_light_pass = false; #endif -uniform bool use_default_normal; +vec3 light_normal_compute(vec3 light_vec, vec3 normal, vec3 base_color, vec3 light_color, vec4 specular_shininess, bool specular_shininess_used) { + float cNdotL = max(0.0, dot(normal, light_vec)); -layout(location = 0) out mediump vec4 frag_color; + if (specular_shininess_used) { + //blinn + vec3 view = vec3(0.0, 0.0, 1.0); // not great but good enough + vec3 half_vec = normalize(view + light_vec); -/* clang-format off */ + float cNdotV = max(dot(normal, view), 0.0); + float cNdotH = max(dot(normal, half_vec), 0.0); + float cVdotH = max(dot(view, half_vec), 0.0); + float cLdotH = max(dot(light_vec, half_vec), 0.0); + float shininess = exp2(15.0 * specular_shininess.a + 1.0) * 0.25; + float blinn = pow(cNdotH, shininess); + blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); + float s = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75); -FRAGMENT_SHADER_GLOBALS + return specular_shininess.rgb * light_color * s + light_color * base_color * cNdotL; + } else { + return light_color * base_color * cNdotL; + } +} -/* clang-format on */ +//float distance = length(shadow_pos); +vec4 light_shadow_compute(uint light_base, vec4 light_color, vec4 shadow_uv +#ifdef LIGHT_CODE_USED + , + vec3 shadow_modulate +#endif +) { + float shadow; + uint shadow_mode = light_data[light_base].flags & LIGHT_FLAGS_FILTER_MASK; + + if (shadow_mode == LIGHT_FLAGS_SHADOW_NEAREST) { + shadow = textureProjLod(shadow_atlas_texture, shadow_uv, 0.0).x; + } else if (shadow_mode == LIGHT_FLAGS_SHADOW_PCF5) { + vec4 shadow_pixel_size = vec4(light_data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0); + shadow = 0.0; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 2.0, 0.0).x; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size, 0.0).x; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv, 0.0).x; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size, 0.0).x; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 2.0, 0.0).x; + shadow /= 5.0; + } else { //PCF13 + vec4 shadow_pixel_size = vec4(light_data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0); + shadow = 0.0; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 6.0, 0.0).x; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 5.0, 0.0).x; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 4.0, 0.0).x; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 3.0, 0.0).x; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 2.0, 0.0).x; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size, 0.0).x; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv, 0.0).x; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size, 0.0).x; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 2.0, 0.0).x; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 3.0, 0.0).x; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 4.0, 0.0).x; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 5.0, 0.0).x; + shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 6.0, 0.0).x; + shadow /= 13.0; + } -void light_compute( - inout vec4 light, - inout vec2 light_vec, - inout float light_height, - inout vec4 light_color, - vec2 light_uv, - inout vec4 shadow_color, - inout vec2 shadow_vec, - vec3 normal, - vec2 uv, -#if defined(SCREEN_UV_USED) - vec2 screen_uv, + vec4 shadow_color = unpackUnorm4x8(light_data[light_base].shadow_color); +#ifdef LIGHT_CODE_USED + shadow_color.rgb *= shadow_modulate; #endif - vec4 color) { -#if defined(USE_LIGHT_SHADER_CODE) + shadow_color.a *= light_color.a; //respect light alpha - /* clang-format off */ + return mix(light_color, shadow_color, shadow); +} -LIGHT_SHADER_CODE +void light_blend_compute(uint light_base, vec4 light_color, inout vec3 color) { + uint blend_mode = light_data[light_base].flags & LIGHT_FLAGS_BLEND_MASK; + + switch (blend_mode) { + case LIGHT_FLAGS_BLEND_MODE_ADD: { + color.rgb += light_color.rgb * light_color.a; + } break; + case LIGHT_FLAGS_BLEND_MODE_SUB: { + color.rgb -= light_color.rgb * light_color.a; + } break; + case LIGHT_FLAGS_BLEND_MODE_MIX: { + color.rgb = mix(color.rgb, light_color.rgb, light_color.a); + } break; + } +} - /* clang-format on */ +float msdf_median(float r, float g, float b, float a) { + return min(max(min(r, g), min(max(r, g), b)), a); +} -#endif +vec2 msdf_map(vec2 value, vec2 in_min, vec2 in_max, vec2 out_min, vec2 out_max) { + return out_min + (out_max - out_min) * (value - in_min) / (in_max - in_min); } void main() { vec4 color = color_interp; vec2 uv = uv_interp; -#ifdef USE_FORCE_REPEAT - //needs to use this to workaround GLES2/WebGL1 forcing tiling that textures that don't support it - uv = mod(uv, vec2(1.0, 1.0)); + vec2 vertex = vertex_interp; + +#if !defined(USE_ATTRIBUTES) && !defined(USE_PRIMITIVE) + +#ifdef USE_NINEPATCH + + int draw_center = 2; + uv = vec2( + map_ninepatch_axis(pixel_size_interp.x, abs(draw_data[draw_data_instance].dst_rect.z), draw_data[draw_data_instance].color_texture_pixel_size.x, draw_data[draw_data_instance].ninepatch_margins.x, draw_data[draw_data_instance].ninepatch_margins.z, int(draw_data[draw_data_instance].flags >> FLAGS_NINEPATCH_H_MODE_SHIFT) & 0x3, draw_center), + map_ninepatch_axis(pixel_size_interp.y, abs(draw_data[draw_data_instance].dst_rect.w), draw_data[draw_data_instance].color_texture_pixel_size.y, draw_data[draw_data_instance].ninepatch_margins.y, draw_data[draw_data_instance].ninepatch_margins.w, int(draw_data[draw_data_instance].flags >> FLAGS_NINEPATCH_V_MODE_SHIFT) & 0x3, draw_center)); + + if (draw_center == 0) { + color.a = 0.0; + } + + uv = uv * draw_data[draw_data_instance].src_rect.zw + draw_data[draw_data_instance].src_rect.xy; //apply region if needed + #endif + if (bool(draw_data[draw_data_instance].flags & FLAGS_CLIP_RECT_UV)) { + uv = clamp(uv, draw_data[draw_data_instance].src_rect.xy, draw_data[draw_data_instance].src_rect.xy + abs(draw_data[draw_data_instance].src_rect.zw)); + } -#if !defined(COLOR_USED) - //default behavior, texture by color - color *= texture(color_texture, uv); #endif -#ifdef SCREEN_UV_USED - vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size; +#ifndef USE_PRIMITIVE + if (bool(draw_data[draw_data_instance].flags & FLAGS_USE_MSDF)) { + float px_range = draw_data[draw_data_instance].ninepatch_margins.x; + float outline_thickness = draw_data[draw_data_instance].ninepatch_margins.y; + //float reserved1 = draw_data[draw_data_instance].ninepatch_margins.z; + //float reserved2 = draw_data[draw_data_instance].ninepatch_margins.w; + + vec4 msdf_sample = texture(color_texture, uv); + vec2 msdf_size = vec2(textureSize(color_texture, 0)); + vec2 dest_size = vec2(1.0) / fwidth(uv); + float px_size = max(0.5 * dot((vec2(px_range) / msdf_size), dest_size), 1.0); + float d = msdf_median(msdf_sample.r, msdf_sample.g, msdf_sample.b, msdf_sample.a) - 0.5; + + if (outline_thickness > 0) { + float cr = clamp(outline_thickness, 0.0, px_range / 2) / px_range; + float a = clamp((d + cr) * px_size, 0.0, 1.0); + color.a = a * color.a; + } else { + float a = clamp(d * px_size + 0.5, 0.0, 1.0); + color.a = a * color.a; + } + + } else { +#else + { #endif + color *= texture(color_texture, uv); + } + + uint light_count = (draw_data[draw_data_instance].flags >> FLAGS_LIGHT_COUNT_SHIFT) & uint(0xF); //max 16 lights + bool using_light = light_count > uint(0) || directional_light_count > uint(0); vec3 normal; #if defined(NORMAL_USED) - bool normal_used = true; #else bool normal_used = false; #endif - if (use_default_normal) { - normal.xy = texture(normal_texture, uv).xy * 2.0 - 1.0; + if (normal_used || (using_light && bool(draw_data[draw_data_instance].flags & FLAGS_DEFAULT_NORMAL_MAP_USED))) { + normal.xy = texture(normal_texture, uv).xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); normal.z = sqrt(1.0 - dot(normal.xy, normal.xy)); normal_used = true; } else { normal = vec3(0.0, 0.0, 1.0); } - { - float normal_depth = 1.0; - -#if defined(NORMALMAP_USED) - vec3 normal_map = vec3(0.0, 0.0, 1.0); - normal_used = true; -#endif - - /* clang-format off */ + vec4 specular_shininess; -FRAGMENT_SHADER_CODE +#if defined(SPECULAR_SHININESS_USED) - /* clang-format on */ - -#if defined(NORMALMAP_USED) - normal = mix(vec3(0.0, 0.0, 1.0), normal_map * vec3(2.0, -2.0, 1.0) - vec3(1.0, -1.0, 0.0), normal_depth); -#endif - } - -#ifdef USE_ATTRIB_MODULATE - color *= modulate_interp; + bool specular_shininess_used = true; #else -#if !defined(MODULATE_USED) - color *= final_modulate; -#endif + bool specular_shininess_used = false; #endif -#ifdef USE_LIGHTING - - vec2 light_vec = transformed_light_uv; - vec2 shadow_vec = transformed_light_uv; - - if (normal_used) { - normal.xy = mat2(local_rot.xy, local_rot.zw) * normal.xy; + if (specular_shininess_used || (using_light && normal_used && bool(draw_data[draw_data_instance].flags & FLAGS_DEFAULT_SPECULAR_MAP_USED))) { + specular_shininess = texture(specular_texture, uv); + specular_shininess *= unpackUnorm4x8(draw_data[draw_data_instance].specular_shininess); + specular_shininess_used = true; + } else { + specular_shininess = vec4(1.0); } - float att = 1.0; - - vec2 light_uv = light_uv_interp.xy; - vec4 light = texture(light_texture, light_uv); - - if (any(lessThan(light_uv_interp.xy, vec2(0.0, 0.0))) || any(greaterThanEqual(light_uv_interp.xy, vec2(1.0, 1.0)))) { - color.a *= light_outside_alpha; //invisible - - } else { - float real_light_height = light_height; - vec4 real_light_color = light_color; - vec4 real_light_shadow_color = light_shadow_color; - -#if defined(USE_LIGHT_SHADER_CODE) - //light is written by the light shader - light_compute( - light, - light_vec, - real_light_height, - real_light_color, - light_uv, - real_light_shadow_color, - shadow_vec, - normal, - uv, #if defined(SCREEN_UV_USED) - screen_uv, -#endif - color); + vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size; +#else + vec2 screen_uv = vec2(0.0); #endif - light *= real_light_color; - - if (normal_used) { - vec3 light_normal = normalize(vec3(light_vec, -real_light_height)); - light *= max(dot(-light_normal, normal), 0.0); - } + vec3 light_vertex = vec3(vertex, 0.0); + vec2 shadow_vertex = vertex; - color *= light; - -#ifdef USE_SHADOWS + { + float normal_map_depth = 1.0; -#ifdef SHADOW_VEC_USED - mat3 inverse_light_matrix = mat3(light_matrix); - inverse_light_matrix[0] = normalize(inverse_light_matrix[0]); - inverse_light_matrix[1] = normalize(inverse_light_matrix[1]); - inverse_light_matrix[2] = normalize(inverse_light_matrix[2]); - shadow_vec = (inverse_light_matrix * vec3(shadow_vec, 0.0)).xy; -#else - shadow_vec = light_uv_interp.zw; +#if defined(NORMAL_MAP_USED) + vec3 normal_map = vec3(0.0, 0.0, 1.0); + normal_used = true; #endif - float angle_to_light = -atan(shadow_vec.x, shadow_vec.y); - float PI = 3.14159265358979323846264; - /*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays - float ang*/ - - float su, sz; - - float abs_angle = abs(angle_to_light); - vec2 point; - float sh; - if (abs_angle < 45.0 * PI / 180.0) { - point = shadow_vec; - sh = 0.0 + (1.0 / 8.0); - } else if (abs_angle > 135.0 * PI / 180.0) { - point = -shadow_vec; - sh = 0.5 + (1.0 / 8.0); - } else if (angle_to_light > 0.0) { - point = vec2(shadow_vec.y, -shadow_vec.x); - sh = 0.25 + (1.0 / 8.0); - } else { - point = vec2(-shadow_vec.y, shadow_vec.x); - sh = 0.75 + (1.0 / 8.0); - } +#CODE : FRAGMENT - highp vec4 s = shadow_matrix * vec4(point, 0.0, 1.0); - s.xyz /= s.w; - su = s.x * 0.5 + 0.5; - sz = s.z * 0.5 + 0.5; - //sz=lightlength(light_vec); +#if defined(NORMAL_MAP_USED) + normal = mix(vec3(0.0, 0.0, 1.0), normal_map * vec3(2.0, -2.0, 1.0) - vec3(1.0, -1.0, 0.0), normal_map_depth); +#endif + } - highp float shadow_attenuation = 0.0; + if (normal_used) { + //convert by item transform + normal.xy = mat2(normalize(draw_data[draw_data_instance].world_x), normalize(draw_data[draw_data_instance].world_y)) * normal.xy; + //convert by canvas transform + normal = normalize((canvas_normal_transform * vec4(normal, 0.0)).xyz); + } -#ifdef USE_RGBA_SHADOWS -#define SHADOW_DEPTH(m_tex, m_uv) dot(texture((m_tex), (m_uv)), vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0)) + vec3 base_color = color.rgb; + if (bool(draw_data[draw_data_instance].flags & FLAGS_USING_LIGHT_MASK)) { + color = vec4(0.0); //invisible by default due to using light mask + } +#ifdef MODE_LIGHT_ONLY + color = vec4(0.0); #else + color *= canvas_modulation; +#endif -#define SHADOW_DEPTH(m_tex, m_uv) (texture((m_tex), (m_uv)).r) +#if !defined(DISABLE_LIGHTING) && !defined(MODE_UNSHADED) -#endif + for (uint i = uint(0); i < directional_light_count; i++) { + uint light_base = i; -#ifdef SHADOW_USE_GRADIENT + vec2 direction = light_data[light_base].position; + vec4 light_color = light_data[light_base].color; - /* clang-format off */ - /* GLSL es 100 doesn't support line continuation characters(backslashes) */ -#define SHADOW_TEST(m_ofs) { highp float sd = SHADOW_DEPTH(shadow_texture, vec2(m_ofs, sh)); shadow_attenuation += 1.0 - smoothstep(sd, sd + shadow_gradient, sz); } +#ifdef LIGHT_CODE_USED + vec4 shadow_modulate = vec4(1.0); + light_color = light_compute(light_vertex, vec3(direction, light_data[light_base].height), normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, true); #else -#define SHADOW_TEST(m_ofs) { highp float sd = SHADOW_DEPTH(shadow_texture, vec2(m_ofs, sh)); shadow_attenuation += step(sz, sd); } - /* clang-format on */ - + if (normal_used) { + vec3 light_vec = normalize(mix(vec3(direction, 0.0), vec3(0, 0, 1), light_data[light_base].height)); + light_color.rgb = light_normal_compute(light_vec, normal, base_color, light_color.rgb, specular_shininess, specular_shininess_used); + } #endif -#ifdef SHADOW_FILTER_NEAREST + if (bool(light_data[light_base].flags & LIGHT_FLAGS_HAS_SHADOW)) { + vec2 shadow_pos = (vec4(shadow_vertex, 0.0, 1.0) * mat4(light_data[light_base].shadow_matrix[0], light_data[light_base].shadow_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations. - SHADOW_TEST(su); + vec4 shadow_uv = vec4(shadow_pos.x, light_data[light_base].shadow_y_ofs, shadow_pos.y * light_data[light_base].shadow_zfar_inv, 1.0); + light_color = light_shadow_compute(light_base, light_color, shadow_uv +#ifdef LIGHT_CODE_USED + , + shadow_modulate.rgb #endif + ); + } -#ifdef SHADOW_FILTER_PCF3 - - SHADOW_TEST(su + shadowpixel_size); - SHADOW_TEST(su); - SHADOW_TEST(su - shadowpixel_size); - shadow_attenuation /= 3.0; + light_blend_compute(light_base, light_color, color.rgb); + } -#endif + // Positional Lights -#ifdef SHADOW_FILTER_PCF5 + for (uint i = uint(0); i < MAX_LIGHTS_PER_ITEM; i++) { + if (i >= light_count) { + break; + } + uint light_base; + if (i < uint(8)) { + if (i < uint(4)) { + light_base = draw_data[draw_data_instance].lights.x; + } else { + light_base = draw_data[draw_data_instance].lights.y; + } + } else { + if (i < uint(12)) { + light_base = draw_data[draw_data_instance].lights.z; + } else { + light_base = draw_data[draw_data_instance].lights.w; + } + } + light_base >>= (i & uint(3)) * uint(8); + light_base &= uint(0xFF); - SHADOW_TEST(su + shadowpixel_size * 2.0); - SHADOW_TEST(su + shadowpixel_size); - SHADOW_TEST(su); - SHADOW_TEST(su - shadowpixel_size); - SHADOW_TEST(su - shadowpixel_size * 2.0); - shadow_attenuation /= 5.0; + vec2 tex_uv = (vec4(vertex, 0.0, 1.0) * mat4(light_data[light_base].texture_matrix[0], light_data[light_base].texture_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations. + vec2 tex_uv_atlas = tex_uv * light_data[light_base].atlas_rect.zw + light_data[light_base].atlas_rect.xy; + vec4 light_color = textureLod(atlas_texture, tex_uv_atlas, 0.0); + vec4 light_base_color = light_data[light_base].color; -#endif +#ifdef LIGHT_CODE_USED -#ifdef SHADOW_FILTER_PCF7 + vec4 shadow_modulate = vec4(1.0); + vec3 light_position = vec3(light_data[light_base].position, light_data[light_base].height); - SHADOW_TEST(su + shadowpixel_size * 3.0); - SHADOW_TEST(su + shadowpixel_size * 2.0); - SHADOW_TEST(su + shadowpixel_size); - SHADOW_TEST(su); - SHADOW_TEST(su - shadowpixel_size); - SHADOW_TEST(su - shadowpixel_size * 2.0); - SHADOW_TEST(su - shadowpixel_size * 3.0); - shadow_attenuation /= 7.0; - -#endif + light_color.rgb *= light_base_color.rgb; + light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, false); +#else -#ifdef SHADOW_FILTER_PCF9 + light_color.rgb *= light_base_color.rgb * light_base_color.a; - SHADOW_TEST(su + shadowpixel_size * 4.0); - SHADOW_TEST(su + shadowpixel_size * 3.0); - SHADOW_TEST(su + shadowpixel_size * 2.0); - SHADOW_TEST(su + shadowpixel_size); - SHADOW_TEST(su); - SHADOW_TEST(su - shadowpixel_size); - SHADOW_TEST(su - shadowpixel_size * 2.0); - SHADOW_TEST(su - shadowpixel_size * 3.0); - SHADOW_TEST(su - shadowpixel_size * 4.0); - shadow_attenuation /= 9.0; + if (normal_used) { + vec3 light_pos = vec3(light_data[light_base].position, light_data[light_base].height); + vec3 pos = light_vertex; + vec3 light_vec = normalize(light_pos - pos); + float cNdotL = max(0.0, dot(normal, light_vec)); + light_color.rgb = light_normal_compute(light_vec, normal, base_color, light_color.rgb, specular_shininess, specular_shininess_used); + } #endif + if (any(lessThan(tex_uv, vec2(0.0, 0.0))) || any(greaterThanEqual(tex_uv, vec2(1.0, 1.0)))) { + //if outside the light texture, light color is zero + light_color.a = 0.0; + } -#ifdef SHADOW_FILTER_PCF13 - - SHADOW_TEST(su + shadowpixel_size * 6.0); - SHADOW_TEST(su + shadowpixel_size * 5.0); - SHADOW_TEST(su + shadowpixel_size * 4.0); - SHADOW_TEST(su + shadowpixel_size * 3.0); - SHADOW_TEST(su + shadowpixel_size * 2.0); - SHADOW_TEST(su + shadowpixel_size); - SHADOW_TEST(su); - SHADOW_TEST(su - shadowpixel_size); - SHADOW_TEST(su - shadowpixel_size * 2.0); - SHADOW_TEST(su - shadowpixel_size * 3.0); - SHADOW_TEST(su - shadowpixel_size * 4.0); - SHADOW_TEST(su - shadowpixel_size * 5.0); - SHADOW_TEST(su - shadowpixel_size * 6.0); - shadow_attenuation /= 13.0; - -#endif + if (bool(light_data[light_base].flags & LIGHT_FLAGS_HAS_SHADOW)) { + vec2 shadow_pos = (vec4(shadow_vertex, 0.0, 1.0) * mat4(light_data[light_base].shadow_matrix[0], light_data[light_base].shadow_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations. + + vec2 pos_norm = normalize(shadow_pos); + vec2 pos_abs = abs(pos_norm); + vec2 pos_box = pos_norm / max(pos_abs.x, pos_abs.y); + vec2 pos_rot = pos_norm * mat2(vec2(0.7071067811865476, -0.7071067811865476), vec2(0.7071067811865476, 0.7071067811865476)); //is there a faster way to 45 degrees rot? + float tex_ofs; + float distance; + if (pos_rot.y > 0) { + if (pos_rot.x > 0) { + tex_ofs = pos_box.y * 0.125 + 0.125; + distance = shadow_pos.x; + } else { + tex_ofs = pos_box.x * -0.125 + (0.25 + 0.125); + distance = shadow_pos.y; + } + } else { + if (pos_rot.x < 0) { + tex_ofs = pos_box.y * -0.125 + (0.5 + 0.125); + distance = -shadow_pos.x; + } else { + tex_ofs = pos_box.x * 0.125 + (0.75 + 0.125); + distance = -shadow_pos.y; + } + } + + distance *= light_data[light_base].shadow_zfar_inv; + + //float distance = length(shadow_pos); + vec4 shadow_uv = vec4(tex_ofs, light_data[light_base].shadow_y_ofs, distance, 1.0); + + light_color = light_shadow_compute(light_base, light_color, shadow_uv +#ifdef LIGHT_CODE_USED + , + shadow_modulate.rgb +#endif + ); + } - //color *= shadow_attenuation; - color = mix(real_light_shadow_color, color, shadow_attenuation); -//use shadows -#endif + light_blend_compute(light_base, light_color, color.rgb); } - -//use lighting -#endif +#endif // UNSHADED frag_color = color; } diff --git a/drivers/gles3/shaders/canvas_shadow.glsl b/drivers/gles3/shaders/canvas_shadow.glsl index 2b3be43f6e..65389c211a 100644 --- a/drivers/gles3/shaders/canvas_shadow.glsl +++ b/drivers/gles3/shaders/canvas_shadow.glsl @@ -10,7 +10,7 @@ precision highp float; precision highp int; #endif -layout(location = 0) highp vec3 vertex; +layout(location = 0) in highp vec3 vertex; uniform highp mat4 projection_matrix; /* clang-format on */ diff --git a/drivers/gles3/shaders/canvas_uniforms_inc.glsl b/drivers/gles3/shaders/canvas_uniforms_inc.glsl new file mode 100644 index 0000000000..e08a15e59d --- /dev/null +++ b/drivers/gles3/shaders/canvas_uniforms_inc.glsl @@ -0,0 +1,120 @@ + +#define MAX_LIGHTS_PER_ITEM uint(16) + +#define M_PI 3.14159265359 + +#define SDF_MAX_LENGTH 16384.0 + +//1 means enabled, 2+ means trails in use +#define FLAGS_INSTANCING_MASK uint(0x7F) +#define FLAGS_INSTANCING_HAS_COLORS uint(1 << 7) +#define FLAGS_INSTANCING_HAS_CUSTOM_DATA uint(1 << 8) + +#define FLAGS_CLIP_RECT_UV uint(1 << 9) +#define FLAGS_TRANSPOSE_RECT uint(1 << 10) +#define FLAGS_USING_LIGHT_MASK uint(1 << 11) +#define FLAGS_NINEPACH_DRAW_CENTER uint(1 << 12) +#define FLAGS_USING_PARTICLES uint(1 << 13) + +#define FLAGS_NINEPATCH_H_MODE_SHIFT 16 +#define FLAGS_NINEPATCH_V_MODE_SHIFT 18 + +#define FLAGS_LIGHT_COUNT_SHIFT 20 + +#define FLAGS_DEFAULT_NORMAL_MAP_USED uint(1 << 26) +#define FLAGS_DEFAULT_SPECULAR_MAP_USED uint(1 << 27) + +#define FLAGS_USE_MSDF uint(1 << 28) + +// must be always 128 bytes long +struct DrawData { + vec2 world_x; + vec2 world_y; + vec2 world_ofs; + vec2 color_texture_pixel_size; +#ifdef USE_PRIMITIVE + vec2 point_a; + vec2 point_b; + vec2 point_c; + vec2 uv_a; + vec2 uv_b; + vec2 uv_c; + uint color_a_rg; + uint color_a_ba; + uint color_b_rg; + uint color_b_ba; + uint color_c_rg; + uint color_c_ba; +#else + vec4 modulation; + vec4 ninepatch_margins; + vec4 dst_rect; //for built-in rect and UV + vec4 src_rect; + uint pad; + uint pad2; +#endif + uint flags; + uint specular_shininess; + uvec4 lights; +}; + +layout(std140) uniform GlobalVariableData { //ubo:1 + vec4 global_variables[MAX_GLOBAL_VARIABLES]; +}; + +layout(std140) uniform CanvasData { //ubo:0 + mat4 canvas_transform; + mat4 screen_transform; + mat4 canvas_normal_transform; + vec4 canvas_modulation; + vec2 screen_pixel_size; + float time; + bool use_pixel_snap; + + vec4 sdf_to_tex; + vec2 screen_to_sdf; + vec2 sdf_to_screen; + + uint directional_light_count; + float tex_to_sdf; + uint pad1; + uint pad2; +}; + +#define LIGHT_FLAGS_BLEND_MASK uint(3 << 16) +#define LIGHT_FLAGS_BLEND_MODE_ADD uint(0 << 16) +#define LIGHT_FLAGS_BLEND_MODE_SUB uint(1 << 16) +#define LIGHT_FLAGS_BLEND_MODE_MIX uint(2 << 16) +#define LIGHT_FLAGS_BLEND_MODE_MASK uint(3 << 16) +#define LIGHT_FLAGS_HAS_SHADOW uint(1 << 20) +#define LIGHT_FLAGS_FILTER_SHIFT 22 +#define LIGHT_FLAGS_FILTER_MASK uint(3 << 22) +#define LIGHT_FLAGS_SHADOW_NEAREST uint(0 << 22) +#define LIGHT_FLAGS_SHADOW_PCF5 uint(1 << 22) +#define LIGHT_FLAGS_SHADOW_PCF13 uint(2 << 22) + +struct Light { + mat2x4 texture_matrix; //light to texture coordinate matrix (transposed) + mat2x4 shadow_matrix; //light to shadow coordinate matrix (transposed) + vec4 color; + + uint shadow_color; // packed + uint flags; //index to light texture + float shadow_pixel_size; + float height; + + vec2 position; + float shadow_zfar_inv; + float shadow_y_ofs; + + vec4 atlas_rect; +}; + +layout(std140) uniform LightData { //ubo:2 + Light light_data[MAX_LIGHTS]; +}; + +layout(std140) uniform DrawDataInstances { //ubo:3 + + DrawData draw_data[MAX_DRAW_DATA_INSTANCES]; +}; diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl index 598c6fd614..62332a15a7 100644 --- a/drivers/gles3/shaders/copy.glsl +++ b/drivers/gles3/shaders/copy.glsl @@ -1,5 +1,21 @@ /* clang-format off */ -[vertex] +#[modes] + +mode_default = +mode_cubemap = #define USE_CUBEMAP +mode_panorama = #define USE_PANORAMA +mode_copy_section = #define USE_COPY_SECTION +mode_asym_pano = #define USE_ASYM_PANO +mode_no_alpha = #define USE_NO_ALPHA +mode_custom_alpha = #define USE_CUSTOM_ALPHA +mode_multiplier = #define USE_MULTIPLIER +mode_sep_cbcr_texture = #define USE_SEP_CBCR_TEXTURE +mode_ycbcr_to_rgb = #define USE_YCBCR_TO_RGB + +#[specializations] + + +#[vertex] #ifdef USE_GLES_OVER_GL #define lowp @@ -10,16 +26,16 @@ precision highp float; precision highp int; #endif -layout(location = 0) highp vec4 vertex_attrib; +layout(location = 0) in highp vec4 vertex_attrib; /* clang-format on */ #if defined(USE_CUBEMAP) || defined(USE_PANORAMA) -layout(location = 4) vec3 cube_in; +layout(location = 4) in vec3 cube_in; #else -layout(location = 4) vec2 uv_in; +layout(location = 4) in vec2 uv_in; #endif -layout(location = 5) vec2 uv2_in; +layout(location = 5) in vec2 uv2_in; #if defined(USE_CUBEMAP) || defined(USE_PANORAMA) out vec3 cube_interp; @@ -28,11 +44,6 @@ out vec2 uv_interp; #endif out vec2 uv2_interp; -// These definitions are here because the shader-wrapper builder does -// not understand `#elif defined()` -#ifdef USE_DISPLAY_TRANSFORM -#endif - #ifdef USE_COPY_SECTION uniform highp vec4 copy_section; #elif defined(USE_DISPLAY_TRANSFORM) @@ -60,7 +71,7 @@ void main() { } /* clang-format off */ -[fragment] +#[fragment] #define M_PI 3.14159265359 @@ -96,7 +107,7 @@ uniform samplerCube source_cube; // texunit:0 uniform sampler2D source; // texunit:0 #endif -#ifdef SEP_CBCR_TEXTURE +#ifdef USE_SEP_CBCR_TEXTURE uniform sampler2D CbCr; //texunit:1 #endif @@ -156,8 +167,8 @@ void main() { vec4 color = texturePanorama(source, normalize(cube_normal.xyz)); #elif defined(USE_CUBEMAP) - vec4 color = textureCube(source_cube, normalize(cube_interp)); -#elif defined(SEP_CBCR_TEXTURE) + vec4 color = texture(source_cube, normalize(cube_interp)); +#elif defined(USE_SEP_CBCR_TEXTURE) vec4 color; color.r = texture(source, uv_interp).r; color.gb = texture(CbCr, uv_interp).rg - vec2(0.5, 0.5); @@ -166,7 +177,7 @@ void main() { vec4 color = texture(source, uv_interp); #endif -#ifdef YCBCR_TO_RGB +#ifdef USE_YCBCR_TO_RGB // YCbCr -> RGB conversion // Using BT.601, which is the standard for SDTV is provided as a reference diff --git a/drivers/gles3/shaders/cube_to_dp.glsl b/drivers/gles3/shaders/cube_to_dp.glsl index ea4df79d4e..2384529a89 100644 --- a/drivers/gles3/shaders/cube_to_dp.glsl +++ b/drivers/gles3/shaders/cube_to_dp.glsl @@ -10,9 +10,9 @@ precision mediump float; precision mediump int; #endif -layout(location = 0) highp vec4 vertex_attrib; +layout(location = 0) in highp vec4 vertex_attrib; /* clang-format on */ -layout(location = 4) vec2 uv_in; +layout(location = 4) in vec2 uv_in; out vec2 uv_interp; diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl index 04bf3ebf02..2081abfef6 100644 --- a/drivers/gles3/shaders/cubemap_filter.glsl +++ b/drivers/gles3/shaders/cubemap_filter.glsl @@ -10,9 +10,9 @@ precision highp float; precision highp int; #endif -layout(location = 0) highp vec2 vertex; +layout(location = 0) in highp vec2 vertex; /* clang-format on */ -layout(location = 4) highp vec2 uv; +layout(location = 4) in highp vec2 uv; out highp vec2 uv_interp; diff --git a/drivers/gles3/shaders/effect_blur.glsl b/drivers/gles3/shaders/effect_blur.glsl index 80063a7175..c9184cca77 100644 --- a/drivers/gles3/shaders/effect_blur.glsl +++ b/drivers/gles3/shaders/effect_blur.glsl @@ -10,9 +10,9 @@ precision highp float; precision highp int; #endif -layout(location = 0) vec2 vertex_attrib; +layout(location = 0) in vec2 vertex_attrib; /* clang-format on */ -layout(location = 4) vec2 uv_in; +layout(location = 4) in vec2 uv_in; out vec2 uv_interp; diff --git a/drivers/gles3/shaders/lens_distorted.glsl b/drivers/gles3/shaders/lens_distorted.glsl index 64c2d70cc8..3aaf1050e5 100644 --- a/drivers/gles3/shaders/lens_distorted.glsl +++ b/drivers/gles3/shaders/lens_distorted.glsl @@ -10,7 +10,7 @@ precision highp float; precision highp int; #endif -layout(location = 0) highp vec2 vertex; +layout(location = 0) in highp vec2 vertex; /* clang-format on */ uniform vec2 offset; diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index c2f3908395..98c92a1d99 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -18,38 +18,38 @@ precision highp int; // attributes // -layout(location = 0) highp vec4 vertex_attrib; +layout(location = 0) in highp vec4 vertex_attrib; /* clang-format on */ -layout(location = 1) vec3 normal_attrib; +layout(location = 1) in vec3 normal_attrib; #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) -layout(location = 2) vec4 tangent_attrib; +layout(location = 2) in vec4 tangent_attrib; #endif #if defined(ENABLE_COLOR_INTERP) -layout(location = 3) vec4 color_attrib; +layout(location = 3) in vec4 color_attrib; #endif #if defined(ENABLE_UV_INTERP) -layout(location = 4) vec2 uv_attrib; +layout(location = 4) in vec2 uv_attrib; #endif #if defined(ENABLE_UV2_INTERP) || defined(USE_LIGHTMAP) -layout(location = 5) vec2 uv2_attrib; +layout(location = 5) in vec2 uv2_attrib; #endif #ifdef USE_SKELETON #ifdef USE_SKELETON_SOFTWARE -layout(location = 13) highp vec4 bone_transform_row_0; -layout(location = 14) highp vec4 bone_transform_row_1; -layout(location = 15) highp vec4 bone_transform_row_2; +layout(location = 13) in highp vec4 bone_transform_row_0; +layout(location = 14) in highp vec4 bone_transform_row_1; +layout(location = 15) in highp vec4 bone_transform_row_2; #else -layout(location = 6) vec4 bone_ids; -layout(location = 7) highp vec4 bone_weights; +layout(location = 6) in vec4 bone_ids; +layout(location = 7) in highp vec4 bone_weights; uniform highp sampler2D bone_transforms; // texunit:-1 uniform ivec2 skeleton_texture_size; @@ -60,12 +60,12 @@ uniform ivec2 skeleton_texture_size; #ifdef USE_INSTANCING -layout(location = 8) highp vec4 instance_xform_row_0; -layout(location = 9) highp vec4 instance_xform_row_1; -layout(location = 10) highp vec4 instance_xform_row_2; +layout(location = 8) in highp vec4 instance_xform_row_0; +layout(location = 9) in highp vec4 instance_xform_row_1; +layout(location = 10) in highp vec4 instance_xform_row_2; -layout(location = 11) highp vec4 instance_color; -layout(location = 12) highp vec4 instance_custom_data; +layout(location = 11) in highp vec4 instance_color; +layout(location = 12) in highp vec4 instance_custom_data; #endif diff --git a/drivers/gles3/shaders/stdlib_inc.glsl b/drivers/gles3/shaders/stdlib_inc.glsl new file mode 100644 index 0000000000..2eddf9d479 --- /dev/null +++ b/drivers/gles3/shaders/stdlib_inc.glsl @@ -0,0 +1,58 @@ +//TODO: only needed by GLES_OVER_GL + +uint float2half(uint f) { + return ((f >> uint(16)) & uint(0x8000)) | + ((((f & uint(0x7f800000)) - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) | + ((f >> uint(13)) & uint(0x03ff)); +} + +uint half2float(uint h) { + return ((h & uint(0x8000)) << uint(16)) | (((h & uint(0x7c00)) + uint(0x1c000)) << uint(13)) | ((h & uint(0x03ff)) << uint(13)); +} + +uint packHalf2x16(vec2 v) { + return float2half(floatBitsToUint(v.x)) | float2half(floatBitsToUint(v.y)) << uint(16); +} + +vec2 unpackHalf2x16(uint v) { + return vec2(uintBitsToFloat(half2float(v & uint(0xffff))), + uintBitsToFloat(half2float(v >> uint(16)))); +} + +uint packUnorm2x16(vec2 v) { + uvec2 uv = uvec2(round(clamp(v, vec2(0.0), vec2(1.0)) * 65535.0)); + return uv.x | uv.y << uint(16); +} + +vec2 unpackUnorm2x16(uint p) { + return vec2(float(p & uint(0xffff)), float(p >> uint(16))) * 0.000015259021; // 1.0 / 65535.0 optimization +} + +uint packSnorm2x16(vec2 v) { + uvec2 uv = uvec2(round(clamp(v, vec2(-1.0), vec2(1.0)) * 32767.0) + 32767.0); + return uv.x | uv.y << uint(16); +} + +vec2 unpackSnorm2x16(uint p) { + vec2 v = vec2(float(p & uint(0xffff)), float(p >> uint(16))); + return clamp((v - 32767.0) * vec2(0.00003051851), vec2(-1.0), vec2(1.0)); +} + +uint packUnorm4x8(vec4 v) { + uvec4 uv = uvec4(round(clamp(v, vec4(0.0), vec4(1.0)) * 255.0)); + return uv.x | uv.y << uint(8) | uv.z << uint(16) | uv.w << uint(24); +} + +vec4 unpackUnorm4x8(uint p) { + return vec4(float(p & uint(0xffff)), float((p >> uint(8)) & uint(0xffff)), float((p >> uint(16)) & uint(0xffff)), float(p >> uint(24))) * 0.00392156862; // 1.0 / 255.0 +} + +uint packSnorm4x8(vec4 v) { + uvec4 uv = uvec4(round(clamp(v, vec4(-1.0), vec4(1.0)) * 127.0) + 127.0); + return uv.x | uv.y << uint(8) | uv.z << uint(16) | uv.w << uint(24); +} + +vec4 unpackSnorm4x8(uint p) { + vec4 v = vec4(float(p & uint(0xffff)), float((p >> uint(8)) & uint(0xffff)), float((p >> uint(16)) & uint(0xffff)), float(p >> uint(24))); + return clamp((v - vec4(127.0)) * vec4(0.00787401574), vec4(-1.0), vec4(1.0)); +} diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl index 8b3aa4d309..4f962626a3 100644 --- a/drivers/gles3/shaders/tonemap.glsl +++ b/drivers/gles3/shaders/tonemap.glsl @@ -10,9 +10,9 @@ precision highp float; precision highp int; #endif -layout(location = 0) vec2 vertex_attrib; +layout(location = 0) in vec2 vertex_attrib; /* clang-format on */ -layout(location = 4) vec2 uv_in; +layout(location = 4) in vec2 uv_in; out vec2 uv_interp; diff --git a/drivers/gles3/texture_loader_gles3.cpp b/drivers/gles3/texture_loader_gles3.cpp index f4ae6decab..ca52eaeacb 100644 --- a/drivers/gles3/texture_loader_gles3.cpp +++ b/drivers/gles3/texture_loader_gles3.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "texture_loader_gles3.h" -#ifdef GLES3_BACKEND_ENABLED +#ifdef GLES3_ENABLED #include "core/io/file_access.h" #include "core/string/print_string.h" diff --git a/drivers/gles3/texture_loader_gles3.h b/drivers/gles3/texture_loader_gles3.h index 68540fc5c0..54ddf80a96 100644 --- a/drivers/gles3/texture_loader_gles3.h +++ b/drivers/gles3/texture_loader_gles3.h @@ -31,8 +31,7 @@ #ifndef TEXTURE_LOADER_OPENGL_H #define TEXTURE_LOADER_OPENGL_H -#include "drivers/gles3/rasterizer_platforms.h" -#ifdef GLES3_BACKEND_ENABLED +#ifdef GLES3_ENABLED #include "core/io/resource_loader.h" #include "scene/resources/texture.h" @@ -47,6 +46,6 @@ public: virtual ~ResourceFormatGLES2Texture() {} }; -#endif // GLES3_BACKEND_ENABLED +#endif // GLES3_ENABLED #endif // TEXTURE_LOADER_OPENGL_H diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 708ea4b265..f6d2427b5c 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -8986,7 +8986,7 @@ void RenderingDeviceVulkan::_free_rids(T &p_owner, const char *p_type) { } void RenderingDeviceVulkan::capture_timestamp(const String &p_name) { - ERR_FAIL_COND_MSG(draw_list != nullptr, "Capturing timestamps during draw list creation is not allowed. Offending timestap was: " + p_name); + ERR_FAIL_COND_MSG(draw_list != nullptr, "Capturing timestamps during draw list creation is not allowed. Offending timestamp was: " + p_name); ERR_FAIL_COND(frames[frame].timestamp_count >= max_timestamp_query_elements); //this should be optional for profiling, else it will slow things down diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 408fddf4bf..f42929ffa4 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -175,7 +175,7 @@ class RenderingDeviceVulkan : public RenderingDevice { // These are temporary buffers on CPU memory that hold // the information until the CPU fetches it and places it // either on GPU buffers, or images (textures). It ensures - // updates are properly synchronized with whathever the + // updates are properly synchronized with whatever the // GPU is doing. // // The logic here is as follows, only 3 of these diff --git a/drivers/windows/dir_access_windows.h b/drivers/windows/dir_access_windows.h index ccd279e694..78d37074e5 100644 --- a/drivers/windows/dir_access_windows.h +++ b/drivers/windows/dir_access_windows.h @@ -35,10 +35,6 @@ #include "core/io/dir_access.h" -/** - @author Juan Linietsky <reduz@gmail.com> -*/ - struct DirAccessWindowsPrivate; class DirAccessWindows : public DirAccess { @@ -90,6 +86,6 @@ public: ~DirAccessWindows(); }; -#endif //WINDOWS_ENABLED +#endif // WINDOWS_ENABLED -#endif +#endif // DIR_ACCESS_WINDOWS_H diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp index eabe0a95e2..71c76f57cf 100644 --- a/editor/action_map_editor.cpp +++ b/editor/action_map_editor.cpp @@ -742,7 +742,7 @@ void ActionMapEditor::_event_config_confirmed() { Ref<InputEvent> ev = event_config_dialog->get_event(); Dictionary new_action = current_action.duplicate(); - Array events = new_action["events"]; + Array events = new_action["events"].duplicate(); if (current_action_event_index == -1) { // Add new event @@ -760,12 +760,26 @@ void ActionMapEditor::_add_action_pressed() { _add_action(add_edit->get_text()); } +bool ActionMapEditor::_has_action(const String &p_name) const { + for (const ActionInfo &action_info : actions_cache) { + if (p_name == action_info.name) { + return true; + } + } + return false; +} + void ActionMapEditor::_add_action(const String &p_name) { if (p_name.is_empty() || !_is_action_name_valid(p_name)) { show_message(TTR("Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or '\"'")); return; } + if (_has_action(p_name)) { + show_message(vformat(TTR("An action with the name '%s' already exists."), p_name)); + return; + } + add_edit->clear(); emit_signal(SNAME("action_added"), p_name); } @@ -791,6 +805,12 @@ void ActionMapEditor::_action_edited() { return; } + if (_has_action(new_name)) { + ti->set_text(0, old_name); + show_message(vformat(TTR("An action with the name '%s' already exists."), new_name)); + return; + } + emit_signal(SNAME("action_renamed"), old_name, new_name); } else if (action_tree->get_selected_column() == 1) { // Deadzone Edited @@ -819,7 +839,6 @@ void ActionMapEditor::_tree_button_pressed(Object *p_item, int p_column, int p_i current_action_event_index = -1; event_config_dialog->popup_and_configure(); - } break; case ActionMapEditor::BUTTON_EDIT_EVENT: { // Action and Action name is located on the parent of the event. @@ -832,7 +851,6 @@ void ActionMapEditor::_tree_button_pressed(Object *p_item, int p_column, int p_i if (ie.is_valid()) { event_config_dialog->popup_and_configure(ie); } - } break; case ActionMapEditor::BUTTON_REMOVE_ACTION: { // Send removed action name @@ -841,12 +859,12 @@ void ActionMapEditor::_tree_button_pressed(Object *p_item, int p_column, int p_i } break; case ActionMapEditor::BUTTON_REMOVE_EVENT: { // Remove event and send updated action - Dictionary action = item->get_parent()->get_meta("__action"); + Dictionary action = item->get_parent()->get_meta("__action").duplicate(); String action_name = item->get_parent()->get_meta("__name"); int event_index = item->get_meta("__index"); - Array events = action["events"]; + Array events = action["events"].duplicate(); events.remove_at(event_index); action["events"] = events; diff --git a/editor/action_map_editor.h b/editor/action_map_editor.h index cf2d871469..e61d1a334a 100644 --- a/editor/action_map_editor.h +++ b/editor/action_map_editor.h @@ -168,6 +168,7 @@ private: void _event_config_confirmed(); void _add_action_pressed(); + bool _has_action(const String &p_name) const; void _add_action(const String &p_name); void _action_edited(); diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 1085d34c4e..3678642521 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -32,6 +32,7 @@ #include "editor/editor_node.h" #include "editor_scale.h" +#include "scene/gui/view_panner.h" #include "scene/resources/text_line.h" float AnimationBezierTrackEdit::_bezier_h_to_pixel(float p_h) { @@ -216,6 +217,9 @@ void AnimationBezierTrackEdit::_draw_line_clipped(const Vector2 &p_from, const V } void AnimationBezierTrackEdit::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { + panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/animation_editors_panning_scheme").operator int()); + } if (p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_ENTER_TREE) { close_button->set_icon(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); @@ -610,6 +614,11 @@ void AnimationBezierTrackEdit::_select_at_anim(const Ref<Animation> &p_anim, int void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); + if (panner->gui_input(p_event)) { + accept_event(); + return; + } + if (p_event->is_pressed()) { if (ED_GET_SHORTCUT("animation_editor/duplicate_selection")->matches_event(p_event)) { duplicate_selection(); @@ -623,40 +632,24 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { } Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN) { - const float v_zoom_orig = v_zoom; - if (mb->is_command_pressed()) { - timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() / 1.05); - } else { + if (mb.is_valid() && mb->is_pressed() && mb->is_alt_pressed()) { + // Alternate zoom (doesn't affect timeline). + if (mb->get_button_index() == MouseButton::WHEEL_DOWN) { + const float v_zoom_orig = v_zoom; if (v_zoom < 100000) { v_zoom *= 1.2; } + v_scroll = v_scroll + (mb->get_position().y - get_size().y / 2) * (v_zoom - v_zoom_orig); + update(); } - v_scroll = v_scroll + (mb->get_position().y - get_size().y / 2) * (v_zoom - v_zoom_orig); - update(); - } - if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) { - const float v_zoom_orig = v_zoom; - if (mb->is_command_pressed()) { - timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() * 1.05); - } else { + if (mb->get_button_index() == MouseButton::WHEEL_UP) { + const float v_zoom_orig = v_zoom; if (v_zoom > 0.000001) { v_zoom /= 1.2; } - } - v_scroll = v_scroll + (mb->get_position().y - get_size().y / 2) * (v_zoom - v_zoom_orig); - update(); - } - - if (mb.is_valid() && mb->get_button_index() == MouseButton::MIDDLE) { - if (mb->is_pressed()) { - int x = mb->get_position().x - timeline->get_name_limit(); - panning_timeline_from = x / timeline->get_zoom_scale(); - panning_timeline = true; - panning_timeline_at = timeline->get_value(); - } else { - panning_timeline = false; + v_scroll = v_scroll + (mb->get_position().y - get_size().y / 2) * (v_zoom - v_zoom_orig); + update(); } } @@ -934,22 +927,6 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { } Ref<InputEventMouseMotion> mm = p_event; - if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_MIDDLE) != MouseButton::NONE) { - v_scroll += mm->get_relative().y * v_zoom; - if (v_scroll > 100000) { - v_scroll = 100000; - } - if (v_scroll < -100000) { - v_scroll = -100000; - } - - int x = mm->get_position().x - timeline->get_name_limit(); - float ofs = x / timeline->get_zoom_scale(); - float diff = ofs - panning_timeline_from; - timeline->set_value(panning_timeline_at - diff); - - update(); - } if (moving_selection_attempt && mm.is_valid()) { if (!moving_selection) { moving_selection = true; @@ -1038,6 +1015,28 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { } } +void AnimationBezierTrackEdit::_scroll_callback(Vector2 p_scroll_vec) { + _pan_callback(-p_scroll_vec * 32); +} + +void AnimationBezierTrackEdit::_pan_callback(Vector2 p_scroll_vec) { + v_scroll += p_scroll_vec.y * v_zoom; + v_scroll = CLAMP(v_scroll, -100000, 100000); + timeline->set_value(timeline->get_value() - p_scroll_vec.x / timeline->get_zoom_scale()); + update(); +} + +void AnimationBezierTrackEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) { + const float v_zoom_orig = v_zoom; + if (p_scroll_vec.y > 0) { + timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() / 1.05); + } else { + timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() * 1.05); + } + v_scroll = v_scroll + (p_origin.y - get_size().y / 2) * (v_zoom - v_zoom_orig); + update(); +} + void AnimationBezierTrackEdit::_menu_selected(int p_index) { switch (p_index) { case MENU_KEY_INSERT: { @@ -1171,6 +1170,11 @@ void AnimationBezierTrackEdit::_bind_methods() { } AnimationBezierTrackEdit::AnimationBezierTrackEdit() { + panner.instantiate(); + panner->set_callbacks(callable_mp(this, &AnimationBezierTrackEdit::_scroll_callback), callable_mp(this, &AnimationBezierTrackEdit::_pan_callback), callable_mp(this, &AnimationBezierTrackEdit::_zoom_callback)); + panner->set_disable_rmb(true); + panner->set_control_scheme(ViewPanner::SCROLL_PANS); + play_position = memnew(Control); play_position->set_mouse_filter(MOUSE_FILTER_PASS); add_child(play_position); diff --git a/editor/animation_bezier_editor.h b/editor/animation_bezier_editor.h index d9bc85a258..6a5b97a7da 100644 --- a/editor/animation_bezier_editor.h +++ b/editor/animation_bezier_editor.h @@ -33,6 +33,8 @@ #include "animation_track_editor.h" +class ViewPanner; + class AnimationBezierTrackEdit : public Control { GDCLASS(AnimationBezierTrackEdit, Control); @@ -123,9 +125,10 @@ class AnimationBezierTrackEdit : public Control { Set<int> selection; - bool panning_timeline = false; - float panning_timeline_from; - float panning_timeline_at; + Ref<ViewPanner> panner; + void _scroll_callback(Vector2 p_scroll_vec); + void _pan_callback(Vector2 p_scroll_vec); + void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin); void _draw_line_clipped(const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, int p_clip_left, int p_clip_right); void _draw_track(int p_track, const Color &p_color); diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index f4e719f552..13e9d58744 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -32,12 +32,12 @@ #include "animation_track_editor_plugins.h" #include "core/input/input.h" -#include "core/os/keyboard.h" #include "editor/animation_bezier_editor.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "editor_node.h" #include "editor_scale.h" #include "scene/animation/animation_player.h" +#include "scene/gui/view_panner.h" #include "scene/main/window.h" #include "scene/scene_string_names.h" #include "servers/audio/audio_stream.h" @@ -1458,6 +1458,10 @@ int AnimationTimelineEdit::get_name_limit() const { } void AnimationTimelineEdit::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { + panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/animation_editors_panning_scheme").operator int()); + } + if (p_what == NOTIFICATION_ENTER_TREE) { add_track->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); loop->set_icon(get_theme_icon(SNAME("Loop"), SNAME("EditorIcons"))); @@ -1760,17 +1764,12 @@ void AnimationTimelineEdit::_play_position_draw() { void AnimationTimelineEdit::gui_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); - const Ref<InputEventMouseButton> mb = p_event; - - if (mb.is_valid() && mb->is_pressed() && mb->is_command_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) { - get_zoom()->set_value(get_zoom()->get_value() * 1.05); + if (panner->gui_input(p_event)) { accept_event(); + return; } - if (mb.is_valid() && mb->is_pressed() && mb->is_command_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN) { - get_zoom()->set_value(get_zoom()->get_value() / 1.05); - accept_event(); - } + const Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid() && mb->is_pressed() && mb->is_alt_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) { if (track_edit) { @@ -1796,29 +1795,19 @@ void AnimationTimelineEdit::gui_input(const Ref<InputEvent> &p_event) { dragging_hsize = false; } if (mb.is_valid() && mb->get_position().x > get_name_limit() && mb->get_position().x < (get_size().width - get_buttons_width())) { - if (!panning_timeline && mb->get_button_index() == MouseButton::LEFT) { + if (!panner->is_panning() && mb->get_button_index() == MouseButton::LEFT) { int x = mb->get_position().x - get_name_limit(); float ofs = x / get_zoom_scale() + get_value(); emit_signal(SNAME("timeline_changed"), ofs, false, Input::get_singleton()->is_key_pressed(Key::ALT)); dragging_timeline = true; } - if (!dragging_timeline && mb->get_button_index() == MouseButton::MIDDLE) { - int x = mb->get_position().x - get_name_limit(); - panning_timeline_from = x / get_zoom_scale(); - panning_timeline = true; - panning_timeline_at = get_value(); - } } if (dragging_timeline && mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed()) { dragging_timeline = false; } - if (panning_timeline && mb.is_valid() && mb->get_button_index() == MouseButton::MIDDLE && !mb->is_pressed()) { - panning_timeline = false; - } - Ref<InputEventMouseMotion> mm = p_event; if (mm.is_valid()) { @@ -1839,17 +1828,29 @@ void AnimationTimelineEdit::gui_input(const Ref<InputEvent> &p_event) { if (dragging_timeline) { int x = mm->get_position().x - get_name_limit(); float ofs = x / get_zoom_scale() + get_value(); - emit_signal(SNAME("timeline_changed"), ofs, false, Input::get_singleton()->is_key_pressed(Key::ALT)); - } - if (panning_timeline) { - int x = mm->get_position().x - get_name_limit(); - float ofs = x / get_zoom_scale(); - float diff = ofs - panning_timeline_from; - set_value(panning_timeline_at - diff); + emit_signal(SNAME("timeline_changed"), ofs, false, mm->is_alt_pressed()); } } } +void AnimationTimelineEdit::_scroll_callback(Vector2 p_scroll_vec) { + // Timeline has no vertical scroll, so we change it to horizontal. + p_scroll_vec.x += p_scroll_vec.y; + _pan_callback(-p_scroll_vec * 32); +} + +void AnimationTimelineEdit::_pan_callback(Vector2 p_scroll_vec) { + set_value(get_value() - p_scroll_vec.x / get_zoom_scale()); +} + +void AnimationTimelineEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) { + if (p_scroll_vec.y < 0) { + get_zoom()->set_value(get_zoom()->get_value() * 1.05); + } else { + get_zoom()->set_value(get_zoom()->get_value() / 1.05); + } +} + void AnimationTimelineEdit::set_use_fps(bool p_use_fps) { use_fps = p_use_fps; update_values(); @@ -1926,10 +1927,14 @@ AnimationTimelineEdit::AnimationTimelineEdit() { add_track->get_popup()->connect("index_pressed", callable_mp(this, &AnimationTimelineEdit::_track_added)); len_hb->hide(); - panning_timeline = false; dragging_timeline = false; dragging_hsize = false; + panner.instantiate(); + panner->set_callbacks(callable_mp(this, &AnimationTimelineEdit::_scroll_callback), callable_mp(this, &AnimationTimelineEdit::_pan_callback), callable_mp(this, &AnimationTimelineEdit::_zoom_callback)); + panner->set_disable_rmb(true); + panner->set_control_scheme(ViewPanner::SCROLL_PANS); + set_layout_direction(Control::LAYOUT_DIRECTION_LTR); } @@ -4500,6 +4505,10 @@ MenuButton *AnimationTrackEditor::get_edit_menu() { } void AnimationTrackEditor::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { + panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/animation_editors_panning_scheme").operator int()); + } + if (p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_ENTER_TREE) { zoom_icon->set_texture(get_theme_icon(SNAME("Zoom"), SNAME("EditorIcons"))); snap->set_icon(get_theme_icon(SNAME("Snap"), SNAME("EditorIcons"))); @@ -5212,17 +5221,12 @@ void AnimationTrackEditor::_box_selection_draw() { } void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) { - Ref<InputEventMouseButton> mb = p_event; - - if (mb.is_valid() && mb->is_pressed() && mb->is_command_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) { - timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() * 1.05); + if (panner->gui_input(p_event)) { scroll->accept_event(); + return; } - if (mb.is_valid() && mb->is_pressed() && mb->is_command_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN) { - timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() / 1.05); - scroll->accept_event(); - } + Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid() && mb->is_pressed() && mb->is_alt_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) { goto_prev_step(true); @@ -5262,10 +5266,6 @@ void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> mm = p_event; - if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_MIDDLE) != MouseButton::NONE) { - timeline->set_value(timeline->get_value() - mm->get_relative().x / timeline->get_zoom_scale()); - } - if (mm.is_valid() && box_selecting) { if ((mm->get_button_mask() & MouseButton::MASK_LEFT) == MouseButton::NONE) { // No longer. @@ -5302,6 +5302,23 @@ void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) { } } +void AnimationTrackEditor::_scroll_callback(Vector2 p_scroll_vec) { + _pan_callback(-p_scroll_vec * 32); +} + +void AnimationTrackEditor::_pan_callback(Vector2 p_scroll_vec) { + timeline->set_value(timeline->get_value() - p_scroll_vec.x / timeline->get_zoom_scale()); + scroll->set_v_scroll(scroll->get_v_scroll() - p_scroll_vec.y); +} + +void AnimationTrackEditor::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) { + if (p_scroll_vec.y < 0) { + timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() * 1.05); + } else { + timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() / 1.05); + } +} + void AnimationTrackEditor::_cancel_bezier_edit() { bezier_edit->hide(); scroll->show(); @@ -6088,6 +6105,11 @@ AnimationTrackEditor::AnimationTrackEditor() { timeline->connect("value_changed", callable_mp(this, &AnimationTrackEditor::_timeline_value_changed)); timeline->connect("length_changed", callable_mp(this, &AnimationTrackEditor::_update_length)); + panner.instantiate(); + panner->set_callbacks(callable_mp(this, &AnimationTrackEditor::_scroll_callback), callable_mp(this, &AnimationTrackEditor::_pan_callback), callable_mp(this, &AnimationTrackEditor::_zoom_callback)); + panner->set_disable_rmb(true); + panner->set_control_scheme(ViewPanner::SCROLL_PANS); + scroll = memnew(ScrollContainer); timeline_vbox->add_child(scroll); scroll->set_v_size_flags(SIZE_EXPAND_FILL); diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index b5d44bc0d3..2a2b20ada9 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -48,8 +48,8 @@ #include "scene_tree_editor.h" class AnimationPlayer; - class AnimationTrackEdit; +class ViewPanner; class AnimationTimelineEdit : public Range { GDCLASS(AnimationTimelineEdit, Range); @@ -81,9 +81,11 @@ class AnimationTimelineEdit : public Range { bool editing; bool use_fps; - bool panning_timeline; - float panning_timeline_from; - float panning_timeline_at; + Ref<ViewPanner> panner; + void _scroll_callback(Vector2 p_scroll_vec); + void _pan_callback(Vector2 p_scroll_vec); + void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin); + bool dragging_timeline; bool dragging_hsize; float dragging_hsize_from; @@ -374,6 +376,11 @@ class AnimationTrackEditor : public VBoxContainer { PropertyInfo _find_hint_for_track(int p_idx, NodePath &r_base_path, Variant *r_current_val = nullptr); + Ref<ViewPanner> panner; + void _scroll_callback(Vector2 p_scroll_vec); + void _pan_callback(Vector2 p_scroll_vec); + void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin); + void _timeline_value_changed(double); float insert_key_from_track_call_ofs; diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp index a6d2225bdc..058e59dea3 100644 --- a/editor/animation_track_editor_plugins.cpp +++ b/editor/animation_track_editor_plugins.cpp @@ -145,20 +145,19 @@ void AnimationTrackEditColor::draw_key_link(int p_index, float p_pixels_sec, int } for (int i = 0; i < color_samples.size() - 1; i++) { - Vector<Vector2> points; - Vector<Color> colors; - - points.push_back(Vector2(Math::lerp(x_from, x_to, float(i) / (color_samples.size() - 1)), y_from)); - colors.push_back(color_samples[i]); - - points.push_back(Vector2(Math::lerp(x_from, x_to, float(i + 1) / (color_samples.size() - 1)), y_from)); - colors.push_back(color_samples[i + 1]); - - points.push_back(Vector2(Math::lerp(x_from, x_to, float(i + 1) / (color_samples.size() - 1)), y_from + fh)); - colors.push_back(color_samples[i + 1]); - - points.push_back(Vector2(Math::lerp(x_from, x_to, float(i) / (color_samples.size() - 1)), y_from + fh)); - colors.push_back(color_samples[i]); + Vector<Vector2> points = { + Vector2(Math::lerp(x_from, x_to, float(i) / (color_samples.size() - 1)), y_from), + Vector2(Math::lerp(x_from, x_to, float(i + 1) / (color_samples.size() - 1)), y_from), + Vector2(Math::lerp(x_from, x_to, float(i + 1) / (color_samples.size() - 1)), y_from + fh), + Vector2(Math::lerp(x_from, x_to, float(i) / (color_samples.size() - 1)), y_from + fh) + }; + + Vector<Color> colors = { + color_samples[i], + color_samples[i + 1], + color_samples[i + 1], + color_samples[i] + }; draw_primitive(points, colors, Vector<Vector2>()); } diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h index 2759c6cfde..8bad2d9b5b 100644 --- a/editor/connections_dialog.h +++ b/editor/connections_dialog.h @@ -28,10 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -/** -@author Juan Linietsky <reduzio@gmail.com> -*/ - #ifndef CONNECTIONS_DIALOG_H #define CONNECTIONS_DIALOG_H @@ -232,4 +228,4 @@ public: ~ConnectionsDock(); }; -#endif +#endif // CONNECTIONS_DIALOG_H diff --git a/editor/debugger/editor_debugger_inspector.cpp b/editor/debugger/editor_debugger_inspector.cpp index addb168e5f..38bdbe2870 100644 --- a/editor/debugger/editor_debugger_inspector.cpp +++ b/editor/debugger/editor_debugger_inspector.cpp @@ -262,13 +262,26 @@ void EditorDebuggerInspector::add_stack_variable(const Array &p_array) { variables->prop_values[type + n] = v; variables->update(); edit(variables); + + // To prevent constantly resizing when using filtering. + int size_x = get_size().x; + if (size_x > get_custom_minimum_size().x) { + set_custom_minimum_size(Size2(size_x, 0)); + } } void EditorDebuggerInspector::clear_stack_variables() { variables->clear(); variables->update(); + set_custom_minimum_size(Size2(0, 0)); } String EditorDebuggerInspector::get_stack_variable(const String &p_var) { - return variables->get_variant(p_var); + for (Map<StringName, Variant>::Element *E = variables->prop_values.front(); E; E = E->next()) { + String v = E->key().operator String(); + if (v.get_slice("/", 1) == p_var) { + return variables->get_variant(v); + } + } + return String(); } diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index b72a20ee2f..df9f02023a 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -790,6 +790,7 @@ void ScriptEditorDebugger::_notification(int p_what) { error_tree->connect("item_activated", callable_mp(this, &ScriptEditorDebugger::_error_activated)); vmem_refresh->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); vmem_export->set_icon(get_theme_icon(SNAME("Save"), SNAME("EditorIcons"))); + search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); reason->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); @@ -864,6 +865,7 @@ void ScriptEditorDebugger::_notification(int p_what) { docontinue->set_icon(get_theme_icon(SNAME("DebugContinue"), SNAME("EditorIcons"))); vmem_refresh->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); vmem_export->set_icon(get_theme_icon(SNAME("Save"), SNAME("EditorIcons"))); + search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); } break; } } @@ -1658,14 +1660,29 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { stack_dump->connect("cell_selected", callable_mp(this, &ScriptEditorDebugger::_stack_dump_frame_selected)); sc->add_child(stack_dump); + VBoxContainer *inspector_vbox = memnew(VBoxContainer); + sc->add_child(inspector_vbox); + + HBoxContainer *tools_hb = memnew(HBoxContainer); + inspector_vbox->add_child(tools_hb); + + search = memnew(LineEdit); + search->set_h_size_flags(Control::SIZE_EXPAND_FILL); + search->set_placeholder(TTR("Filter stack variables")); + search->set_clear_button_enabled(true); + tools_hb->add_child(search); + inspector = memnew(EditorDebuggerInspector); inspector->set_h_size_flags(SIZE_EXPAND_FILL); + inspector->set_v_size_flags(SIZE_EXPAND_FILL); inspector->set_enable_capitalize_paths(false); inspector->set_read_only(true); inspector->connect("object_selected", callable_mp(this, &ScriptEditorDebugger::_remote_object_selected)); inspector->connect("object_edited", callable_mp(this, &ScriptEditorDebugger::_remote_object_edited)); inspector->connect("object_property_updated", callable_mp(this, &ScriptEditorDebugger::_remote_object_property_updated)); - sc->add_child(inspector); + inspector->register_text_enter(search); + inspector->set_use_filter(true); + inspector_vbox->add_child(inspector); tabs->add_child(dbg); } diff --git a/editor/debugger/script_editor_debugger.h b/editor/debugger/script_editor_debugger.h index ff1a852f26..ceb30e4565 100644 --- a/editor/debugger/script_editor_debugger.h +++ b/editor/debugger/script_editor_debugger.h @@ -134,6 +134,7 @@ private: LineEdit *vmem_total; Tree *stack_dump; + LineEdit *search = nullptr; EditorDebuggerInspector *inspector; SceneDebuggerTree *scene_tree; diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 0829b9d24f..8e4bbbb99b 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -324,7 +324,7 @@ float EditorAudioBus::_normalized_volume_to_scaled_db(float normalized) { /* There are three different formulas for the conversion from normalized * values to relative decibal values. * One formula is an exponential graph which intends to counteract - * the logorithmic nature of human hearing. This is an approximation + * the logarithmic nature of human hearing. This is an approximation * of the behaviour of a 'logarithmic potentiometer' found on most * musical instruments and also emulated in popular software. * The other two equations are hand-tuned linear tapers that intend to diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index a0673c8fb7..703f606c76 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -1644,7 +1644,7 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector config->get_section_keys("params", &sk); for (const String ¶m : sk) { Variant value = config->get_value("params", param); - //override with whathever is in file + //override with whatever is in file source_file_options[p_files[i]][param] = value; } } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index afd5407f37..9b4b99b32d 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -2780,8 +2780,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } } } break; - case RUN_PROJECT_DATA_FOLDER: { - // ensure_user_data_dir() to prevent the edge case: "Open Project Data Folder" won't work after the project was renamed in ProjectSettingsEditor unless the project is saved + case RUN_USER_DATA_FOLDER: { + // ensure_user_data_dir() to prevent the edge case: "Open User Data Folder" won't work after the project was renamed in ProjectSettingsEditor unless the project is saved OS::get_singleton()->ensure_user_data_dir(); OS::get_singleton()->shell_open(String("file://") + OS::get_singleton()->get_user_data_dir()); } break; @@ -6038,6 +6038,11 @@ EditorNode::EditorNode() { EDITOR_DEF("interface/inspector/default_color_picker_shape", (int32_t)ColorPicker::SHAPE_VHS_CIRCLE); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_shape", PROPERTY_HINT_ENUM, "HSV Rectangle,HSV Rectangle Wheel,VHS Circle", PROPERTY_USAGE_DEFAULT)); EDITOR_DEF("run/auto_save/save_before_running", true); + EDITOR_DEF("interface/editors/sub_editor_panning_scheme", 0); + EDITOR_DEF("interface/editors/animation_editors_panning_scheme", 1); + // Should be in sync with ControlScheme in ViewPanner. + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/editors/sub_editor_panning_scheme", PROPERTY_HINT_ENUM, "Scroll Zooms,Scroll Pans", PROPERTY_USAGE_DEFAULT)); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/editors/animation_editors_panning_scheme", PROPERTY_HINT_ENUM, "Scroll Zooms,Scroll Pans", PROPERTY_USAGE_DEFAULT)); const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); for (const String &E : textfile_ext) { @@ -6443,7 +6448,7 @@ EditorNode::EditorNode() { p->add_separator(); p->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/export", TTR("Export..."), Key::NONE, TTR("Export")), FILE_EXPORT_PROJECT); p->add_item(TTR("Install Android Build Template..."), FILE_INSTALL_ANDROID_SOURCE); - p->add_item(TTR("Open Project Data Folder"), RUN_PROJECT_DATA_FOLDER); + p->add_item(TTR("Open User Data Folder"), RUN_USER_DATA_FOLDER); plugin_config_dialog = memnew(PluginConfigDialog); plugin_config_dialog->connect("plugin_ready", callable_mp(this, &EditorNode::_on_plugin_ready)); diff --git a/editor/editor_node.h b/editor/editor_node.h index 7ecdb7c263..af7223ffb4 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -167,7 +167,7 @@ private: RUN_PLAY_SCENE, RUN_PLAY_CUSTOM_SCENE, RUN_SETTINGS, - RUN_PROJECT_DATA_FOLDER, + RUN_USER_DATA_FOLDER, RUN_RELOAD_CURRENT_PROJECT, RUN_PROJECT_MANAGER, RUN_VCS_METADATA, diff --git a/editor/editor_paths.cpp b/editor/editor_paths.cpp index a4481cd1eb..d4e40db406 100644 --- a/editor/editor_paths.cpp +++ b/editor/editor_paths.cpp @@ -91,6 +91,11 @@ EditorPaths::EditorPaths() { // Self-contained mode if a `._sc_` or `_sc_` file is present in executable dir. String exe_path = OS::get_singleton()->get_executable_path().get_base_dir(); + + // On macOS, look outside .app bundle, since .app bundle is read-only. + if (OS::get_singleton()->has_feature("macos") && exe_path.ends_with("MacOS") && exe_path.plus_file("..").simplify_path().ends_with("Contents")) { + exe_path = exe_path.plus_file("../../..").simplify_path(); + } { DirAccessRef d = DirAccess::create_for_path(exe_path); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index a8a1dc37ab..5b7ea65b04 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -30,7 +30,9 @@ #include "editor_themes.h" +#include "core/error/error_macros.h" #include "core/io/resource_loader.h" +#include "core/variant/dictionary.h" #include "editor_fonts.h" #include "editor_icons.gen.h" #include "editor_scale.h" @@ -95,6 +97,7 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false, Ref<ImageTexture> texture(memnew(ImageTexture)); Ref<Image> img = p_texture->get_image(); + ERR_FAIL_NULL_V(img, Ref<Texture2D>()); img = img->duplicate(); if (p_flip_y) { @@ -109,7 +112,7 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false, } #ifdef MODULE_SVG_ENABLED -static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float p_scale = EDSCALE, float p_saturation = 1.0) { +static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float p_scale = EDSCALE, float p_saturation = 1.0, Dictionary p_convert_colors = Dictionary()) { Ref<ImageTexture> icon = memnew(ImageTexture); Ref<Image> img = memnew(Image); @@ -117,8 +120,9 @@ static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, // Generating upsampled icons is slower, and the benefit is hardly visible // with integer editor scales. const bool upsample = !Math::is_equal_approx(Math::round(p_scale), p_scale); - ImageLoaderSVG::create_image_from_string(img, editor_icons_sources[p_index], p_scale, upsample, p_convert_color); - + ImageLoaderSVG img_loader; + img_loader.set_replace_colors(p_convert_colors); + img_loader.create_image_from_string(img, editor_icons_sources[p_index], p_scale, upsample, p_convert_color); if (p_saturation != 1.0) { img->adjust_bcs(1.0, 1.0, p_saturation); } @@ -135,8 +139,10 @@ static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = true, int p_thumb_size = 32, bool p_only_thumbs = false, float p_icon_saturation = 1.0) { #ifdef MODULE_SVG_ENABLED // The default icon theme is designed to be used for a dark theme. - // This dictionary stores color codes to convert to other colors + // This dictionary stores Color values to convert to other colors // for better readability on a light theme. + // Godot Color values are used to avoid the ambiguity of strings + // (where "#ffffff", "fff", and "white" are all equivalent). Dictionary dark_icon_color_dictionary; // The names of the icons to never convert, even if one of their colors @@ -243,8 +249,6 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = dark_icon_color_dictionary[Color::html("#45ff8b")] = success_color; dark_icon_color_dictionary[Color::html("#dbab09")] = warning_color; - ImageLoaderSVG::set_convert_colors(&dark_icon_color_dictionary); - // Generate icons. if (!p_only_thumbs) { for (int i = 0; i < editor_icons_count; i++) { @@ -255,7 +259,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = } const int is_exception = exceptions.has(editor_icons_names[i]); - const Ref<ImageTexture> icon = editor_generate_icon(i, !is_exception, EDSCALE, saturation); + const Ref<ImageTexture> icon = editor_generate_icon(i, !is_exception, EDSCALE, saturation, dark_icon_color_dictionary); p_theme->set_icon(editor_icons_names[i], "EditorIcons", icon); } @@ -269,7 +273,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = for (int i = 0; i < editor_bg_thumbs_count; i++) { const int index = editor_bg_thumbs_indices[i]; const int is_exception = exceptions.has(editor_icons_names[index]); - const Ref<ImageTexture> icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter); + const Ref<ImageTexture> icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter, dark_icon_color_dictionary); p_theme->set_icon(editor_icons_names[index], "EditorIcons", icon); } @@ -278,13 +282,11 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = for (int i = 0; i < editor_md_thumbs_count; i++) { const int index = editor_md_thumbs_indices[i]; const bool is_exception = exceptions.has(editor_icons_names[index]); - const Ref<ImageTexture> icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter); + const Ref<ImageTexture> icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter, dark_icon_color_dictionary); p_theme->set_icon(editor_icons_names[index], "EditorIcons", icon); } } - - ImageLoaderSVG::set_convert_colors(nullptr); #else WARN_PRINT("SVG support disabled, editor icons won't be rendered."); #endif diff --git a/editor/icons/SnapGrid.svg b/editor/icons/SnapGrid.svg index e3aea78162..6960d4d13d 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="m3 0v3h-3v2h3v4h-3v2h3v3h2v-9h9v-2h-3v-3h-2v3h-4v-3zm4 13v2h2v-2zm6 0v2h2v-2z" fill="#e0e0e0"/><path d="m11 7a4 4 0 0 0 -4 4v2h2v-2a2 2 0 0 1 2-2 2 2 0 0 1 2 2v2h2v-2a4 4 0 0 0 -4-4z" fill="#fff" fill-opacity=".68627"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 0v2h-2v1h2v4h-2v1h2v4h-2v1h2v2h1v-2h3v-1h-3v-4h4l1-1v-4h4v3h1v-3h2v-1h-2v-2h-1v2h-4v-2h-1v2h-4v-2zm1 3h4v4h-4zm4 10v2h2v-2zm6 0v2h2v-2z" fill="#e0e0e0"/><path d="m11 7a4 4 0 0 0 -4 4v2h2v-2a2 2 0 0 1 2-2 2 2 0 0 1 2 2v2h2v-2a4 4 0 0 0 -4-4z" fill="#fff" fill-opacity=".68627"/></svg> diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index 22b2bd1ed4..c1ae5be0bb 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -471,7 +471,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p bool local_xform_mirror = p_local_xform.basis.determinant() < 0; if (p_morph_data) { - //add morphie target + //add morph target ERR_FAIL_COND_V(!p_morph_data->targets.has("MORPH_TARGET"), ERR_INVALID_DATA); String mt = p_morph_data->targets["MORPH_TARGET"]; ERR_FAIL_COND_V(!p_morph_data->sources.has(mt), ERR_INVALID_DATA); diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index ccb287e433..f56e868286 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -406,6 +406,7 @@ Container *InspectorDock::get_addon_area() { void InspectorDock::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_ENTER_TREE: case NOTIFICATION_TRANSLATION_CHANGED: case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { @@ -415,6 +416,7 @@ void InspectorDock::_notification(int p_what) { resource_load_button->set_icon(get_theme_icon(SNAME("Load"), SNAME("EditorIcons"))); resource_save_button->set_icon(get_theme_icon(SNAME("Save"), SNAME("EditorIcons"))); resource_extra_button->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); + open_docs_button->set_icon(get_theme_icon(SNAME("HelpSearch"), SNAME("EditorIcons"))); PopupMenu *resource_extra_popup = resource_extra_button->get_popup(); resource_extra_popup->set_item_icon(resource_extra_popup->get_item_index(RESOURCE_EDIT_CLIPBOARD), get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons"))); @@ -430,6 +432,7 @@ void InspectorDock::_notification(int p_what) { history_menu->set_icon(get_theme_icon(SNAME("History"), SNAME("EditorIcons"))); object_menu->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons"))); + search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); warning->set_icon(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons"))); warning->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor"))); } break; @@ -562,7 +565,6 @@ void InspectorDock::update_keying() { InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) { set_name("Inspector"); - set_theme(p_editor->get_gui_base()->get_theme()); editor = p_editor; editor_data = &p_editor_data; @@ -573,7 +575,6 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) { resource_new_button = memnew(Button); resource_new_button->set_flat(true); resource_new_button->set_tooltip(TTR("Create a new resource in memory and edit it.")); - resource_new_button->set_icon(get_theme_icon(SNAME("New"), SNAME("EditorIcons"))); general_options_hb->add_child(resource_new_button); resource_new_button->connect("pressed", callable_mp(this, &InspectorDock::_new_resource)); resource_new_button->set_focus_mode(Control::FOCUS_NONE); @@ -581,14 +582,12 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) { resource_load_button = memnew(Button); resource_load_button->set_flat(true); resource_load_button->set_tooltip(TTR("Load an existing resource from disk and edit it.")); - resource_load_button->set_icon(get_theme_icon(SNAME("Load"), SNAME("EditorIcons"))); general_options_hb->add_child(resource_load_button); resource_load_button->connect("pressed", callable_mp(this, &InspectorDock::_open_resource_selector)); resource_load_button->set_focus_mode(Control::FOCUS_NONE); resource_save_button = memnew(MenuButton); resource_save_button->set_tooltip(TTR("Save the currently edited resource.")); - resource_save_button->set_icon(get_theme_icon(SNAME("Save"), SNAME("EditorIcons"))); general_options_hb->add_child(resource_save_button); resource_save_button->get_popup()->add_item(TTR("Save"), RESOURCE_SAVE); resource_save_button->get_popup()->add_item(TTR("Save As..."), RESOURCE_SAVE_AS); @@ -597,7 +596,6 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) { resource_save_button->set_disabled(true); resource_extra_button = memnew(MenuButton); - resource_extra_button->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); resource_extra_button->set_tooltip(TTR("Extra resource options.")); general_options_hb->add_child(resource_extra_button); resource_extra_button->connect("about_to_popup", callable_mp(this, &InspectorDock::_prepare_resource_extra_popup)); @@ -614,11 +612,6 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) { backward_button = memnew(Button); backward_button->set_flat(true); general_options_hb->add_child(backward_button); - if (is_layout_rtl()) { - backward_button->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); - } else { - backward_button->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); - } backward_button->set_tooltip(TTR("Go to the previous edited object in history.")); backward_button->set_disabled(true); backward_button->connect("pressed", callable_mp(this, &InspectorDock::_edit_back)); @@ -626,18 +619,12 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) { forward_button = memnew(Button); forward_button->set_flat(true); general_options_hb->add_child(forward_button); - if (is_layout_rtl()) { - forward_button->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); - } else { - forward_button->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); - } forward_button->set_tooltip(TTR("Go to the next edited object in history.")); forward_button->set_disabled(true); forward_button->connect("pressed", callable_mp(this, &InspectorDock::_edit_forward)); history_menu = memnew(MenuButton); history_menu->set_tooltip(TTR("History of recently edited objects.")); - history_menu->set_icon(get_theme_icon(SNAME("History"), SNAME("EditorIcons"))); general_options_hb->add_child(history_menu); history_menu->connect("about_to_popup", callable_mp(this, &InspectorDock::_prepare_history)); history_menu->get_popup()->connect("id_pressed", callable_mp(this, &InspectorDock::_select_history)); @@ -652,7 +639,6 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) { open_docs_button->set_flat(true); open_docs_button->set_disabled(true); open_docs_button->set_tooltip(TTR("Open documentation for this object.")); - open_docs_button->set_icon(get_theme_icon(SNAME("HelpSearch"), SNAME("EditorIcons"))); open_docs_button->set_shortcut(ED_SHORTCUT("property_editor/open_help", TTR("Open Documentation"))); subresource_hb->add_child(open_docs_button); open_docs_button->connect("pressed", callable_mp(this, &InspectorDock::_menu_option), varray(OBJECT_REQUEST_HELP)); @@ -668,13 +654,11 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) { search = memnew(LineEdit); search->set_h_size_flags(Control::SIZE_EXPAND_FILL); search->set_placeholder(TTR("Filter properties")); - search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); search->set_clear_button_enabled(true); property_tools_hb->add_child(search); object_menu = memnew(MenuButton); object_menu->set_shortcut_context(this); - object_menu->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons"))); property_tools_hb->add_child(object_menu); object_menu->set_tooltip(TTR("Manage object properties.")); object_menu->get_popup()->connect("id_pressed", callable_mp(this, &InspectorDock::_menu_option)); @@ -682,8 +666,6 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) { warning = memnew(Button); add_child(warning); warning->set_text(TTR("Changes may be lost!")); - warning->set_icon(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons"))); - warning->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor"))); warning->set_clip_text(true); warning->hide(); warning->connect("pressed", callable_mp(this, &InspectorDock::_warning_pressed)); diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index 459de5d35b..c0029312a7 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -488,10 +488,11 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() { color.a *= 0.2; } - Vector<Color> colors; - colors.push_back(color); - colors.push_back(color); - colors.push_back(color); + Vector<Color> colors = { + color, + color, + color + }; blend_space_draw->draw_primitive(points, colors, Vector<Vector2>()); } diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 9ebdede4e9..10e2f5f1d0 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -732,6 +732,10 @@ void AnimationNodeBlendTreeEditor::_removed_from_graph() { } void AnimationNodeBlendTreeEditor::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { + graph->set_panning_scheme((GraphEdit::PanningScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int()); + } + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 089c37d7a6..cb84e7ea65 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -3381,10 +3381,11 @@ void CanvasItemEditor::_draw_selection() { Size2 move_factor = Size2(MOVE_HANDLE_DISTANCE, MOVE_HANDLE_DISTANCE); viewport->draw_set_transform_matrix(simple_xform); - Vector<Point2> points; - points.push_back(Vector2(move_factor.x * EDSCALE, 5 * EDSCALE)); - points.push_back(Vector2(move_factor.x * EDSCALE, -5 * EDSCALE)); - points.push_back(Vector2((move_factor.x + 10) * EDSCALE, 0)); + Vector<Point2> points = { + Vector2(move_factor.x * EDSCALE, 5 * EDSCALE), + Vector2(move_factor.x * EDSCALE, -5 * EDSCALE), + Vector2((move_factor.x + 10) * EDSCALE, 0) + }; viewport->draw_colored_polygon(points, get_theme_color(SNAME("axis_x_color"), SNAME("Editor"))); viewport->draw_line(Point2(), Point2(move_factor.x * EDSCALE, 0), get_theme_color(SNAME("axis_x_color"), SNAME("Editor")), Math::round(EDSCALE)); @@ -5823,11 +5824,12 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String & editor_data->get_undo_redo().add_do_property(child, "rect_size", texture_size); } else if (node_class == "Polygon2D") { Size2 texture_size = texture->get_size(); - Vector<Vector2> list; - list.push_back(Vector2(0, 0)); - list.push_back(Vector2(texture_size.width, 0)); - list.push_back(Vector2(texture_size.width, texture_size.height)); - list.push_back(Vector2(0, texture_size.height)); + Vector<Vector2> list = { + Vector2(0, 0), + Vector2(texture_size.width, 0), + Vector2(texture_size.width, texture_size.height), + Vector2(0, texture_size.height) + }; editor_data->get_undo_redo().add_do_property(child, "polygon", list); } diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.cpp b/editor/plugins/collision_polygon_3d_editor_plugin.cpp index bf6485f9ec..52651ae380 100644 --- a/editor/plugins/collision_polygon_3d_editor_plugin.cpp +++ b/editor/plugins/collision_polygon_3d_editor_plugin.cpp @@ -358,6 +358,7 @@ void CollisionPolygon3DEditor::_polygon_draw() { float depth = _get_depth() * 0.5; + m->clear_surfaces(); imesh->clear_surfaces(); imgeom->set_material_override(line_material); imesh->surface_begin(Mesh::PRIMITIVE_LINES); diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp index 474e84cae8..59ba49232e 100644 --- a/editor/plugins/node_3d_editor_gizmos.cpp +++ b/editor/plugins/node_3d_editor_gizmos.cpp @@ -117,52 +117,52 @@ void EditorNode3DGizmo::redraw() { } } -String EditorNode3DGizmo::get_handle_name(int p_id) const { +String EditorNode3DGizmo::get_handle_name(int p_id, bool p_secondary) const { String ret; - if (GDVIRTUAL_CALL(_get_handle_name, p_id, ret)) { + if (GDVIRTUAL_CALL(_get_handle_name, p_id, p_secondary, ret)) { return ret; } ERR_FAIL_COND_V(!gizmo_plugin, ""); - return gizmo_plugin->get_handle_name(this, p_id); + return gizmo_plugin->get_handle_name(this, p_id, p_secondary); } -bool EditorNode3DGizmo::is_handle_highlighted(int p_id) const { +bool EditorNode3DGizmo::is_handle_highlighted(int p_id, bool p_secondary) const { bool success; - if (GDVIRTUAL_CALL(_is_handle_highlighted, p_id, success)) { + if (GDVIRTUAL_CALL(_is_handle_highlighted, p_id, p_secondary, success)) { return success; } ERR_FAIL_COND_V(!gizmo_plugin, false); - return gizmo_plugin->is_handle_highlighted(this, p_id); + return gizmo_plugin->is_handle_highlighted(this, p_id, p_secondary); } -Variant EditorNode3DGizmo::get_handle_value(int p_id) const { +Variant EditorNode3DGizmo::get_handle_value(int p_id, bool p_secondary) const { Variant value; - if (GDVIRTUAL_CALL(_get_handle_value, p_id, value)) { + if (GDVIRTUAL_CALL(_get_handle_value, p_id, p_secondary, value)) { return value; } ERR_FAIL_COND_V(!gizmo_plugin, Variant()); - return gizmo_plugin->get_handle_value(this, p_id); + return gizmo_plugin->get_handle_value(this, p_id, p_secondary); } -void EditorNode3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) { - if (GDVIRTUAL_CALL(_set_handle, p_id, p_camera, p_point)) { +void EditorNode3DGizmo::set_handle(int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { + if (GDVIRTUAL_CALL(_set_handle, p_id, p_secondary, p_camera, p_point)) { return; } ERR_FAIL_COND(!gizmo_plugin); - gizmo_plugin->set_handle(this, p_id, p_camera, p_point); + gizmo_plugin->set_handle(this, p_id, p_secondary, p_camera, p_point); } -void EditorNode3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p_cancel) { - if (GDVIRTUAL_CALL(_commit_handle, p_id, p_restore, p_cancel)) { +void EditorNode3DGizmo::commit_handle(int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { + if (GDVIRTUAL_CALL(_commit_handle, p_id, p_secondary, p_restore, p_cancel)) { return; } ERR_FAIL_COND(!gizmo_plugin); - gizmo_plugin->commit_handle(this, p_id, p_restore, p_cancel); + gizmo_plugin->commit_handle(this, p_id, p_secondary, p_restore, p_cancel); } int EditorNode3DGizmo::subgizmos_intersect_ray(Camera3D *p_camera, const Vector2 &p_point) const { @@ -324,37 +324,34 @@ void EditorNode3DGizmo::add_unscaled_billboard(const Ref<Material> &p_material, ERR_FAIL_COND(!spatial_node); Instance ins; - Vector<Vector3> vs; - Vector<Vector2> uv; - Vector<Color> colors; - - vs.push_back(Vector3(-p_scale, p_scale, 0)); - vs.push_back(Vector3(p_scale, p_scale, 0)); - vs.push_back(Vector3(p_scale, -p_scale, 0)); - vs.push_back(Vector3(-p_scale, -p_scale, 0)); - - uv.push_back(Vector2(0, 0)); - uv.push_back(Vector2(1, 0)); - uv.push_back(Vector2(1, 1)); - uv.push_back(Vector2(0, 1)); - - colors.push_back(p_modulate); - colors.push_back(p_modulate); - colors.push_back(p_modulate); - colors.push_back(p_modulate); + Vector<Vector3> vs = { + Vector3(-p_scale, p_scale, 0), + Vector3(p_scale, p_scale, 0), + Vector3(p_scale, -p_scale, 0), + Vector3(-p_scale, -p_scale, 0) + }; + + Vector<Vector2> uv = { + Vector2(0, 0), + Vector2(1, 0), + Vector2(1, 1), + Vector2(0, 1) + }; + + Vector<Color> colors = { + p_modulate, + p_modulate, + p_modulate, + p_modulate + }; + + Vector<int> indices = { 0, 1, 2, 0, 2, 3 }; Ref<ArrayMesh> mesh = memnew(ArrayMesh); Array a; a.resize(Mesh::ARRAY_MAX); a[Mesh::ARRAY_VERTEX] = vs; a[Mesh::ARRAY_TEX_UV] = uv; - Vector<int> indices; - indices.push_back(0); - indices.push_back(1); - indices.push_back(2); - indices.push_back(0); - indices.push_back(2); - indices.push_back(3); a[Mesh::ARRAY_INDEX] = indices; a[Mesh::ARRAY_COLOR] = colors; mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, a); @@ -410,7 +407,8 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref< } bool is_current_hover_gizmo = Node3DEditor::get_singleton()->get_current_hover_gizmo() == this; - int current_hover_handle = Node3DEditor::get_singleton()->get_current_hover_gizmo_handle(); + bool current_hover_handle_secondary; + int current_hover_handle = Node3DEditor::get_singleton()->get_current_hover_gizmo_handle(current_hover_handle_secondary); Instance ins; Ref<ArrayMesh> mesh = memnew(ArrayMesh); @@ -424,12 +422,12 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref< Color *w = colors.ptrw(); for (int i = 0; i < p_handles.size(); i++) { Color col(1, 1, 1, 1); - if (is_handle_highlighted(i)) { + if (is_handle_highlighted(i, p_secondary)) { col = Color(0, 0, 1, 0.9); } int id = p_ids.is_empty() ? i : p_ids[i]; - if (!is_current_hover_gizmo || current_hover_handle != id) { + if (!is_current_hover_gizmo || current_hover_handle != id || p_secondary != current_hover_handle_secondary) { col.a = 0.8; } @@ -574,8 +572,9 @@ bool EditorNode3DGizmo::intersect_frustum(const Camera3D *p_camera, const Vector return false; } -void EditorNode3DGizmo::handles_intersect_ray(Camera3D *p_camera, const Vector2 &p_point, bool p_shift_pressed, int &r_id) { +void EditorNode3DGizmo::handles_intersect_ray(Camera3D *p_camera, const Vector2 &p_point, bool p_shift_pressed, int &r_id, bool &r_secondary) { r_id = -1; + r_secondary = false; ERR_FAIL_COND(!spatial_node); ERR_FAIL_COND(!valid); @@ -605,6 +604,7 @@ void EditorNode3DGizmo::handles_intersect_ray(Camera3D *p_camera, const Vector2 } else { r_id = secondary_handle_ids[i]; } + r_secondary = true; } } } @@ -628,6 +628,7 @@ void EditorNode3DGizmo::handles_intersect_ray(Camera3D *p_camera, const Vector2 } else { r_id = handle_ids[i]; } + r_secondary = false; } } } @@ -839,12 +840,12 @@ void EditorNode3DGizmo::_bind_methods() { ClassDB::bind_method(D_METHOD("get_subgizmo_selection"), &EditorNode3DGizmo::get_subgizmo_selection); GDVIRTUAL_BIND(_redraw); - GDVIRTUAL_BIND(_get_handle_name, "id"); - GDVIRTUAL_BIND(_is_handle_highlighted, "id"); + GDVIRTUAL_BIND(_get_handle_name, "id", "secondary"); + GDVIRTUAL_BIND(_is_handle_highlighted, "id", "secondary"); - GDVIRTUAL_BIND(_get_handle_value, "id"); - GDVIRTUAL_BIND(_set_handle, "id", "camera", "point"); - GDVIRTUAL_BIND(_commit_handle, "id", "restore", "cancel"); + GDVIRTUAL_BIND(_get_handle_value, "id", "secondary"); + GDVIRTUAL_BIND(_set_handle, "id", "secondary", "camera", "point"); + GDVIRTUAL_BIND(_commit_handle, "id", "secondary", "restore", "cancel"); GDVIRTUAL_BIND(_subgizmos_intersect_ray, "camera", "point"); GDVIRTUAL_BIND(_subgizmos_intersect_frustum, "camera", "frustum"); @@ -1054,12 +1055,12 @@ void EditorNode3DGizmoPlugin::_bind_methods() { GDVIRTUAL_BIND(_is_selectable_when_hidden); GDVIRTUAL_BIND(_redraw, "gizmo"); - GDVIRTUAL_BIND(_get_handle_name, "gizmo", "handle_id"); - GDVIRTUAL_BIND(_is_handle_highlighted, "gizmo", "handle_id"); - GDVIRTUAL_BIND(_get_handle_value, "gizmo", "handle_id"); + GDVIRTUAL_BIND(_get_handle_name, "gizmo", "handle_id", "secondary"); + GDVIRTUAL_BIND(_is_handle_highlighted, "gizmo", "handle_id", "secondary"); + GDVIRTUAL_BIND(_get_handle_value, "gizmo", "handle_id", "secondary"); - GDVIRTUAL_BIND(_set_handle, "gizmo", "handle_id", "camera", "screen_pos"); - GDVIRTUAL_BIND(_commit_handle, "gizmo", "handle_id", "restore", "cancel"); + GDVIRTUAL_BIND(_set_handle, "gizmo", "handle_id", "secondary", "camera", "screen_pos"); + GDVIRTUAL_BIND(_commit_handle, "gizmo", "handle_id", "secondary", "restore", "cancel"); GDVIRTUAL_BIND(_subgizmos_intersect_ray, "gizmo", "camera", "screen_pos"); GDVIRTUAL_BIND(_subgizmos_intersect_frustum, "gizmo", "camera", "frustum_planes"); @@ -1110,36 +1111,36 @@ void EditorNode3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { GDVIRTUAL_CALL(_redraw, p_gizmo); } -bool EditorNode3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const { +bool EditorNode3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { bool ret; - if (GDVIRTUAL_CALL(_is_handle_highlighted, Ref<EditorNode3DGizmo>(p_gizmo), p_id, ret)) { + if (GDVIRTUAL_CALL(_is_handle_highlighted, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, ret)) { return ret; } return false; } -String EditorNode3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { +String EditorNode3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { String ret; - if (GDVIRTUAL_CALL(_get_handle_name, Ref<EditorNode3DGizmo>(p_gizmo), p_id, ret)) { + if (GDVIRTUAL_CALL(_get_handle_name, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, ret)) { return ret; } return ""; } -Variant EditorNode3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { +Variant EditorNode3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { Variant ret; - if (GDVIRTUAL_CALL(_get_handle_value, Ref<EditorNode3DGizmo>(p_gizmo), p_id, ret)) { + if (GDVIRTUAL_CALL(_get_handle_value, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, ret)) { return ret; } return Variant(); } -void EditorNode3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) { - GDVIRTUAL_CALL(_set_handle, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_camera, p_point); +void EditorNode3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { + GDVIRTUAL_CALL(_set_handle, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, p_camera, p_point); } -void EditorNode3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { - GDVIRTUAL_CALL(_commit_handle, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_restore, p_cancel); +void EditorNode3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { + GDVIRTUAL_CALL(_commit_handle, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, p_restore, p_cancel); } int EditorNode3DGizmoPlugin::subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const { @@ -1244,7 +1245,7 @@ int Light3DGizmoPlugin::get_priority() const { return -1; } -String Light3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { +String Light3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { if (p_id == 0) { return "Radius"; } else { @@ -1252,7 +1253,7 @@ String Light3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int } } -Variant Light3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { +Variant Light3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node()); if (p_id == 0) { return light->get_param(Light3D::PARAM_RANGE); @@ -1291,7 +1292,7 @@ static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vec return Math::rad2deg(a); } -void Light3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) { +void Light3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node()); Transform3D gt = light->get_global_transform(); Transform3D gi = gt.affine_inverse(); @@ -1335,7 +1336,7 @@ void Light3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, } } -void Light3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { +void Light3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node()); if (p_cancel) { light->set_param(p_id == 0 ? Light3D::PARAM_RANGE : Light3D::PARAM_SPOT_ANGLE, p_restore); @@ -1477,9 +1478,10 @@ void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p_gizmo->add_lines(points_primary, material_primary, false, color); p_gizmo->add_lines(points_secondary, material_secondary, false, color); - Vector<Vector3> handles; - handles.push_back(Vector3(0, 0, -r)); - handles.push_back(Vector3(w, 0, -d)); + Vector<Vector3> handles = { + Vector3(0, 0, -r), + Vector3(w, 0, -d) + }; p_gizmo->add_handles(handles, get_material("handles")); p_gizmo->add_unscaled_billboard(icon, 0.05, color); @@ -1508,16 +1510,16 @@ int AudioStreamPlayer3DGizmoPlugin::get_priority() const { return -1; } -String AudioStreamPlayer3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { +String AudioStreamPlayer3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { return "Emission Radius"; } -Variant AudioStreamPlayer3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { +Variant AudioStreamPlayer3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node()); return player->get_emission_angle(); } -void AudioStreamPlayer3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) { +void AudioStreamPlayer3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node()); Transform3D gt = player->get_global_transform(); @@ -1554,7 +1556,7 @@ void AudioStreamPlayer3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo } } -void AudioStreamPlayer3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { +void AudioStreamPlayer3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node()); if (p_cancel) { @@ -1666,7 +1668,7 @@ int Camera3DGizmoPlugin::get_priority() const { return -1; } -String Camera3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { +String Camera3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node()); if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) { @@ -1676,7 +1678,7 @@ String Camera3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, in } } -Variant Camera3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { +Variant Camera3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node()); if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) { @@ -1686,7 +1688,7 @@ Variant Camera3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, } } -void Camera3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) { +void Camera3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node()); Transform3D gt = camera->get_global_transform(); @@ -1715,7 +1717,7 @@ void Camera3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, } } -void Camera3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { +void Camera3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node()); if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) { @@ -2210,10 +2212,10 @@ void SpringArm3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p_gizmo->clear(); - Vector<Vector3> lines; - - lines.push_back(Vector3()); - lines.push_back(Vector3(0, 0, 1.0) * spring_arm->get_length()); + Vector<Vector3> lines = { + Vector3(), + Vector3(0, 0, 1.0) * spring_arm->get_length() + }; Ref<StandardMaterial3D> material = get_material("shape_material", p_gizmo); @@ -2370,21 +2372,21 @@ void SoftDynamicBody3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p_gizmo->add_collision_triangles(tm); } -String SoftDynamicBody3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { +String SoftDynamicBody3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { return "SoftDynamicBody3D pin point"; } -Variant SoftDynamicBody3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { +Variant SoftDynamicBody3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { SoftDynamicBody3D *soft_body = Object::cast_to<SoftDynamicBody3D>(p_gizmo->get_spatial_node()); return Variant(soft_body->is_point_pinned(p_id)); } -void SoftDynamicBody3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { +void SoftDynamicBody3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { SoftDynamicBody3D *soft_body = Object::cast_to<SoftDynamicBody3D>(p_gizmo->get_spatial_node()); soft_body->pin_point_toggle(p_id); } -bool SoftDynamicBody3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const { +bool SoftDynamicBody3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { SoftDynamicBody3D *soft_body = Object::cast_to<SoftDynamicBody3D>(p_gizmo->get_spatial_node()); return soft_body->is_point_pinned(p_id); } @@ -2411,7 +2413,7 @@ int VisibleOnScreenNotifier3DGizmoPlugin::get_priority() const { return -1; } -String VisibleOnScreenNotifier3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { +String VisibleOnScreenNotifier3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { switch (p_id) { case 0: return "Size X"; @@ -2430,12 +2432,12 @@ String VisibleOnScreenNotifier3DGizmoPlugin::get_handle_name(const EditorNode3DG return ""; } -Variant VisibleOnScreenNotifier3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { +Variant VisibleOnScreenNotifier3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_spatial_node()); return notifier->get_aabb(); } -void VisibleOnScreenNotifier3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) { +void VisibleOnScreenNotifier3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_spatial_node()); Transform3D gt = notifier->get_global_transform(); @@ -2487,7 +2489,7 @@ void VisibleOnScreenNotifier3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p } } -void VisibleOnScreenNotifier3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { +void VisibleOnScreenNotifier3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_spatial_node()); if (p_cancel) { @@ -2603,7 +2605,7 @@ bool GPUParticles3DGizmoPlugin::is_selectable_when_hidden() const { return true; } -String GPUParticles3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { +String GPUParticles3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { switch (p_id) { case 0: return "Size X"; @@ -2622,12 +2624,12 @@ String GPUParticles3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_giz return ""; } -Variant GPUParticles3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { +Variant GPUParticles3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node()); return particles->get_visibility_aabb(); } -void GPUParticles3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) { +void GPUParticles3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node()); Transform3D gt = particles->get_global_transform(); @@ -2678,7 +2680,7 @@ void GPUParticles3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int } } -void GPUParticles3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { +void GPUParticles3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node()); if (p_cancel) { @@ -2764,7 +2766,7 @@ int GPUParticlesCollision3DGizmoPlugin::get_priority() const { return -1; } -String GPUParticlesCollision3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { +String GPUParticlesCollision3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { const Node3D *cs = p_gizmo->get_spatial_node(); if (Object::cast_to<GPUParticlesCollisionSphere3D>(cs) || Object::cast_to<GPUParticlesAttractorSphere3D>(cs)) { @@ -2778,7 +2780,7 @@ String GPUParticlesCollision3DGizmoPlugin::get_handle_name(const EditorNode3DGiz return ""; } -Variant GPUParticlesCollision3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { +Variant GPUParticlesCollision3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { const Node3D *cs = p_gizmo->get_spatial_node(); if (Object::cast_to<GPUParticlesCollisionSphere3D>(cs) || Object::cast_to<GPUParticlesAttractorSphere3D>(cs)) { @@ -2792,7 +2794,7 @@ Variant GPUParticlesCollision3DGizmoPlugin::get_handle_value(const EditorNode3DG return Variant(); } -void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) { +void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { Node3D *sn = p_gizmo->get_spatial_node(); Transform3D gt = sn->get_global_transform(); @@ -2838,7 +2840,7 @@ void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_g } } -void GPUParticlesCollision3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { +void GPUParticlesCollision3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { Node3D *sn = p_gizmo->get_spatial_node(); if (Object::cast_to<GPUParticlesCollisionSphere3D>(sn) || Object::cast_to<GPUParticlesAttractorSphere3D>(sn)) { @@ -3027,7 +3029,7 @@ int ReflectionProbeGizmoPlugin::get_priority() const { return -1; } -String ReflectionProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { +String ReflectionProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { switch (p_id) { case 0: return "Extents X"; @@ -3046,12 +3048,12 @@ String ReflectionProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gi return ""; } -Variant ReflectionProbeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { +Variant ReflectionProbeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node()); return AABB(probe->get_extents(), probe->get_origin_offset()); } -void ReflectionProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) { +void ReflectionProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node()); Transform3D gt = probe->get_global_transform(); @@ -3108,7 +3110,7 @@ void ReflectionProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, in } } -void ReflectionProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { +void ReflectionProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node()); AABB restore = p_restore; @@ -3212,7 +3214,7 @@ int DecalGizmoPlugin::get_priority() const { return -1; } -String DecalGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { +String DecalGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { switch (p_id) { case 0: return "Extents X"; @@ -3225,12 +3227,12 @@ String DecalGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p return ""; } -Variant DecalGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { +Variant DecalGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node()); return decal->get_extents(); } -void DecalGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) { +void DecalGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node()); Transform3D gt = decal->get_global_transform(); @@ -3261,7 +3263,7 @@ void DecalGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Ca decal->set_extents(extents); } -void DecalGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { +void DecalGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node()); Vector3 restore = p_restore; @@ -3352,7 +3354,7 @@ int VoxelGIGizmoPlugin::get_priority() const { return -1; } -String VoxelGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { +String VoxelGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { switch (p_id) { case 0: return "Extents X"; @@ -3365,12 +3367,12 @@ String VoxelGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int return ""; } -Variant VoxelGIGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { +Variant VoxelGIGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node()); return probe->get_extents(); } -void VoxelGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) { +void VoxelGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node()); Transform3D gt = probe->get_global_transform(); @@ -3401,7 +3403,7 @@ void VoxelGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, probe->set_extents(extents); } -void VoxelGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { +void VoxelGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node()); Vector3 restore = p_restore; @@ -3521,20 +3523,6 @@ LightmapGIGizmoPlugin::LightmapGIGizmoPlugin() { create_icon_material("baked_indirect_light_icon", Node3DEditor::get_singleton()->get_theme_icon(SNAME("GizmoLightmapGI"), SNAME("EditorIcons"))); } -String LightmapGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { - return ""; -} - -Variant LightmapGIGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { - return Variant(); -} - -void LightmapGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) { -} - -void LightmapGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { -} - bool LightmapGIGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<LightmapGI>(p_spatial) != nullptr; } @@ -3703,20 +3691,6 @@ LightmapProbeGizmoPlugin::LightmapProbeGizmoPlugin() { create_material("lightprobe_lines", gizmo_color); } -String LightmapProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { - return ""; -} - -Variant LightmapProbeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { - return Variant(); -} - -void LightmapProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) { -} - -void LightmapProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { -} - bool LightmapProbeGizmoPlugin::has_gizmo(Node3D *p_spatial) { return Object::cast_to<LightmapProbe>(p_spatial) != nullptr; } @@ -3863,7 +3837,7 @@ int CollisionShape3DGizmoPlugin::get_priority() const { return -1; } -String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { +String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { const CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node()); Ref<Shape3D> s = cs->get_shape(); @@ -3894,7 +3868,7 @@ String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_g return ""; } -Variant CollisionShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { +Variant CollisionShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node()); Ref<Shape3D> s = cs->get_shape(); @@ -3930,7 +3904,7 @@ Variant CollisionShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p return Variant(); } -void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) { +void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node()); Ref<Shape3D> s = cs->get_shape(); @@ -4044,7 +4018,7 @@ void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, i } } -void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { +void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node()); Ref<Shape3D> s = cs->get_shape(); @@ -4296,9 +4270,10 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p_gizmo->add_collision_segments(collision_segments); - Vector<Vector3> handles; - handles.push_back(Vector3(cs2->get_radius(), 0, 0)); - handles.push_back(Vector3(0, cs2->get_height() * 0.5, 0)); + Vector<Vector3> handles = { + Vector3(cs2->get_radius(), 0, 0), + Vector3(0, cs2->get_height() * 0.5, 0) + }; p_gizmo->add_handles(handles, handles_material); } @@ -4352,16 +4327,16 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p_gizmo->add_collision_segments(collision_segments); - Vector<Vector3> handles; - handles.push_back(Vector3(cs2->get_radius(), 0, 0)); - handles.push_back(Vector3(0, cs2->get_height() * 0.5, 0)); + Vector<Vector3> handles = { + Vector3(cs2->get_radius(), 0, 0), + Vector3(0, cs2->get_height() * 0.5, 0) + }; p_gizmo->add_handles(handles, handles_material); } if (Object::cast_to<WorldBoundaryShape3D>(*s)) { Ref<WorldBoundaryShape3D> wbs = s; const Plane &p = wbs->get_plane(); - Vector<Vector3> points; Vector3 n1 = p.get_any_perpendicular_normal(); Vector3 n2 = p.normal.cross(n1).normalized(); @@ -4373,16 +4348,18 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p.normal * p.d + n1 * -10.0 + n2 * 10.0, }; - points.push_back(pface[0]); - points.push_back(pface[1]); - points.push_back(pface[1]); - points.push_back(pface[2]); - points.push_back(pface[2]); - points.push_back(pface[3]); - points.push_back(pface[3]); - points.push_back(pface[0]); - points.push_back(p.normal * p.d); - points.push_back(p.normal * p.d + p.normal * 3); + Vector<Vector3> points = { + pface[0], + pface[1], + pface[1], + pface[2], + pface[2], + pface[3], + pface[3], + pface[0], + p.normal * p.d, + p.normal * p.d + p.normal * 3 + }; p_gizmo->add_lines(points, material); p_gizmo->add_collision_segments(points); @@ -4419,9 +4396,10 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { if (Object::cast_to<SeparationRayShape3D>(*s)) { Ref<SeparationRayShape3D> rs = s; - Vector<Vector3> points; - points.push_back(Vector3()); - points.push_back(Vector3(0, 0, rs->get_length())); + Vector<Vector3> points = { + Vector3(), + Vector3(0, 0, rs->get_length()) + }; p_gizmo->add_lines(points, material); p_gizmo->add_collision_segments(points); Vector<Vector3> handles; @@ -5298,15 +5276,15 @@ int FogVolumeGizmoPlugin::get_priority() const { return -1; } -String FogVolumeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { +String FogVolumeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { return "Extents"; } -Variant FogVolumeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { +Variant FogVolumeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { return Vector3(p_gizmo->get_spatial_node()->call("get_extents")); } -void FogVolumeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) { +void FogVolumeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { Node3D *sn = p_gizmo->get_spatial_node(); Transform3D gt = sn->get_global_transform(); @@ -5335,7 +5313,7 @@ void FogVolumeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id sn->call("set_extents", he); } -void FogVolumeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { +void FogVolumeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { Node3D *sn = p_gizmo->get_spatial_node(); if (p_cancel) { diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h index a8383aefed..66b3f02fcf 100644 --- a/editor/plugins/node_3d_editor_gizmos.h +++ b/editor/plugins/node_3d_editor_gizmos.h @@ -80,12 +80,11 @@ protected: EditorNode3DGizmoPlugin *gizmo_plugin; GDVIRTUAL0(_redraw) - GDVIRTUAL1RC(String, _get_handle_name, int) - GDVIRTUAL1RC(bool, _is_handle_highlighted, int) - - GDVIRTUAL1RC(Variant, _get_handle_value, int) - GDVIRTUAL3(_set_handle, int, const Camera3D *, Vector2) - GDVIRTUAL3(_commit_handle, int, Variant, bool) + GDVIRTUAL2RC(String, _get_handle_name, int, bool) + GDVIRTUAL2RC(bool, _is_handle_highlighted, int, bool) + GDVIRTUAL2RC(Variant, _get_handle_value, int, bool) + GDVIRTUAL4(_set_handle, int, bool, const Camera3D *, Vector2) + GDVIRTUAL4(_commit_handle, int, bool, Variant, bool) GDVIRTUAL2RC(int, _subgizmos_intersect_ray, const Camera3D *, Vector2) GDVIRTUAL2RC(Vector<int>, _subgizmos_intersect_frustum, const Camera3D *, TypedArray<Plane>) @@ -102,11 +101,11 @@ public: void add_handles(const Vector<Vector3> &p_handles, const Ref<Material> &p_material, const Vector<int> &p_ids = Vector<int>(), bool p_billboard = false, bool p_secondary = false); void add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position = Vector3(), const Transform3D &p_xform = Transform3D()); - virtual bool is_handle_highlighted(int p_id) const; - virtual String get_handle_name(int p_id) const; - virtual Variant get_handle_value(int p_id) const; - virtual void set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point); - virtual void commit_handle(int p_id, const Variant &p_restore, bool p_cancel = false); + virtual bool is_handle_highlighted(int p_id, bool p_secondary) const; + virtual String get_handle_name(int p_id, bool p_secondary) const; + virtual Variant get_handle_value(int p_id, bool p_secondary) const; + virtual void set_handle(int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point); + virtual void commit_handle(int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false); virtual int subgizmos_intersect_ray(Camera3D *p_camera, const Vector2 &p_point) const; virtual Vector<int> subgizmos_intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum) const; @@ -121,7 +120,7 @@ public: Node3D *get_spatial_node() const { return spatial_node; } Ref<EditorNode3DGizmoPlugin> get_plugin() const { return gizmo_plugin; } bool intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum); - void handles_intersect_ray(Camera3D *p_camera, const Vector2 &p_point, bool p_shift_pressed, int &r_id); + void handles_intersect_ray(Camera3D *p_camera, const Vector2 &p_point, bool p_shift_pressed, int &r_id, bool &r_secondary); bool intersect_ray(Camera3D *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal); bool is_subgizmo_selected(int p_id) const; Vector<int> get_subgizmo_selection() const; @@ -167,12 +166,12 @@ protected: GDVIRTUAL0RC(bool, _is_selectable_when_hidden) GDVIRTUAL1(_redraw, Ref<EditorNode3DGizmo>) - GDVIRTUAL2RC(String, _get_handle_name, Ref<EditorNode3DGizmo>, int) - GDVIRTUAL2RC(bool, _is_handle_highlighted, Ref<EditorNode3DGizmo>, int) - GDVIRTUAL2RC(Variant, _get_handle_value, Ref<EditorNode3DGizmo>, int) + GDVIRTUAL3RC(String, _get_handle_name, Ref<EditorNode3DGizmo>, int, bool) + GDVIRTUAL3RC(bool, _is_handle_highlighted, Ref<EditorNode3DGizmo>, int, bool) + GDVIRTUAL3RC(Variant, _get_handle_value, Ref<EditorNode3DGizmo>, int, bool) - GDVIRTUAL4(_set_handle, Ref<EditorNode3DGizmo>, int, const Camera3D *, Vector2) - GDVIRTUAL4(_commit_handle, Ref<EditorNode3DGizmo>, int, Variant, bool) + GDVIRTUAL5(_set_handle, Ref<EditorNode3DGizmo>, int, bool, const Camera3D *, Vector2) + GDVIRTUAL5(_commit_handle, Ref<EditorNode3DGizmo>, int, bool, Variant, bool) GDVIRTUAL3RC(int, _subgizmos_intersect_ray, Ref<EditorNode3DGizmo>, const Camera3D *, Vector2) GDVIRTUAL3RC(Vector<int>, _subgizmos_intersect_frustum, Ref<EditorNode3DGizmo>, const Camera3D *, TypedArray<Plane>) @@ -194,11 +193,11 @@ public: virtual bool is_selectable_when_hidden() const; virtual void redraw(EditorNode3DGizmo *p_gizmo); - virtual bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const; - virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const; - virtual Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const; - virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point); - virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false); + virtual bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const; + virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const; + virtual Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const; + virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point); + virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false); virtual int subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const; virtual Vector<int> subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const; @@ -223,10 +222,10 @@ public: String get_gizmo_name() const override; int get_priority() const override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override; void redraw(EditorNode3DGizmo *p_gizmo) override; Light3DGizmoPlugin(); @@ -240,10 +239,10 @@ public: String get_gizmo_name() const override; int get_priority() const override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override; void redraw(EditorNode3DGizmo *p_gizmo) override; AudioStreamPlayer3DGizmoPlugin(); @@ -270,10 +269,10 @@ public: String get_gizmo_name() const override; int get_priority() const override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override; void redraw(EditorNode3DGizmo *p_gizmo) override; Camera3DGizmoPlugin(); @@ -390,10 +389,10 @@ public: bool is_selectable_when_hidden() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override; - bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override; + bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; SoftDynamicBody3DGizmoPlugin(); }; @@ -407,10 +406,10 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override; VisibleOnScreenNotifier3DGizmoPlugin(); }; @@ -437,10 +436,10 @@ public: bool is_selectable_when_hidden() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override; GPUParticles3DGizmoPlugin(); }; @@ -454,10 +453,10 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override; GPUParticlesCollision3DGizmoPlugin(); }; @@ -471,10 +470,10 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override; ReflectionProbeGizmoPlugin(); }; @@ -488,10 +487,10 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override; DecalGizmoPlugin(); }; @@ -505,10 +504,10 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override; VoxelGIGizmoPlugin(); }; @@ -522,11 +521,6 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override; - LightmapGIGizmoPlugin(); }; @@ -539,11 +533,6 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override; - LightmapProbeGizmoPlugin(); }; @@ -568,10 +557,10 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override; CollisionShape3DGizmoPlugin(); }; @@ -678,10 +667,10 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override; - void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override; FogVolumeGizmoPlugin(); }; diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 957d1483bc..6ea8fba9b5 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -423,6 +423,7 @@ Vector3 Node3DEditorViewport::_get_ray(const Vector2 &p_pos) const { void Node3DEditorViewport::_clear_selected() { _edit.gizmo = Ref<EditorNode3DGizmo>(); _edit.gizmo_handle = -1; + _edit.gizmo_handle_secondary = false; _edit.gizmo_initial_value = Variant(); Node3D *selected = spatial_editor->get_single_selected_node(); @@ -1358,7 +1359,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { if (b->is_pressed() && _edit.gizmo.is_valid()) { //restore - _edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_initial_value, true); + _edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_handle_secondary, _edit.gizmo_initial_value, true); _edit.gizmo = Ref<EditorNode3DGizmo>(); } @@ -1496,11 +1497,13 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } int gizmo_handle = -1; - seg->handles_intersect_ray(camera, _edit.mouse_pos, b->is_shift_pressed(), gizmo_handle); + bool gizmo_secondary = false; + seg->handles_intersect_ray(camera, _edit.mouse_pos, b->is_shift_pressed(), gizmo_handle, gizmo_secondary); if (gizmo_handle != -1) { _edit.gizmo = seg; _edit.gizmo_handle = gizmo_handle; - _edit.gizmo_initial_value = seg->get_handle_value(gizmo_handle); + _edit.gizmo_handle_secondary = gizmo_secondary; + _edit.gizmo_initial_value = seg->get_handle_value(gizmo_handle, gizmo_secondary); intersected_handle = true; break; } @@ -1612,7 +1615,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { surface->update(); } else { if (_edit.gizmo.is_valid()) { - _edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_initial_value, false); + _edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_handle_secondary, _edit.gizmo_initial_value, false); _edit.gizmo = Ref<EditorNode3DGizmo>(); break; } @@ -1694,6 +1697,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { Ref<EditorNode3DGizmo> found_gizmo; int found_handle = -1; + bool found_handle_secondary = false; for (int i = 0; i < gizmos.size(); i++) { Ref<EditorNode3DGizmo> seg = gizmos[i]; @@ -1701,7 +1705,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { continue; } - seg->handles_intersect_ray(camera, _edit.mouse_pos, false, found_handle); + seg->handles_intersect_ray(camera, _edit.mouse_pos, false, found_handle, found_handle_secondary); if (found_handle != -1) { found_gizmo = seg; @@ -1713,9 +1717,11 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { spatial_editor->select_gizmo_highlight_axis(-1); } - if (found_gizmo != spatial_editor->get_current_hover_gizmo() || found_handle != spatial_editor->get_current_hover_gizmo_handle()) { + bool current_hover_handle_secondary = false; + int curreny_hover_handle = spatial_editor->get_current_hover_gizmo_handle(current_hover_handle_secondary); + if (found_gizmo != spatial_editor->get_current_hover_gizmo() || found_handle != curreny_hover_handle || found_handle_secondary != current_hover_handle_secondary) { spatial_editor->set_current_hover_gizmo(found_gizmo); - spatial_editor->set_current_hover_gizmo_handle(found_handle); + spatial_editor->set_current_hover_gizmo_handle(found_handle, found_handle_secondary); spatial_editor->get_single_selected_node()->update_gizmos(); } } @@ -1728,9 +1734,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { NavigationMode nav_mode = NAVIGATION_NONE; if (_edit.gizmo.is_valid()) { - _edit.gizmo->set_handle(_edit.gizmo_handle, camera, m->get_position()); - Variant v = _edit.gizmo->get_handle_value(_edit.gizmo_handle); - String n = _edit.gizmo->get_handle_name(_edit.gizmo_handle); + _edit.gizmo->set_handle(_edit.gizmo_handle, _edit.gizmo_handle_secondary, camera, m->get_position()); + Variant v = _edit.gizmo->get_handle_value(_edit.gizmo_handle, _edit.gizmo_handle_secondary); + String n = _edit.gizmo->get_handle_name(_edit.gizmo_handle, _edit.gizmo_handle_secondary); set_message(n + ": " + String(v)); } else if ((m->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { @@ -4301,6 +4307,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito _edit.plane = TRANSFORM_VIEW; _edit.snap = true; _edit.gizmo_handle = -1; + _edit.gizmo_handle_secondary = false; index = p_index; editor = p_editor; @@ -5306,6 +5313,7 @@ void Node3DEditor::edit(Node3D *p_spatial) { selected = p_spatial; current_hover_gizmo = Ref<EditorNode3DGizmo>(); current_hover_gizmo_handle = -1; + current_hover_gizmo_handle_secondary = false; if (selected) { Vector<Ref<Node3DGizmo>> gizmos = selected->get_gizmos(); @@ -7676,6 +7684,7 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) { EDITOR_DEF("editors/3d/navigation/show_viewport_rotation_gizmo", true); current_hover_gizmo_handle = -1; + current_hover_gizmo_handle_secondary = false; { //sun popup diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 8d42e88b53..da560f4d83 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -312,6 +312,7 @@ private: bool snap = false; Ref<EditorNode3DGizmo> gizmo; int gizmo_handle = 0; + bool gizmo_handle_secondary = false; Variant gizmo_initial_value; } _edit; @@ -554,6 +555,7 @@ private: Ref<Node3DGizmo> current_hover_gizmo; int current_hover_gizmo_handle; + bool current_hover_gizmo_handle_secondary; real_t snap_translate_value; real_t snap_rotate_value; @@ -810,8 +812,15 @@ public: Ref<EditorNode3DGizmo> get_current_hover_gizmo() const { return current_hover_gizmo; } void set_current_hover_gizmo(Ref<EditorNode3DGizmo> p_gizmo) { current_hover_gizmo = p_gizmo; } - void set_current_hover_gizmo_handle(int p_id) { current_hover_gizmo_handle = p_id; } - int get_current_hover_gizmo_handle() const { return current_hover_gizmo_handle; } + void set_current_hover_gizmo_handle(int p_id, bool p_secondary) { + current_hover_gizmo_handle = p_id; + current_hover_gizmo_handle_secondary = p_secondary; + } + + int get_current_hover_gizmo_handle(bool &r_secondary) const { + r_secondary = current_hover_gizmo_handle_secondary; + return current_hover_gizmo_handle; + } void set_can_preview(Camera3D *p_preview); diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp index c31b893498..cb62dcdccc 100644 --- a/editor/plugins/path_3d_editor_plugin.cpp +++ b/editor/plugins/path_3d_editor_plugin.cpp @@ -36,17 +36,17 @@ #include "node_3d_editor_plugin.h" #include "scene/resources/curve.h" -String Path3DGizmo::get_handle_name(int p_id) const { +String Path3DGizmo::get_handle_name(int p_id, bool p_secondary) const { Ref<Curve3D> c = path->get_curve(); if (c.is_null()) { return ""; } - if (p_id < c->get_point_count()) { + if (!p_secondary) { return TTR("Curve Point #") + itos(p_id); } - p_id = p_id - c->get_point_count() + 1; + p_id += 1; // Account for the first point only having an "out" handle int idx = p_id / 2; int t = p_id % 2; @@ -60,18 +60,18 @@ String Path3DGizmo::get_handle_name(int p_id) const { return n; } -Variant Path3DGizmo::get_handle_value(int p_id) const { +Variant Path3DGizmo::get_handle_value(int p_id, bool p_secondary) const { Ref<Curve3D> c = path->get_curve(); if (c.is_null()) { return Variant(); } - if (p_id < c->get_point_count()) { + if (!p_secondary) { original = c->get_point_position(p_id); return original; } - p_id = p_id - c->get_point_count() + 1; + p_id += 1; // Account for the first point only having an "out" handle int idx = p_id / 2; int t = p_id % 2; @@ -88,7 +88,7 @@ Variant Path3DGizmo::get_handle_value(int p_id) const { return ofs; } -void Path3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) { +void Path3DGizmo::set_handle(int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { Ref<Curve3D> c = path->get_curve(); if (c.is_null()) { return; @@ -100,7 +100,7 @@ void Path3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point Vector3 ray_dir = p_camera->project_ray_normal(p_point); // Setting curve point positions - if (p_id < c->get_point_count()) { + if (!p_secondary) { const Plane p = Plane(p_camera->get_transform().basis.get_axis(2), gt.xform(original)); Vector3 inters; @@ -118,7 +118,7 @@ void Path3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point return; } - p_id = p_id - c->get_point_count() + 1; + p_id += 1; // Account for the first point only having an "out" handle int idx = p_id / 2; int t = p_id % 2; @@ -157,7 +157,7 @@ void Path3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point } } -void Path3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p_cancel) { +void Path3DGizmo::commit_handle(int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { Ref<Curve3D> c = path->get_curve(); if (c.is_null()) { return; @@ -165,7 +165,7 @@ void Path3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p_cance UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo(); - if (p_id < c->get_point_count()) { + if (!p_secondary) { if (p_cancel) { c->set_point_position(p_id, p_restore); return; @@ -178,7 +178,7 @@ void Path3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p_cance return; } - p_id = p_id - c->get_point_count() + 1; + p_id += 1; // Account for the first point only having an "out" handle int idx = p_id / 2; int t = p_id % 2; diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h index a7da2c07e5..adda648868 100644 --- a/editor/plugins/path_3d_editor_plugin.h +++ b/editor/plugins/path_3d_editor_plugin.h @@ -45,10 +45,10 @@ class Path3DGizmo : public EditorNode3DGizmo { mutable float orig_out_length; public: - virtual String get_handle_name(int p_idx) const override; - virtual Variant get_handle_value(int p_id) const override; - virtual void set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) override; - virtual void commit_handle(int p_id, const Variant &p_restore, bool p_cancel = false) override; + virtual String get_handle_name(int p_id, bool p_secondary) const override; + virtual Variant get_handle_value(int p_id, bool p_secondary) const override; + virtual void set_handle(int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override; + virtual void commit_handle(int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override; virtual void redraw() override; Path3DGizmo(Path3D *p_path = nullptr); diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index e272b96778..c6d1d99c08 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -38,6 +38,8 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "scene/2d/skeleton_2d.h" +#include "scene/gui/scroll_container.h" +#include "scene/gui/view_panner.h" Node2D *Polygon2DEditor::_get_node() const { return node; @@ -63,9 +65,8 @@ int Polygon2DEditor::_get_polygon_count() const { void Polygon2DEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: - case NOTIFICATION_THEME_CHANGED: { - uv_edit_draw->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); - bone_scroll->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + uv_panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int()); } break; case NOTIFICATION_READY: { button_uv->set_icon(get_theme_icon(SNAME("Uv"), SNAME("EditorIcons"))); @@ -88,6 +89,11 @@ void Polygon2DEditor::_notification(int p_what) { uv_vscroll->set_anchors_and_offsets_preset(PRESET_RIGHT_WIDE); uv_hscroll->set_anchors_and_offsets_preset(PRESET_BOTTOM_WIDE); + [[fallthrough]]; + } + case NOTIFICATION_THEME_CHANGED: { + uv_edit_draw->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + bone_scroll->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); } break; case NOTIFICATION_VISIBILITY_CHANGED: { if (!is_visible()) { @@ -440,6 +446,11 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { return; } + if (uv_panner->gui_input(p_input)) { + accept_event(); + return; + } + Transform2D mtx; mtx.elements[2] = -uv_draw_ofs; mtx.scale_basis(Vector2(uv_draw_zoom, uv_draw_zoom)); @@ -767,23 +778,13 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { } uv_edit_draw->update(); - - } else if (mb->get_button_index() == MouseButton::WHEEL_UP && mb->is_pressed()) { - uv_zoom->set_value(uv_zoom->get_value() / (1 - (0.1 * mb->get_factor()))); - } else if (mb->get_button_index() == MouseButton::WHEEL_DOWN && mb->is_pressed()) { - uv_zoom->set_value(uv_zoom->get_value() * (1 - (0.1 * mb->get_factor()))); } } Ref<InputEventMouseMotion> mm = p_input; if (mm.is_valid()) { - if ((mm->get_button_mask() & MouseButton::MASK_MIDDLE) != MouseButton::NONE || Input::get_singleton()->is_key_pressed(Key::SPACE)) { - Vector2 drag = mm->get_relative(); - uv_hscroll->set_value(uv_hscroll->get_value() - drag.x); - uv_vscroll->set_value(uv_vscroll->get_value() - drag.y); - - } else if (uv_drag) { + if (uv_drag) { Vector2 uv_drag_to = mm->get_position(); uv_drag_to = snap_point(uv_drag_to); // FIXME: Only works correctly with 'UV_MODE_EDIT_POINT', it's imprecise with the rest. Vector2 drag = mtx.affine_inverse().xform(uv_drag_to) - mtx.affine_inverse().xform(uv_drag_from); @@ -925,6 +926,23 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { } } +void Polygon2DEditor::_uv_scroll_callback(Vector2 p_scroll_vec) { + _uv_pan_callback(-p_scroll_vec * 32); +} + +void Polygon2DEditor::_uv_pan_callback(Vector2 p_scroll_vec) { + uv_hscroll->set_value(uv_hscroll->get_value() - p_scroll_vec.x); + uv_vscroll->set_value(uv_vscroll->get_value() - p_scroll_vec.y); +} + +void Polygon2DEditor::_uv_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) { + if (p_scroll_vec.y < 0) { + uv_zoom->set_value(uv_zoom->get_value() / (1 - (0.1 * Math::abs(p_scroll_vec.y)))); + } else { + uv_zoom->set_value(uv_zoom->get_value() * (1 - (0.1 * Math::abs(p_scroll_vec.y)))); + } +} + void Polygon2DEditor::_uv_scroll_changed(real_t) { if (updating_uv_scroll) { return; @@ -1262,6 +1280,10 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) : uv_edit_mode[2]->connect("pressed", callable_mp(this, &Polygon2DEditor::_uv_edit_mode_select), varray(2)); uv_edit_mode[3]->connect("pressed", callable_mp(this, &Polygon2DEditor::_uv_edit_mode_select), varray(3)); + uv_panner.instantiate(); + uv_panner->set_callbacks(callable_mp(this, &Polygon2DEditor::_uv_scroll_callback), callable_mp(this, &Polygon2DEditor::_uv_pan_callback), callable_mp(this, &Polygon2DEditor::_uv_zoom_callback)); + uv_panner->set_disable_rmb(true); + uv_mode_hb->add_child(memnew(VSeparator)); uv_main_vb->add_child(uv_mode_hb); diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h index a04179dcad..959c230d7b 100644 --- a/editor/plugins/polygon_2d_editor_plugin.h +++ b/editor/plugins/polygon_2d_editor_plugin.h @@ -32,7 +32,9 @@ #define POLYGON_2D_EDITOR_PLUGIN_H #include "editor/plugins/abstract_polygon_2d_editor.h" -#include "scene/gui/scroll_container.h" + +class ViewPanner; +class ScrollContainer; class Polygon2DEditor : public AbstractPolygon2DEditor { GDCLASS(Polygon2DEditor, AbstractPolygon2DEditor); @@ -78,6 +80,11 @@ class Polygon2DEditor : public AbstractPolygon2DEditor { MenuButton *uv_menu; TextureRect *uv_icon_zoom; + Ref<ViewPanner> uv_panner; + void _uv_scroll_callback(Vector2 p_scroll_vec); + void _uv_pan_callback(Vector2 p_scroll_vec); + void _uv_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin); + VBoxContainer *bone_scroll_main_vb; ScrollContainer *bone_scroll; VBoxContainer *bone_scroll_vb; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 03ed0e0ef2..f1e5e7612b 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1771,6 +1771,7 @@ struct _ScriptEditorItemData { String name; String sort_key; Ref<Texture2D> icon; + bool tool = false; int index = 0; String tooltip; bool used = false; @@ -1894,6 +1895,7 @@ void ScriptEditor::_update_script_colors() { int hist_size = EditorSettings::get_singleton()->get("text_editor/script_list/script_temperature_history_size"); Color hot_color = get_theme_color(SNAME("accent_color"), SNAME("Editor")); + hot_color.set_s(hot_color.get_s() * 0.9); Color cold_color = get_theme_color(SNAME("font_color"), SNAME("Editor")); for (int i = 0; i < script_list->get_item_count(); i++) { @@ -1953,6 +1955,7 @@ void ScriptEditor::_update_script_names() { se->set_meta("_edit_res_path", path); } String name = se->get_name(); + Ref<Script> scr = se->get_edited_resource(); _ScriptEditorItemData sd; sd.icon = icon; @@ -1962,6 +1965,9 @@ void ScriptEditor::_update_script_names() { sd.used = used.has(se->get_edited_resource()); sd.category = 0; sd.ref = se; + if (scr.is_valid()) { + sd.tool = scr->is_tool(); + } switch (sort_by) { case SORT_BY_NAME: { @@ -2081,8 +2087,14 @@ void ScriptEditor::_update_script_names() { } } + Color tool_color = get_theme_color(SNAME("accent_color"), SNAME("Editor")); + tool_color.set_s(tool_color.get_s() * 1.5); for (int i = 0; i < sedata_filtered.size(); i++) { script_list->add_item(sedata_filtered[i].name, sedata_filtered[i].icon); + if (sedata_filtered[i].tool) { + script_list->set_item_icon_modulate(script_list->get_item_count() - 1, tool_color); + } + int index = script_list->get_item_count() - 1; script_list->set_item_tooltip(index, sedata_filtered[i].tooltip); script_list->set_item_metadata(index, sedata_filtered[i].index); /* Saving as metadata the script's index in the tab container and not the filtered one */ diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 97a882c383..ab094f4dc6 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -392,8 +392,17 @@ String ScriptTextEditor::get_name() { } Ref<Texture2D> ScriptTextEditor::get_theme_icon() { - if (get_parent_control() && get_parent_control()->has_theme_icon(script->get_class(), "EditorIcons")) { - return get_parent_control()->get_theme_icon(script->get_class(), "EditorIcons"); + if (get_parent_control()) { + String icon_name = script->get_class(); + if (script->is_built_in()) { + icon_name += "Internal"; + } + + if (get_parent_control()->has_theme_icon(icon_name, "EditorIcons")) { + return get_parent_control()->get_theme_icon(icon_name, "EditorIcons"); + } else if (get_parent_control()->has_theme_icon(script->get_class(), "EditorIcons")) { + return get_parent_control()->get_theme_icon(script->get_class(), "EditorIcons"); + } } return Ref<Texture2D>(); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index e8bbeb0834..afecada1db 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -205,7 +205,7 @@ void ShaderTextEditor::_check_shader_mode() { static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) { RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable); - return RS::global_variable_type_get_shader_datatype(gvt); + return (ShaderLanguage::DataType)RS::global_variable_type_get_shader_datatype(gvt); } void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptCodeCompletionOption> *r_options) { diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h index cc90d381a5..db2d1438b3 100644 --- a/editor/plugins/shader_editor_plugin.h +++ b/editor/plugins/shader_editor_plugin.h @@ -40,7 +40,7 @@ #include "scene/gui/text_edit.h" #include "scene/main/timer.h" #include "scene/resources/shader.h" -#include "servers/rendering/shader_language.h" +#include "servers/rendering/shader_warnings.h" class ShaderTextEditor : public CodeTextEditor { GDCLASS(ShaderTextEditor, CodeTextEditor); diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index c03e55be69..900bf4ef57 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -36,10 +36,6 @@ #include "editor/editor_scale.h" #include "scene/gui/check_box.h" -/** - @author Mariano Suligoy -*/ - void draw_margin_line(Control *edit_draw, Vector2 from, Vector2 to) { Vector2 line = (to - from).normalized() * 10; diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h index 23981ddb81..bffc6fd9bf 100644 --- a/editor/plugins/texture_region_editor_plugin.h +++ b/editor/plugins/texture_region_editor_plugin.h @@ -40,10 +40,6 @@ #include "scene/resources/style_box.h" #include "scene/resources/texture.h" -/** - @author Mariano Suligoy -*/ - class TextureRegionEditor : public VBoxContainer { GDCLASS(TextureRegionEditor, VBoxContainer); diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index c85956991a..24ede3b85e 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/editor/plugins/tiles/tile_atlas_view.cpp @@ -37,57 +37,31 @@ #include "scene/gui/label.h" #include "scene/gui/panel.h" #include "scene/gui/texture_rect.h" +#include "scene/gui/view_panner.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" void TileAtlasView::gui_input(const Ref<InputEvent> &p_event) { - Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid()) { - drag_type = DRAG_TYPE_NONE; - - Vector2i scroll_vec = Vector2((mb->get_button_index() == MouseButton::WHEEL_LEFT) - (mb->get_button_index() == MouseButton::WHEEL_RIGHT), (mb->get_button_index() == MouseButton::WHEEL_UP) - (mb->get_button_index() == MouseButton::WHEEL_DOWN)); - if (scroll_vec != Vector2()) { - if (mb->is_ctrl_pressed()) { - if (mb->is_shift_pressed()) { - panning.x += 32 * mb->get_factor() * scroll_vec.y; - panning.y += 32 * mb->get_factor() * scroll_vec.x; - } else { - panning.y += 32 * mb->get_factor() * scroll_vec.y; - panning.x += 32 * mb->get_factor() * scroll_vec.x; - } - - emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning); - _update_zoom_and_panning(true); - accept_event(); + if (panner->gui_input(p_event)) { + accept_event(); + } +} - } else if (!mb->is_shift_pressed()) { - zoom_widget->set_zoom_by_increments(scroll_vec.y * 2); - emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning); - _update_zoom_and_panning(true); - accept_event(); - } - } +void TileAtlasView::_scroll_callback(Vector2 p_scroll_vec) { + _pan_callback(-p_scroll_vec * 32); +} - if (mb->get_button_index() == MouseButton::MIDDLE || mb->get_button_index() == MouseButton::RIGHT) { - if (mb->is_pressed()) { - drag_type = DRAG_TYPE_PAN; - } else { - drag_type = DRAG_TYPE_NONE; - } - accept_event(); - } - } +void TileAtlasView::_pan_callback(Vector2 p_scroll_vec) { + panning += p_scroll_vec; + emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning); + _update_zoom_and_panning(true); +} - Ref<InputEventMouseMotion> mm = p_event; - if (mm.is_valid()) { - if (drag_type == DRAG_TYPE_PAN) { - panning += mm->get_relative(); - _update_zoom_and_panning(); - emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning); - accept_event(); - } - } +void TileAtlasView::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) { + zoom_widget->set_zoom_by_increments(-p_scroll_vec.y * 2); + emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning); + _update_zoom_and_panning(true); } Size2i TileAtlasView::_compute_base_tiles_control_size() { @@ -548,6 +522,11 @@ void TileAtlasView::update() { void TileAtlasView::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: + panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int()); + break; + case NOTIFICATION_READY: button_center_view->set_icon(get_theme_icon(SNAME("CenterView"), SNAME("EditorIcons"))); break; @@ -561,6 +540,9 @@ void TileAtlasView::_bind_methods() { TileAtlasView::TileAtlasView() { set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); + panner.instantiate(); + panner->set_callbacks(callable_mp(this, &TileAtlasView::_scroll_callback), callable_mp(this, &TileAtlasView::_pan_callback), callable_mp(this, &TileAtlasView::_zoom_callback)); + Panel *panel = memnew(Panel); panel->set_clip_contents(true); panel->set_mouse_filter(Control::MOUSE_FILTER_IGNORE); diff --git a/editor/plugins/tiles/tile_atlas_view.h b/editor/plugins/tiles/tile_atlas_view.h index ca7f083132..6a0e0ae820 100644 --- a/editor/plugins/tiles/tile_atlas_view.h +++ b/editor/plugins/tiles/tile_atlas_view.h @@ -41,6 +41,8 @@ #include "scene/gui/texture_rect.h" #include "scene/resources/tile_set.h" +class ViewPanner; + class TileAtlasView : public Control { GDCLASS(TileAtlasView, Control); @@ -64,6 +66,11 @@ private: void _center_view(); virtual void gui_input(const Ref<InputEvent> &p_event) override; + Ref<ViewPanner> panner; + void _scroll_callback(Vector2 p_scroll_vec); + void _pan_callback(Vector2 p_scroll_vec); + void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin); + Map<Vector2, Map<int, Rect2i>> alternative_tiles_rect_cache; void _update_alternative_tiles_rect_cache(); diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp index 73fd62d2c4..d5c2051f31 100644 --- a/editor/plugins/tiles/tile_data_editors.cpp +++ b/editor/plugins/tiles/tile_data_editors.cpp @@ -1148,6 +1148,7 @@ void TileDataDefaultEditor::setup_property_editor(Variant::Type p_type, String p property_editor->set_label(p_label); } property_editor->connect("property_changed", callable_mp(this, &TileDataDefaultEditor::_property_value_changed).unbind(1)); + property_editor->set_tooltip(p_property); property_editor->update_property(); add_child(property_editor); } @@ -1325,6 +1326,15 @@ void TileDataCollisionEditor::_property_value_changed(StringName p_property, Var dummy_object->set(p_property, p_value); } +void TileDataCollisionEditor::_property_selected(StringName p_path, int p_focusable) { + // Deselect all other properties + for (KeyValue<StringName, EditorProperty *> &editor : property_editors) { + if (editor.key != p_path) { + editor.value->deselect(); + } + } +} + void TileDataCollisionEditor::_polygons_changed() { // Update the dummy object properties and their editors. for (int i = 0; i < polygon_editor->get_polygon_count(); i++) { @@ -1346,6 +1356,8 @@ void TileDataCollisionEditor::_polygons_changed() { one_way_property_editor->set_object_and_property(dummy_object, one_way_property); one_way_property_editor->set_label(one_way_property); one_way_property_editor->connect("property_changed", callable_mp(this, &TileDataCollisionEditor::_property_value_changed).unbind(1)); + one_way_property_editor->connect("selected", callable_mp(this, &TileDataCollisionEditor::_property_selected)); + one_way_property_editor->set_tooltip(one_way_property_editor->get_edited_property()); one_way_property_editor->update_property(); add_child(one_way_property_editor); property_editors[one_way_property] = one_way_property_editor; @@ -1356,6 +1368,8 @@ void TileDataCollisionEditor::_polygons_changed() { one_way_margin_property_editor->set_object_and_property(dummy_object, one_way_margin_property); one_way_margin_property_editor->set_label(one_way_margin_property); one_way_margin_property_editor->connect("property_changed", callable_mp(this, &TileDataCollisionEditor::_property_value_changed).unbind(1)); + one_way_margin_property_editor->connect("selected", callable_mp(this, &TileDataCollisionEditor::_property_selected)); + one_way_margin_property_editor->set_tooltip(one_way_margin_property_editor->get_edited_property()); one_way_margin_property_editor->update_property(); add_child(one_way_margin_property_editor); property_editors[one_way_margin_property] = one_way_margin_property_editor; @@ -1515,6 +1529,8 @@ TileDataCollisionEditor::TileDataCollisionEditor() { linear_velocity_editor->set_object_and_property(dummy_object, "linear_velocity"); linear_velocity_editor->set_label("linear_velocity"); linear_velocity_editor->connect("property_changed", callable_mp(this, &TileDataCollisionEditor::_property_value_changed).unbind(1)); + linear_velocity_editor->connect("selected", callable_mp(this, &TileDataCollisionEditor::_property_selected)); + linear_velocity_editor->set_tooltip(linear_velocity_editor->get_edited_property()); linear_velocity_editor->update_property(); add_child(linear_velocity_editor); property_editors["linear_velocity"] = linear_velocity_editor; @@ -1523,6 +1539,8 @@ TileDataCollisionEditor::TileDataCollisionEditor() { angular_velocity_editor->set_object_and_property(dummy_object, "angular_velocity"); angular_velocity_editor->set_label("angular_velocity"); angular_velocity_editor->connect("property_changed", callable_mp(this, &TileDataCollisionEditor::_property_value_changed).unbind(1)); + angular_velocity_editor->connect("selected", callable_mp(this, &TileDataCollisionEditor::_property_selected)); + angular_velocity_editor->set_tooltip(angular_velocity_editor->get_edited_property()); angular_velocity_editor->update_property(); add_child(angular_velocity_editor); property_editors["angular_velocity"] = angular_velocity_editor; @@ -2492,6 +2510,7 @@ TileDataTerrainsEditor::TileDataTerrainsEditor() { terrain_set_property_editor->set_object_and_property(dummy_object, "terrain_set"); terrain_set_property_editor->set_label("Terrain Set"); terrain_set_property_editor->connect("property_changed", callable_mp(this, &TileDataTerrainsEditor::_property_value_changed).unbind(1)); + terrain_set_property_editor->set_tooltip(terrain_set_property_editor->get_edited_property()); add_child(terrain_set_property_editor); terrain_property_editor = memnew(EditorPropertyEnum); diff --git a/editor/plugins/tiles/tile_data_editors.h b/editor/plugins/tiles/tile_data_editors.h index b45eb9530b..e4551d3302 100644 --- a/editor/plugins/tiles/tile_data_editors.h +++ b/editor/plugins/tiles/tile_data_editors.h @@ -306,6 +306,7 @@ class TileDataCollisionEditor : public TileDataDefaultEditor { Map<StringName, EditorProperty *> property_editors; void _property_value_changed(StringName p_property, Variant p_value, StringName p_field); + void _property_selected(StringName p_path, int p_focusable); void _polygons_changed(); virtual Variant _get_painted_value() override; diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp index f99fcb3675..cdde22f5bc 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.cpp +++ b/editor/plugins/tiles/tiles_editor_plugin.cpp @@ -113,7 +113,7 @@ void TilesEditorPlugin::_thread() { tile_map->set_scale(scale); tile_map->set_position(-(scale * encompassing_rect.get_center()) + thumbnail_size2 / 2); - // Add the viewport at the lasst moment to avoid rendering too early. + // Add the viewport at the last moment to avoid rendering too early. EditorNode::get_singleton()->add_child(viewport); RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<TilesEditorPlugin *>(this), &TilesEditorPlugin::_preview_frame_started), Vector<Variant>(), Object::CONNECT_ONESHOT); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 03797b1797..f05ff72e5d 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -2445,6 +2445,14 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_pa vsnode->set_script(add_options[p_idx].script); } + bool is_texture2d = (Object::cast_to<VisualShaderNodeTexture>(vsnode.ptr()) != nullptr); + bool is_texture3d = (Object::cast_to<VisualShaderNodeTexture3D>(vsnode.ptr()) != nullptr); + bool is_texture2d_array = (Object::cast_to<VisualShaderNodeTexture2DArray>(vsnode.ptr()) != nullptr); + bool is_cubemap = (Object::cast_to<VisualShaderNodeCubemap>(vsnode.ptr()) != nullptr); + bool is_curve = (Object::cast_to<VisualShaderNodeCurveTexture>(vsnode.ptr()) != nullptr); + bool is_curve_xyz = (Object::cast_to<VisualShaderNodeCurveXYZTexture>(vsnode.ptr()) != nullptr); + bool is_uniform = (Object::cast_to<VisualShaderNodeUniform>(vsnode.ptr()) != nullptr); + Point2 position = graph->get_scroll_ofs(); if (saved_node_pos_dirty) { @@ -2570,23 +2578,32 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_pa } } } + + if (output_port_type == VisualShaderNode::PORT_TYPE_SAMPLER) { + if (is_texture2d) { + undo_redo->add_do_method(vsnode.ptr(), "set_source", VisualShaderNodeTexture::SOURCE_PORT); + } + if (is_texture3d || is_texture2d_array) { + undo_redo->add_do_method(vsnode.ptr(), "set_source", VisualShaderNodeSample3D::SOURCE_PORT); + } + if (is_cubemap) { + undo_redo->add_do_method(vsnode.ptr(), "set_source", VisualShaderNodeCubemap::SOURCE_PORT); + } + } } } _member_cancel(); - VisualShaderNodeUniform *uniform = Object::cast_to<VisualShaderNodeUniform>(vsnode.ptr()); - if (uniform) { + if (is_uniform) { undo_redo->add_do_method(this, "_update_uniforms", true); undo_redo->add_undo_method(this, "_update_uniforms", true); } - VisualShaderNodeCurveTexture *curve = Object::cast_to<VisualShaderNodeCurveTexture>(vsnode.ptr()); - if (curve) { + if (is_curve) { graph_plugin->call_deferred(SNAME("update_curve"), id_to_use); } - VisualShaderNodeCurveXYZTexture *curve_xyz = Object::cast_to<VisualShaderNodeCurveXYZTexture>(vsnode.ptr()); - if (curve_xyz) { + if (is_curve_xyz) { graph_plugin->call_deferred(SNAME("update_curve_xyz"), id_to_use); } @@ -2595,22 +2612,17 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_pa } else { //post-initialization - VisualShaderNodeTexture *texture2d = Object::cast_to<VisualShaderNodeTexture>(vsnode.ptr()); - VisualShaderNodeTexture3D *texture3d = Object::cast_to<VisualShaderNodeTexture3D>(vsnode.ptr()); - - if (texture2d || texture3d || curve || curve_xyz) { + if (is_texture2d || is_texture3d || is_curve || is_curve_xyz) { undo_redo->add_do_method(vsnode.ptr(), "set_texture", ResourceLoader::load(p_resource_path)); return; } - VisualShaderNodeCubemap *cubemap = Object::cast_to<VisualShaderNodeCubemap>(vsnode.ptr()); - if (cubemap) { + if (is_cubemap) { undo_redo->add_do_method(vsnode.ptr(), "set_cube_map", ResourceLoader::load(p_resource_path)); return; } - VisualShaderNodeTexture2DArray *texture2d_array = Object::cast_to<VisualShaderNodeTexture2DArray>(vsnode.ptr()); - if (texture2d_array) { + if (is_texture2d_array) { undo_redo->add_do_method(vsnode.ptr(), "set_texture_array", ResourceLoader::load(p_resource_path)); } } @@ -3209,6 +3221,10 @@ void VisualShaderEditor::_notification(int p_what) { } } + if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { + graph->set_panning_scheme((GraphEdit::PanningScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int()); + } + if (p_what == NOTIFICATION_DRAG_BEGIN) { Dictionary dd = get_viewport()->gui_get_drag_data(); if (members->is_visible_in_tree() && dd.has("id")) { @@ -3910,7 +3926,7 @@ void VisualShaderEditor::_preview_size_changed() { static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) { RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable); - return RS::global_variable_type_get_shader_datatype(gvt); + return (ShaderLanguage::DataType)RS::global_variable_type_get_shader_datatype(gvt); } void VisualShaderEditor::_update_preview() { @@ -5260,21 +5276,26 @@ Size2 VisualShaderNodePortPreview::get_minimum_size() const { void VisualShaderNodePortPreview::_notification(int p_what) { if (p_what == NOTIFICATION_DRAW) { - Vector<Vector2> points; - Vector<Vector2> uvs; - Vector<Color> colors; - points.push_back(Vector2()); - uvs.push_back(Vector2(0, 0)); - colors.push_back(Color(1, 1, 1, 1)); - points.push_back(Vector2(get_size().width, 0)); - uvs.push_back(Vector2(1, 0)); - colors.push_back(Color(1, 1, 1, 1)); - points.push_back(get_size()); - uvs.push_back(Vector2(1, 1)); - colors.push_back(Color(1, 1, 1, 1)); - points.push_back(Vector2(0, get_size().height)); - uvs.push_back(Vector2(0, 1)); - colors.push_back(Color(1, 1, 1, 1)); + Vector<Vector2> points = { + Vector2(), + Vector2(get_size().width, 0), + get_size(), + Vector2(0, get_size().height) + }; + + Vector<Vector2> uvs = { + Vector2(0, 0), + Vector2(1, 0), + Vector2(1, 1), + Vector2(0, 1) + }; + + Vector<Color> colors = { + Color(1, 1, 1, 1), + Color(1, 1, 1, 1), + Color(1, 1, 1, 1), + Color(1, 1, 1, 1) + }; draw_primitive(points, colors, uvs); } diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index b710eb2546..1bf6243bcc 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -275,10 +275,8 @@ void ProjectSettingsEditor::_editor_restart_close() { void ProjectSettingsEditor::_action_added(const String &p_name) { String name = "input/" + p_name; - if (ProjectSettings::get_singleton()->has_setting(name)) { - action_map->show_message(vformat(TTR("An action with the name '%s' already exists."), name)); - return; - } + ERR_FAIL_COND_MSG(ProjectSettings::get_singleton()->has_setting(name), + "An action with this name already exists."); Dictionary action; action["events"] = Array(); @@ -351,10 +349,8 @@ void ProjectSettingsEditor::_action_renamed(const String &p_old_name, const Stri const String old_property_name = "input/" + p_old_name; const String new_property_name = "input/" + p_new_name; - if (ProjectSettings::get_singleton()->has_setting(new_property_name)) { - action_map->show_message(vformat(TTR("An action with the name '%s' already exists."), new_property_name)); - return; - } + ERR_FAIL_COND_MSG(ProjectSettings::get_singleton()->has_setting(new_property_name), + "An action with this name already exists."); int order = ProjectSettings::get_singleton()->get_order(old_property_name); Dictionary action = ProjectSettings::get_singleton()->get(old_property_name); diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp index 0e34d200f2..20845b0e9d 100644 --- a/editor/rename_dialog.cpp +++ b/editor/rename_dialog.cpp @@ -527,7 +527,7 @@ String RenameDialog::_postprocess(const String &subject) { // To Lowercase result = result.to_lower(); } else if (case_id == 2) { - // To Upercase + // To Uppercase result = result.to_upper(); } diff --git a/editor/rename_dialog.h b/editor/rename_dialog.h index 7a882dc693..9d02fb10bd 100644 --- a/editor/rename_dialog.h +++ b/editor/rename_dialog.h @@ -41,10 +41,6 @@ #include "scene/gui/option_button.h" #include "scene/gui/spin_box.h" -/** -@author Blazej Floch -*/ - class RenameDialog : public ConfirmationDialog { GDCLASS(RenameDialog, ConfirmationDialog); diff --git a/editor/reparent_dialog.h b/editor/reparent_dialog.h index 3d76eb3294..981829a871 100644 --- a/editor/reparent_dialog.h +++ b/editor/reparent_dialog.h @@ -37,9 +37,7 @@ #include "scene/gui/check_button.h" #include "scene/gui/dialogs.h" #include "scene/gui/line_edit.h" -/** -@author Juan Linietsky <reduzio@gmail.com> -*/ + class ReparentDialog : public ConfirmationDialog { GDCLASS(ReparentDialog, ConfirmationDialog); @@ -60,4 +58,4 @@ public: ~ReparentDialog(); }; -#endif +#endif // REPARENT_DIALOG_H diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 7e72777da1..2e72b17651 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -2721,6 +2721,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { menu->add_icon_shortcut(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW); menu->add_icon_shortcut(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANTIATE); } + menu->add_icon_shortcut(get_theme_icon(SNAME("Collapse"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/expand_collapse_all"), TOOL_EXPAND_COLLAPSE); menu->add_separator(); existing_script = selected->get_script(); @@ -2861,7 +2862,6 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { void SceneTreeDock::_open_tree_menu() { menu->clear(); - menu->add_icon_shortcut(get_theme_icon(SNAME("Collapse"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/expand_collapse_all"), TOOL_EXPAND_COLLAPSE); menu->add_check_item(TTR("Auto Expand to Selected"), TOOL_AUTO_EXPAND); menu->set_item_checked(menu->get_item_idx_from_text(TTR("Auto Expand to Selected")), EditorSettings::get_singleton()->get("docks/scene_tree/auto_expand_to_selected")); @@ -3260,7 +3260,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel ED_SHORTCUT("scene_tree/add_child_node", TTR("Add Child Node"), KeyModifierMask::CMD | Key::A); ED_SHORTCUT("scene_tree/instance_scene", TTR("Instantiate Child Scene"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::A); - ED_SHORTCUT("scene_tree/expand_collapse_all", TTR("Expand/Collapse All")); + ED_SHORTCUT("scene_tree/expand_collapse_all", TTR("Expand/Collapse Branch")); ED_SHORTCUT("scene_tree/cut_node", TTR("Cut"), KeyModifierMask::CMD | Key::X); ED_SHORTCUT("scene_tree/copy_node", TTR("Copy"), KeyModifierMask::CMD | Key::C); ED_SHORTCUT("scene_tree/paste_node", TTR("Paste"), KeyModifierMask::CMD | Key::V); diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp index f97ffcae65..2f3867a58c 100644 --- a/editor/shader_globals_editor.cpp +++ b/editor/shader_globals_editor.cpp @@ -30,6 +30,7 @@ #include "shader_globals_editor.h" #include "editor_node.h" +#include "servers/rendering/shader_language.h" static const char *global_var_type_names[RS::GLOBAL_VAR_TYPE_MAX] = { "bool", diff --git a/editor/translations/af.po b/editor/translations/af.po index fb80e360f9..f139124259 100644 --- a/editor/translations/af.po +++ b/editor/translations/af.po @@ -373,6 +373,7 @@ msgstr "Skep %d NUWE bane en voeg sleutels by?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -853,6 +854,7 @@ msgstr "Voeg By" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -904,8 +906,7 @@ msgstr "Koppel tans Sein:" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -2005,7 +2006,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Verfris" @@ -2128,7 +2128,8 @@ msgstr "Gidse & Lêers:" msgid "Preview:" msgstr "Voorskou:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Lêer:" @@ -2316,7 +2317,7 @@ msgstr "Metodes" msgid "Signal" msgstr "Seine" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Konstant" @@ -2348,6 +2349,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -3056,7 +3059,7 @@ msgstr "" #: editor/editor_node.cpp #, fuzzy -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "Projek Stigters" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3194,11 +3197,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -#, fuzzy -msgid "Toggle System Console" -msgstr "Wissel Modus" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3419,6 +3417,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3500,7 +3499,6 @@ msgid "Author" msgstr "Outeurs" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3729,6 +3727,12 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Fout terwyl laai:" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4645,6 +4649,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6375,6 +6380,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9839,7 +9845,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9847,7 +9853,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9855,10 +9866,41 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "Verander Skikking Waarde-Soort" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Verander Skikking Waarde-Soort" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Herset Zoem" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -9867,7 +9909,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Skuif Gunsteling Op" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Nodus Naam:" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9876,52 +9948,141 @@ msgid "Detect new changes" msgstr "Skep Nuwe" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Discard all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Changes" -msgstr "Verander Skikking Waarde-Soort" +msgid "Stage all changes" +msgstr "Plaaslike veranderinge word gebêre..." #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +#, fuzzy +msgid "Unstage all changes" +msgstr "Plaaslike veranderinge word gebêre..." + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit List" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "Nodus Naam:" +msgid "Branches" +msgstr "Passendes:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "Skrap" +msgid "Create New Branch" +msgstr "Skep Nuwe" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +#, fuzzy +msgid "Remove Branch" +msgstr "Verwyder Anim Baan" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "Skaal Seleksie" +msgid "Remotes" +msgstr "Verwyder" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "Vervang Alles" +msgid "Create New Remote" +msgstr "Skep Nuwe" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" +#, fuzzy +msgid "Remove Remote" +msgstr "Verwyder Seleksie" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Nodus Naam:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Verwyder" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Pull" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "Nodus Naam:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "Skrap" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "View:" +msgstr "Voorskou:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Split" +msgstr "Wysig Nodus Kurwe" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12516,6 +12677,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13377,6 +13539,39 @@ msgstr "Verfris" msgid "Edit Member" msgstr "Lede" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Animasie Zoem." + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -13389,6 +13584,82 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Skep Vouer" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Geldige karakters:" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -13405,6 +13676,20 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Maak Funksie" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Herskaleer Skikking" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -13414,6 +13699,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -13422,6 +13711,61 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Skrap" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Skep Vouer" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Anim Dupliseer Sleutels" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -13431,13 +13775,70 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Konstantes" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Alle Seleksie" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp #, fuzzy msgid "Search VisualScript" msgstr "Deursoek Hulp" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Skuif Byvoeg Sleutel" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Seine" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Seine" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -14024,7 +14425,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14237,7 +14647,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/ar.po b/editor/translations/ar.po index 406f882df8..37c6d1943e 100644 --- a/editor/translations/ar.po +++ b/editor/translations/ar.po @@ -34,7 +34,7 @@ # Ahmed Shahwan <dev.ahmed.shahwan@gmail.com>, 2019. # hshw <shw@tutanota.com>, 2020. # Youssef Harmal <the.coder.crab@gmail.com>, 2020. -# Nabeel20 <nabeelandnizam@gmail.com>, 2020, 2021. +# Nabeel20 <nabeelandnizam@gmail.com>, 2020, 2021, 2022. # merouche djallal <kbordora@gmail.com>, 2020. # Airbus5717 <Abdussamadf350@gmail.com>, 2020. # tamsamani mohamed <tamsmoha@gmail.com>, 2020. @@ -56,14 +56,14 @@ # Hafid Talbi <atalbiie@gmail.com>, 2021. # Hareth Mohammed <harethpy@gmail.com>, 2021. # Mohammed Mubarak <modymu9@gmail.com>, 2021. -# Spirit <i8bou3@gmail.com>, 2021. +# Spirit <i8bou3@gmail.com>, 2021, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-01-03 03:54+0000\n" -"Last-Translator: HASSAN GAMER - ØØ³Ù† جيمر <gamerhassan55@gmail.com>\n" +"PO-Revision-Date: 2022-01-12 16:52+0000\n" +"Last-Translator: Nabeel20 <nabeelandnizam@gmail.com>\n" "Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/" "godot/ar/>\n" "Language: ar\n" @@ -413,6 +413,7 @@ msgstr "أنشئ %d مسارات جديدة Ùˆ أدخل Ù…ÙØ§ØªÙŠØØŸ" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -877,6 +878,7 @@ msgstr "أضÙ" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -926,8 +928,7 @@ msgstr "إشارة غير قادر على الاتصال" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1985,7 +1986,6 @@ msgid "New Folder..." msgstr "مجلد جديد..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "ØªØØ¯ÙŠØ«" @@ -2102,7 +2102,8 @@ msgstr "الوجهات ÙˆØ§Ù„Ù…Ù„ÙØ§Øª:" msgid "Preview:" msgstr "إستعراض:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "الملÙ:" @@ -2279,7 +2280,7 @@ msgstr "دالة" msgid "Signal" msgstr "الإشاراة" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "ثابت" @@ -2310,6 +2311,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "ØªØØ¯ÙŠØ¯ %s" @@ -2387,7 +2390,7 @@ msgstr "أعلى" #: editor/editor_network_profiler.cpp editor/editor_node.cpp msgid "Node" -msgstr "عقدة" +msgstr "ÙˆØØ¯Ø©" #: editor/editor_network_profiler.cpp msgid "Incoming RPC" @@ -2895,7 +2898,7 @@ msgstr "Ù…Ø³Ø Ø§Ù„Ù…Ø®Ø·Ø·" #: editor/editor_node.cpp editor/import_dock.cpp #: editor/script_create_dialog.cpp msgid "Default" -msgstr "Ø§Ù„Ø¥ÙØªØ±Ø§Ø¶ÙŠ" +msgstr "Ø§ÙØªØ±Ø§Ø¶ÙŠ" #: editor/editor_node.cpp editor/editor_resource_picker.cpp #: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp @@ -3062,8 +3065,9 @@ msgid "Install Android Build Template..." msgstr "تØÙ…يل قالب البناء للأندرويد..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "ÙØªØ مجلد بيانات المشروع" +#, fuzzy +msgid "Open User Data Folder" +msgstr "ÙØªØ مجلّد بيانات Ø§Ù„Ù…ØØ±Ù‘ر" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3222,10 +3226,6 @@ msgid "Toggle Fullscreen" msgstr "ØªÙØ¹ÙŠÙ„/إلغاء وضع الشاشة الكاملة" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "إظهار/Ø¥Ø®ÙØ§Ø¡ ÙˆØØ¯Ø© التØÙƒÙ… بالنظام" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "ÙØªØ مجلّد بيانات/إعدادات Ø§Ù„Ù…ØØ±Ù‘ر" @@ -3457,6 +3457,7 @@ msgid "Load Errors" msgstr "خطأ تØÙ…يل" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "ØØ¯Ø¯" @@ -3535,7 +3536,6 @@ msgid "Author" msgstr "المالك" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Ø§Ù„ØØ§Ù„Ø©" @@ -3775,6 +3775,12 @@ msgstr "المسار للمشهد:" msgid "Import From Node:" msgstr "إستيراد من عقدة:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "خطأ" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "Ø§ÙØªØ المجلد Ø§Ù„ØØ§ÙˆÙŠ Ù‡Ø°Ù‡ القوالب." @@ -4680,6 +4686,7 @@ msgid "Subfolder:" msgstr "المجلد Ø§Ù„ÙØ±Ø¹ÙŠ:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "المالك:" @@ -6395,6 +6402,7 @@ msgid "Zoom to 1600%" msgstr "التكبير ØØªÙ‰ 1600%" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "أض٠%s" @@ -9883,7 +9891,8 @@ msgid "TileSet" msgstr "Ù…ÙØØ¯Ø¯ البلاط" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "لا يوجد Ø¥Ø¶Ø§ÙØ§Øª VCS Ù…ØªÙˆØ§ÙØ±Ø©." #: editor/plugins/version_control_editor_plugin.cpp @@ -9891,16 +9900,56 @@ msgid "Error" msgstr "خطأ" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "لم يتم Ø¥Ø¶Ø§ÙØ© Ù…Ù„ÙØ§Øª إلى المرØÙ„Ø©" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "لا أسم Ù…Ùقدم." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "ارتكاب" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "لم يتم تهيئة Ø¥Ø¶Ø§ÙØ§Øª VCS" +#, fuzzy +msgid "Staged Changes" +msgstr "تغيرات Ø§Ù„Ù…ÙØ¸Ù„Ù„" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "تغيرات Ø§Ù„Ù…ÙØ¸Ù„Ù„" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "ارتكاب" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "الشجرة Ø§Ù„ÙØ±Ø¹ÙŠØ©" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "هل أنت واثق من ÙØªØ أكثر من مشروع؟" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "طَبق إعادة تعيين" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9911,16 +9960,148 @@ msgid "Initialize" msgstr "الشروع" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "ØÙŠØ² التدريج" +#, fuzzy +msgid "Remote Login" +msgstr "Ù…Ø³Ø Ø§Ù„Ù†Ù‚Ø·Ø©" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "إعادة التسمية" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "الكش٠عن التغيرات الجديدة" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "التغيرات" +#, fuzzy +msgid "Discard all changes" +msgstr "الإغلاق مع ØÙظ التعديلات؟" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "جاري تخزين التعديلات المØÙ„ية..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "ØªÙØºÙŠØ±Ø§Øª المادة" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "اقترا٠التعديلا" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "اقترا٠التعديلا" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "ارتكاب" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "يطابق:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "إنشاء مشروع جديد" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "ØØ°Ù مسار Ø§Ù„ØªØØ±ÙŠÙƒ" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "عن بعد" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "إنشاء مشروع جديد" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "إزالة عنصر" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "من بعد " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "من بعد " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "الميش المصدر:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9939,28 +10120,23 @@ msgid "Typechange" msgstr "تعديل النوع" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "ØÙددت المرØÙ„Ø©" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "Ù…ÙØ¬Ù…Ù„ المراØÙ„" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "اقترا٠التعديلا" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "إظهار آخر تعديلات المل٠قبل قبولهم ÙÙŠ آخر نسخة" +#, fuzzy +msgid "View:" +msgstr "أظهر" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "لا Ù…Ù„Ù ÙØ±ÙˆÙ‚ نشط" +#, fuzzy +msgid "Split" +msgstr "ÙØµÙ„ المسار" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "الكش٠عن التغييرات ÙÙŠ Ù…Ù„Ù Ø§Ù„ÙØ±ÙˆÙ‚" +#, fuzzy +msgid "Unified" +msgstr "Ù…ÙØ¹Ø¯Ù‘Ù„" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12666,6 +12842,7 @@ msgid "Export list to a CSV file" msgstr "تصدير القائمة إلى مل٠CSV" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "مسار المورد" @@ -13524,6 +13701,40 @@ msgstr "ØªØØ¯ÙŠØ« الرسم البياني" msgid "Edit Member" msgstr "تعديل العضو" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "ØªØØ¯ÙŠØ¯ التعبير" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "رسوم Ù…ØªØØ±ÙƒØ©" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "نوع الإدخال غير متوقع: " @@ -13536,6 +13747,88 @@ msgstr "Ø£ØµØ¨Ø Ø§Ù„Ù…Ùكرر غير ØµØ§Ù„ØØ§Ù‹" msgid "Iterator became invalid: " msgstr "Ø£ØµØ¨Ø Ø§Ù„Ù…Ùكرر غير ØµØ§Ù„ØØ§Ù‹: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "إعادة تسمية مجلد:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "ØØ¯Ù‘Ø©" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "نوع:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "ذاتي" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "عند Ø§Ù„ØØ±Ù %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "أض٠%s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "ØªØØ¯ÙŠØ¯ %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "أض٠%s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "جلب %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "اسم خاصية المؤشر index property غير صالØ." @@ -13552,6 +13845,21 @@ msgstr "لا يؤدي المسار للوصول لعÙقدة!" msgid "Invalid index property name '%s' in node %s." msgstr "اسم خاصية المؤشر \"الÙهرس\" '%s' ÙÙŠ العÙقدة %s غير صالØ." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "ØªØØ¯ÙŠØ¯ %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "الوظائ٠البرمجية" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "تغيير ØØ¬Ù… المصÙÙˆÙØ©" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": معامل النوع غير صØÙŠØ: " @@ -13561,6 +13869,10 @@ msgid ": Invalid arguments: " msgstr ": معاملات غير ØµØ§Ù„ØØ©: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "لم يتم إيجاد VariableGet ÙÙŠ النص البرمجي: " @@ -13569,6 +13881,66 @@ msgid "VariableSet not found in script: " msgstr "لم يتم إيجاد (Ù…ÙØØ¯Ø¯ Ø§Ù„Ù…ÙØªØºÙŠØ±) VariableSet ÙÙŠ النص البرمجي: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "إعادة تØÙ…يل" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "ترتيبية المØÙˆØ± Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "ترتيبية المØÙˆØ± Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "ثابت" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "ثابت" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "ثابت" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "ثابت" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "تمكين نمط البرمجة Singleton Ù„ GDNative" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "عقدة التنقل الزمني" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "تعديل شجرة المشهد" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "ذاتي" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "قص العÙقد" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "العقدة المخصصة لا ØªØØªÙˆÙŠ Ø·Ø±ÙŠÙ‚Ø© ()step_ ØŒ لا يمكن معالجة الشكل البياني." @@ -13580,13 +13952,75 @@ msgstr "" "القيمة Ø§Ù„Ù…ÙØ±Ø¬Ø¹Ø© من _step() غير ØµØ§Ù„ØØ©ØŒ ينبغي أن تكون رقماً (تسلسل)ØŒ أو نصاً " "(خطأ)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "إستدعاءات" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "ثوابت" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "استخدام الØÙŠÙ‘ز المØÙ„ÙŠ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "استخدام الØÙŠÙ‘ز المØÙ„ÙŠ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "إجراء" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Ø¨ØØ« VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "جلب %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "ØªØØ±ÙŠÙƒ الإطار" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "نسبة الإطار الÙيزيائي %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "الإشاراة" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "الإشاراة" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "كائن" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14265,16 +14699,26 @@ msgstr "" "خلÙية-المنظر ParallaxBackground." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "لا يدعم برنامج تشغيل الÙيديو GLES2 الجسيمات القائمة على ÙˆØØ¯Ø© معالجة الرسومات " "(GPU-based particles).\n" "استخدم عقدة جسيمات-ÙˆØØ¯Ø©-المعالجة-المركزية-ثنائية-Ø§Ù„Ø¨ÙØ¹Ø¯ (CPUParticles2D) بدلاً " "من ذلك. يمكنك استخدام خيار \"التØÙˆÙŠÙ„ إلى CPUParticles\" لهذا الغرض." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14541,10 +14985,11 @@ msgid "Only uniform scales are supported." msgstr "المعايير Ø§Ù„Ù…ÙˆØØ¯Ø© هي المدعومة Ùقط." #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "الجسيمات القائمة على ÙˆØØ¯Ø© معالجة الرسومات (GPU-based particles) لا تدعم " "برنامج تشغيل الÙيديو GLES2 .\n" @@ -14553,6 +14998,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "لا يوجد شيء مرئي لأن المجسمات لم يتم تعيين لها رسم التمريرات." diff --git a/editor/translations/az.po b/editor/translations/az.po index bc7f45ca0f..5aecfb0e5f 100644 --- a/editor/translations/az.po +++ b/editor/translations/az.po @@ -379,6 +379,7 @@ msgstr "%d YENİ izlÉ™r yarat vÉ™ açarları daxil et?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -861,6 +862,7 @@ msgstr "ÆlavÉ™ Et" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -912,8 +914,7 @@ msgstr "Siqnala baÄŸlana bilmir" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1963,7 +1964,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2080,7 +2080,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2248,7 +2249,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2278,6 +2279,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2974,7 +2977,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3109,10 +3112,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3330,6 +3329,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3407,7 +3407,6 @@ msgid "Author" msgstr "MüəlliflÉ™r" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3634,6 +3633,11 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +msgid "%s Error" +msgstr "" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4494,6 +4498,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6148,6 +6153,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9441,7 +9447,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9449,7 +9455,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9457,10 +9468,41 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "DÉ™yiÅŸdir" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Æminsinizmi ki, bütün É™laqÉ™lÉ™ri bu siqnaldan çıxartmaq istÉ™yirsiniz?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Sıfırla" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -9469,39 +9511,56 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "SÉ™hv açarları sil" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Username" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect new changes" +msgid "SSH Public Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Select SSH public key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "SSH Private Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +msgid "Select SSH private key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Detect new changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Discard all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Stage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +msgid "Unstage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Commit Message" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9509,15 +9568,114 @@ msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Commit List" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "UyÄŸunlaÅŸmalar:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Yeni %s yarat" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Animasya İzini Sil" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +#, fuzzy +msgid "Remotes" +msgstr "Sil" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Yeni %s yarat" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Sil" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Sil" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12028,6 +12186,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12859,6 +13018,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Animasiyanı TÉ™mizlÉ™mÉ™" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12871,6 +13063,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12887,6 +13153,20 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funksiyalar:" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Massiv Ölçüsünü DÉ™yiÅŸ" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12896,6 +13176,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12904,6 +13188,55 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Node" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Açar sözü buraya daxil edin" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "CustomNode" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12913,12 +13246,66 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Funksiyalar:" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Siqnal:" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13480,7 +13867,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13693,7 +14089,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/bg.po b/editor/translations/bg.po index 03d385bf53..a0e22270a6 100644 --- a/editor/translations/bg.po +++ b/editor/translations/bg.po @@ -372,6 +372,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -821,6 +822,7 @@ msgstr "ДобавÑне" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -870,8 +872,7 @@ msgstr "Сигналът не може да бъде Ñвързан" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1897,7 +1898,6 @@ msgid "New Folder..." msgstr "Ðова папка..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2014,7 +2014,8 @@ msgstr "Папки и файлове:" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Файл:" @@ -2184,7 +2185,7 @@ msgstr "Метод" msgid "Signal" msgstr "Сигнал" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "КонÑтанта" @@ -2215,6 +2216,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2933,7 +2936,8 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +#, fuzzy +msgid "Open User Data Folder" msgstr "ОтварÑне на папката Ñ Ð´Ð°Ð½Ð½Ð¸ на проекта" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3070,10 +3074,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Превключване на ÑиÑтемната конзола" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "ОтварÑне на папката Ñ Ð´Ð°Ð½Ð½Ð¸/наÑтройки на редактора" @@ -3294,6 +3294,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3370,7 +3371,6 @@ msgid "Author" msgstr "Ðвтор" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3595,6 +3595,12 @@ msgstr "Път на Ñцената:" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Грешка!" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4452,6 +4458,7 @@ msgid "Subfolder:" msgstr "Подпапка:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6129,6 +6136,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "ДобавÑне на %s" @@ -9459,7 +9467,7 @@ msgid "TileSet" msgstr "Плочен набор" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9467,7 +9475,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9475,7 +9488,38 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "Промени в шейдъра:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Промени в шейдъра:" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Поддърво" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9487,7 +9531,37 @@ msgid "Initialize" msgstr "Инициализиране" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Премахване на точката" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Преименуван" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9495,49 +9569,140 @@ msgid "Detect new changes" msgstr "ЗаÑичане на новите промени" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +#, fuzzy +msgid "Discard all changes" +msgstr "ЗатвÑране и запазване на промените?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Запазване на локалните промени..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Промени в материала:" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" -msgstr "Преименуван" +msgid "Commit List" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" -msgstr "Изтрит" +msgid "Commit list size" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "10" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "СъвпадениÑ:" + +#: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "Покажи СелекциÑта (вмеÑти в Ñ†ÐµÐ»Ð¸Ñ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€ÐµÑ†)" +msgid "Create New Branch" +msgstr "Създаване на нов проект" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "Запази Ð’Ñичко" +msgid "Remove Branch" +msgstr "Премахване на проекта" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Отдалечен" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Създаване на нов проект" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Премахване на текÑтурата" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Отдалечено " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Отдалечено " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Източник за полигонна мрежа:" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "Преименуван" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "Изтрит" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Unmerged" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +#, fuzzy +msgid "View:" +msgstr "Преглед" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12056,6 +12221,7 @@ msgid "Export list to a CSV file" msgstr "ИзнаÑÑне на ÑпиÑъка като файл CSV" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12896,6 +13062,40 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Задаване на израз" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "анимациÑ" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12908,6 +13108,84 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Папка:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Типове:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "ДобавÑне на %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "ДобавÑне на %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12924,6 +13202,20 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Функции" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "ПреоразмерÑване на маÑива" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12933,6 +13225,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12941,6 +13237,64 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Презареждане" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Ð˜Ð½Ð´ÐµÐºÑ Ð¿Ð¾ Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Ð˜Ð½Ð´ÐµÐºÑ Ð¿Ð¾ Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "КонÑтанта" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "КонÑтанта" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "КонÑтанта" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "КонÑтанта" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Ðов корен на Ñцената" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Редактиране на дървото на Ñцената" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "ИзрÑзване на възлите" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12950,12 +13304,69 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "КонÑтанти" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "ДейÑтвие" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "ТърÑене във VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "ПремеÑтване на кадъра" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Сигнал" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Сигнал" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13553,7 +13964,16 @@ msgstr "ParallaxLayer работи Ñамо, когато е наÑледник msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13775,7 +14195,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/bn.po b/editor/translations/bn.po index a5f504af97..6af9541a8e 100644 --- a/editor/translations/bn.po +++ b/editor/translations/bn.po @@ -366,6 +366,7 @@ msgstr "%d à¦à¦° জনà§à¦¯ নতà§à¦¨ টà§à¦°à§à¦¯à¦¾à¦•/পথ-সমà #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -846,6 +847,7 @@ msgstr "সংযোজন করà§à¦¨" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -898,8 +900,7 @@ msgstr "সংযোজক সংকেত/সিগনà§à¦¯à¦¾à¦²:" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -2021,7 +2022,6 @@ msgid "New Folder..." msgstr "ফোলà§à¦¡à¦¾à¦° তৈরি করà§à¦¨" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "রিফà§à¦°à§‡à¦¸ করà§à¦¨" @@ -2146,7 +2146,8 @@ msgstr "পথ à¦à¦¬à¦‚ ফাইল:" msgid "Preview:" msgstr "পà§à¦°à¦¿à¦à¦¿à¦‰:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "ফাইল:" @@ -2349,7 +2350,7 @@ msgstr "মেথডের তালিকা:" msgid "Signal" msgstr "সংকেতসমূহ" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "ধà§à¦°à§à¦¬à¦•/কনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦Ÿ" @@ -2382,6 +2383,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -3157,7 +3160,7 @@ msgstr "" #: editor/editor_node.cpp #, fuzzy -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "পà§à¦°à¦•লà§à¦ª মà§à¦¯à¦¾à¦¨à§‡à¦œà¦¾à¦°" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3325,11 +3328,6 @@ msgstr "পূরà§à¦£-পরà§à¦¦à¦¾ অদলবদল/টগল করà§à¦ #: editor/editor_node.cpp #, fuzzy -msgid "Toggle System Console" -msgstr "CanvasItem দৃশà§à¦¯à¦®à¦¾à¦¨à¦¤à¦¾ টগল করà§à¦¨" - -#: editor/editor_node.cpp -#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "à¦à¦¡à¦¿à¦Ÿà¦°à§‡à¦° সেটিংস" @@ -3567,6 +3565,7 @@ msgid "Load Errors" msgstr "à¦à§à¦²/সমসà§à¦¯à¦¾-সমূহ লোড করà§à¦¨" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨" @@ -3658,7 +3657,6 @@ msgid "Author" msgstr "লেখক" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp #, fuzzy msgid "Status" @@ -3908,6 +3906,12 @@ msgstr "দৃশà§à¦¯à§‡à¦° পথ:" msgid "Import From Node:" msgstr "নোড হতে ইমà§à¦ªà§‹à¦°à§à¦Ÿ করà§à¦¨:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "সমসà§à¦¯à¦¾/à¦à§à¦²" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4891,6 +4895,7 @@ msgid "Subfolder:" msgstr "উপফোলà§à¦¡à¦¾à¦°:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "লেখক:" @@ -6725,6 +6730,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "%s সংযà§à¦•à§à¦¤ করà§à¦¨" @@ -10406,7 +10412,7 @@ msgid "TileSet" msgstr "TileSet (টাইল-সেট)..." #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -10414,19 +10420,58 @@ msgid "Error" msgstr "সমসà§à¦¯à¦¾/à¦à§à¦²" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy +msgid "No commit message was provided." +msgstr "পà§à¦¨à¦ƒà¦¨à¦¾à¦®à¦•রণ করà§à¦¨ অথবা সরান..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy msgid "Commit" msgstr "কমিউনিটি/যৌথ-সামাজিক উৎস" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "পরিবরà§à¦¤à¦¨à¦¸à¦®à§‚হ হাল-নাগাদ করà§à¦¨" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "পরিবরà§à¦¤à¦¨à¦¸à¦®à§‚হ হাল-নাগাদ করà§à¦¨" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "কমিউনিটি/যৌথ-সামাজিক উৎস" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "à¦à¦•ধিক পà§à¦°à¦•লà§à¦ª খোলায় আপনি সà§à¦¨à¦¿à¦¶à§à¦šà¦¿à¦¤?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "সমà§à¦ªà§à¦°à¦¸à¦¾à¦°à¦¨/সংকোচন অপসারণ করà§à¦¨ (রিসেট জà§à¦®à§)" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -10436,7 +10481,37 @@ msgid "Initialize" msgstr "বড় হাতের অকà§à¦·à¦°à§‡ পরিবরà§à¦¤à¦¨à§‡ করà§à¦¨" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "পথের বিনà§à¦¦à§ অপসারণ করà§à¦¨" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "পà§à¦¨à¦ƒà¦¨à¦¾à¦®à¦•রণ করà§à¦¨" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -10446,54 +10521,146 @@ msgstr "নতà§à¦¨ তৈরি করà§à¦¨" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Changes" -msgstr "পরিবরà§à¦¤à¦¨ করà§à¦¨" +msgid "Discard all changes" +msgstr "বনà§à¦§ à¦à¦¬à¦‚ পরিবরà§à¦¤à¦¨ সংরকà§à¦·à¦£ করবেন?" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +#, fuzzy +msgid "Stage all changes" +msgstr "সà§à¦¥à¦¾à¦¨à§€à§Ÿ পরিবরà§à¦¤à¦¨-সমূহ সংরকà§à¦·à¦¿à¦¤ হচà§à¦›à§‡..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "পরিবরà§à¦¤à¦¨à¦¸à¦®à§‚হ হাল-নাগাদ করà§à¦¨" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿà§‡à¦° পরিবরà§à¦¤à¦¨à¦¸à¦®à§‚হ সà§à¦¸à¦‚গত/সমনà§à¦¬à§Ÿ করà§à¦¨" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Changes" +msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿà§‡à¦° পরিবরà§à¦¤à¦¨à¦¸à¦®à§‚হ সà§à¦¸à¦‚গত/সমনà§à¦¬à§Ÿ করà§à¦¨" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "কমিউনিটি/যৌথ-সামাজিক উৎস" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "পà§à¦¨à¦ƒà¦¨à¦¾à¦®à¦•রণ করà§à¦¨" +msgid "Branches" +msgstr "মিলসমূহ:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" +msgid "Create New Branch" +msgstr "নতà§à¦¨ পà§à¦°à¦•লà§à¦ª তৈরি করà§à¦¨" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (Anim) টà§à¦°à§à¦¯à¦¾à¦• রিমà§à¦ করà§à¦¨" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" msgstr "অপসারণ করà§à¦¨" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Typechange" -msgstr "পরিবরà§à¦¤à¦¨ করà§à¦¨" +msgid "Create New Remote" +msgstr "নতà§à¦¨ পà§à¦°à¦•লà§à¦ª তৈরি করà§à¦¨" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ সমূহ অপসারণ করà§à¦¨" +msgid "Remove Remote" +msgstr "বসà§à¦¤à§ অপসারণ করà§à¦¨" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "সকলà§à¦—à§à¦²à¦¿ সংরকà§à¦·à¦£ করà§à¦¨" +msgid "Remote Name" +msgstr "অপসারণ করà§à¦¨" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" -msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿà§‡à¦° পরিবরà§à¦¤à¦¨à¦¸à¦®à§‚হ সà§à¦¸à¦‚গত/সমনà§à¦¬à§Ÿ করà§à¦¨" +msgid "Remote URL" +msgstr "অপসারণ করà§à¦¨" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "No file diff is active" -msgstr "কোনো ফাইল নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ হয়নি!" +msgid "Force Push" +msgstr "উৎস Mesh:" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "পà§à¦¨à¦ƒà¦¨à¦¾à¦®à¦•রণ করà§à¦¨" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "অপসারণ করà§à¦¨" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Typechange" +msgstr "পরিবরà§à¦¤à¦¨ করà§à¦¨" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "View:" +msgstr "দৃশà§à¦¯/পরিদরà§à¦¶à¦¨" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Split" +msgstr "পথ বিà¦à¦•à§à¦¤ করà§à¦¨" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -13263,6 +13430,7 @@ msgid "Export list to a CSV file" msgstr "পà§à¦°à¦•লà§à¦ª à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ করà§à¦¨" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "রিসোরà§à¦¸-à¦à¦° পথ" @@ -14209,6 +14377,40 @@ msgstr "রিফà§à¦°à§‡à¦¸ করà§à¦¨" msgid "Edit Member" msgstr "সদসà§à¦¯à¦—ণ (Members):" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "অà¦à¦¿à¦¬à§à¦¯à¦•à§à¦¤à¦¿ (Expression) পরিবরà§à¦¤à¦¨ করà§à¦¨" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "যোগান/ইনপà§à¦Ÿ-à¦à¦° ধরণ পà§à¦¨à¦°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦¿à¦®à§‚লক নয়: " @@ -14221,6 +14423,87 @@ msgstr "পà§à¦¨à¦°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦•ারী অকারà§à¦¯à¦•র হà msgid "Iterator became invalid: " msgstr "পà§à¦¨à¦°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦•ারী অকারà§à¦¯à¦•র হয়ে পড়েছে: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "নোড পà§à¦¨à¦ƒà¦¨à¦¾à¦®à¦•রণ করà§à¦¨" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "পিচà§â€Œ" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "ধরণ:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "সà§à¦¬à§€à¦¯à¦¼" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "গà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ অকà§à¦·à¦°à¦¸à¦®à§‚হ:" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "%s সংযà§à¦•à§à¦¤ করà§à¦¨" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "%s সংযà§à¦•à§à¦¤ করà§à¦¨" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "সূচক/ইনডেকà§à¦¸ মানের অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ নাম।" @@ -14237,6 +14520,20 @@ msgstr "পথটি নোডকে দিকনিরà§à¦¦à§‡à¦¶ করে ঠmsgid "Invalid index property name '%s' in node %s." msgstr "%s নোডে সূচক/ইনডেকà§à¦¸ মানের অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ নাম '%s'।" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "ফাংশনগà§à¦²à¦¿:" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "শà§à¦°à§‡à¦£à§€à¦¬à¦¿à¦¨à§à¦¯à¦¾à¦¸/সারি পà§à¦¨à¦°à§à¦®à¦¾à¦ªà¦¨ করà§à¦¨" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ মান/আরà§à¦—à§à¦®à§‡à¦¨à§à¦Ÿ-à¦à¦° ধরণ: " @@ -14246,6 +14543,10 @@ msgid ": Invalid arguments: " msgstr ": অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ মান/আরà§à¦—à§à¦®à§‡à¦¨à§à¦Ÿ-সমূহ: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿà§‡ চলক-পà§à¦°à¦¾à¦ªà¦• (VariableGet) পাওয়া যায়নি: " @@ -14254,6 +14555,65 @@ msgid "VariableSet not found in script: " msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿà§‡ চলক-সà§à¦¥à¦¾à¦ªà¦• (VariableSet) পাওয়া যায়নি: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "রিলোড" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "ইনà§à¦¡à§‡à¦•à§à¦¸:" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "ইনà§à¦¡à§‡à¦•à§à¦¸:" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "ধà§à¦°à§à¦¬à¦•/কনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦Ÿ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "ধà§à¦°à§à¦¬à¦•/কনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦Ÿ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "ধà§à¦°à§à¦¬à¦•/কনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦Ÿ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "ধà§à¦°à§à¦¬à¦•/কনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦Ÿ" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "টাইম-সীকà§â€Œ নোড" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "দৃশà§à¦¯à§‡à¦° শাখা (নোডসমূহ):" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "সà§à¦¬à§€à¦¯à¦¼" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "নোড-সমূহ করà§à¦¤à¦¨/কাট করà§à¦¨" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "সà§à¦¬à¦¨à¦¿à¦°à§à¦®à¦¿à¦¤ (custom) নোডে কোনো _step() মেথড নেই, গà§à¦°à¦¾à¦« পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾à¦•রণ অসমà§à¦à¦¬à¥¤" @@ -14265,15 +14625,77 @@ msgstr "" "_step() হতে অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ মান ফেরৎ à¦à¦¸à§‡à¦›à§‡, মান অবশà§à¦¯à¦‡ পূরà§à¦£à¦¸à¦‚খà§à¦¯à¦¾ (integer) (কà§à¦°à¦®à¦¿à¦•), " "অথবা শবà§à¦¦à¦®à¦¾à¦²à¦¾/বাকà§à¦¯ (string) (à¦à§à¦²/সমসà§à¦¯à¦¾) হতে হবে।" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "ডাকà§à¦¨ (Call)" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "ধà§à¦°à§à¦¬à¦•সমূহ:" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "মাপের মোড করà§à¦¨ (R)" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "মাপের মোড করà§à¦¨ (R)" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾/অà§à¦¯à¦¾à¦•শন" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp #, fuzzy msgid "Search VisualScript" msgstr "Shader Graph Node অপসারণ করà§à¦¨" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "ফà§à¦°à§‡à¦® পà§à¦°à¦¤à¦¿à¦²à§‡à¦ªà¦¨ করà§à¦¨" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "সà§à¦¥à¦¿à¦°/বদà§à¦§ ফà§à¦°à§‡à¦® %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" msgstr "" +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "সংকেতসমূহ" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "সংকেতসমূহ" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "ইনসà§à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸" + #: platform/android/export/export_plugin.cpp msgid "Package name is missing." msgstr "" @@ -14889,7 +15311,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -15126,7 +15557,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/br.po b/editor/translations/br.po index e7990afc1f..77c78f55b8 100644 --- a/editor/translations/br.po +++ b/editor/translations/br.po @@ -360,6 +360,7 @@ msgstr "Krouiñ %d roudenn NEVEZ hag enlakaat alc'hwezioù ?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -823,6 +824,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -872,8 +874,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1897,7 +1898,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2014,7 +2014,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2182,7 +2183,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2212,6 +2213,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2906,7 +2909,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3041,10 +3044,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3262,6 +3261,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3338,7 +3338,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3564,6 +3563,11 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +msgid "%s Error" +msgstr "" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4419,6 +4423,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6067,6 +6072,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9351,7 +9357,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9359,7 +9365,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9367,7 +9378,35 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9379,39 +9418,55 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +msgid "Remote Login" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect new changes" +msgid "Username" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Password" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "SSH Public Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +msgid "Select SSH public key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" +msgid "SSH Private Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect new changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +msgid "Stage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Unstage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9419,15 +9474,108 @@ msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Commit List" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Branch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Dilemel ar Roudenn Fiñvskeudenn" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remotes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remove Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote URL" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "View:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -11936,6 +12084,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12765,6 +12914,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Tro Fiñvskeudenn" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12777,6 +12959,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12793,6 +13049,19 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Fonksionoù :" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12802,6 +13071,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12810,6 +13083,55 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Node" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Enlakaat an Alc'hwezh Amañ" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "CustomNode" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12819,12 +13141,65 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Fonksionoù :" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13386,7 +13761,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13599,7 +13983,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/ca.po b/editor/translations/ca.po index 043bc573f0..15c6342076 100644 --- a/editor/translations/ca.po +++ b/editor/translations/ca.po @@ -6,7 +6,7 @@ # Javier Ocampos <xavier.ocampos@gmail.com>, 2018. # Roger Blanco Ribera <roger.blancoribera@gmail.com>, 2016-2018, 2020. # Rubén Moreno <ruben.moreno.romero@gmail.com>, 2018. -# roger <616steam@gmail.com>, 2019, 2020, 2021. +# roger <616steam@gmail.com>, 2019, 2020, 2021, 2022. # Roger BR <drai_kin@hotmail.com>, 2019. # Adolfo Jayme Barrientos <fitojb@ubuntu.com>, 2020. # Xavier Gomez <hiulit@gmail.com>, 2020, 2021. @@ -21,7 +21,7 @@ msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-12-20 18:53+0000\n" +"PO-Revision-Date: 2022-01-12 16:52+0000\n" "Last-Translator: roger <616steam@gmail.com>\n" "Language-Team: Catalan <https://hosted.weblate.org/projects/godot-engine/" "godot/ca/>\n" @@ -30,7 +30,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.10\n" +"X-Generator: Weblate 4.10.1\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -371,6 +371,7 @@ msgstr "Voleu crear %d NOVES pistes i inserir-hi claus?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -842,6 +843,7 @@ msgstr "Afegeix" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -893,8 +895,7 @@ msgstr "No es pot connectar el senyal" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1510,7 +1511,7 @@ msgstr "Nom no và lid." #: editor/editor_autoload_settings.cpp msgid "Cannot begin with a digit." -msgstr "" +msgstr "No pot començar amb un digit." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" @@ -1982,7 +1983,6 @@ msgid "New Folder..." msgstr "Nou Directori..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Refresca" @@ -2099,7 +2099,8 @@ msgstr "Directoris i Fitxers:" msgid "Preview:" msgstr "Vista prèvia:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Fitxer:" @@ -2278,7 +2279,7 @@ msgstr "Mètode" msgid "Signal" msgstr "Senyal" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Constant" @@ -2309,6 +2310,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Definir %s" @@ -3071,8 +3074,9 @@ msgid "Install Android Build Template..." msgstr "Instal·lar Plantilla de Compilació d'Android..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Obre el directori de Dades del Projecte" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Obre el directori de Dades de l'Editor" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3236,10 +3240,6 @@ msgid "Toggle Fullscreen" msgstr "Mode Pantalla Completa" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Commutar la consola del sistema" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Obre el directori de Dades/Configuració de l'Editor" @@ -3470,6 +3470,7 @@ msgid "Load Errors" msgstr "Errors de Cà rrega" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Selecciona" @@ -3550,7 +3551,6 @@ msgid "Author" msgstr "Autors" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Estat" @@ -3792,6 +3792,12 @@ msgstr "Camà de l'Escena:" msgid "Import From Node:" msgstr "Importa des del Node:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Error" + #: editor/export_template_manager.cpp #, fuzzy msgid "Open the folder containing these templates." @@ -4000,6 +4006,7 @@ msgstr "Obrir Fitxer" #: editor/export_template_manager.cpp msgid "Open the folder containing installed templates for the current version." msgstr "" +"Obre la carpeta que conté les plantilles instal·lades per la versió actual." #: editor/export_template_manager.cpp msgid "Uninstall" @@ -4033,6 +4040,8 @@ msgid "" "Download and install templates for the current version from the best " "possible mirror." msgstr "" +"Descarrega i instal·la plantilles per a la versió actual des del millor " +"mirall possible." #: editor/export_template_manager.cpp msgid "Official export templates aren't available for development builds." @@ -4084,6 +4093,8 @@ msgid "" "The templates will continue to download.\n" "You may experience a short editor freeze when they finish." msgstr "" +"Les plantilles continuaran descarregant-se.\n" +"Es possible que experimenteu una breu congelació de l'editor quan acabin." #: editor/filesystem_dock.cpp msgid "Favorites" @@ -4719,6 +4730,7 @@ msgid "Subfolder:" msgstr "Subcarpeta:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Autor:" @@ -5671,8 +5683,9 @@ msgid "All" msgstr "Tot" #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "Search templates, projects, and demos" -msgstr "" +msgstr "Buscar plantilles, projectes i demos." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Search assets (excluding templates, projects, and demos)" @@ -6460,6 +6473,7 @@ msgid "Zoom to 1600%" msgstr "Zoom a 1600%" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Afegeix %s" @@ -9964,7 +9978,8 @@ msgid "TileSet" msgstr "Conjunt de rajoles" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "No hi ha addons VCS disponibles." #: editor/plugins/version_control_editor_plugin.cpp @@ -9972,8 +9987,14 @@ msgid "Error" msgstr "Error" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "No hi ha fitxers afegits a l'escenari" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "No s'ha proporcionat cap nom." #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy @@ -9982,8 +10003,41 @@ msgstr "Comunitat" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "VCS Addon is not initialized" -msgstr "L'Addon VCS no està inicialitzat" +msgid "Staged Changes" +msgstr "Canvis de Shader:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Canvis de Shader:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Comunitat" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Subarbre" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Esteu segur que voleu obrir més d'un projecte de cop?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Resetejar" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9995,16 +10049,149 @@ msgid "Initialize" msgstr "Converteix a Majúscules" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "Zona de posada en escena" +#, fuzzy +msgid "Remote Login" +msgstr "Elimina Punt" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Reanomena" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Detectar nous canvis" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Canvis" +#, fuzzy +msgid "Discard all changes" +msgstr "Tancar i desar els canvis?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Emmagatzemant canvis locals..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Canvis de Material:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Sincronitzar Canvis en Scripts" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Changes" +msgstr "Sincronitzar Canvis en Scripts" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Comunitat" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Coincidències:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Crea un Projecte nou" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Treu la Pista" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Remot" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Crea un Projecte nou" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Elimina Element" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Remot " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Remot " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Malla d'Origen:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -10026,33 +10213,23 @@ msgid "Typechange" msgstr "Modifica" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy -msgid "Stage Selected" -msgstr "Elimina Seleccionats" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "Desa-ho Tot" +msgid "View:" +msgstr "Vista" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" -msgstr "Sincronitzar Canvis en Scripts" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "" -"Verifica les diferències entre fitxers abans de publicar-les a la darrera " -"versió" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "No hi ha cap diferència de fitxer activa" +msgid "Split" +msgstr "Parteix el CamÃ" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "Detecta els canvis en el fitxer" +#, fuzzy +msgid "Unified" +msgstr "Modificat" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12837,6 +13014,7 @@ msgid "Export list to a CSV file" msgstr "Exportar Perfil" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Camà de Recursos" @@ -13735,6 +13913,40 @@ msgstr "Refresca" msgid "Edit Member" msgstr "Editar Membre" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Canviar Expressió" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animació" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Tipus d'entrada no iterable: " @@ -13747,6 +13959,88 @@ msgstr "L'Iterador ja no és và lid" msgid "Iterator became invalid: " msgstr "L'Iterador ja no és và lid: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Reanomenant directori:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "commutador:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Tipus:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Propi" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Al carà cter %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Afegeix %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Definir %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Afegeix %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Obtenir %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "El Nom de la propietat Ãndex no és và lid." @@ -13763,6 +14057,21 @@ msgstr "El camà no condueix a cap Node!" msgid "Invalid index property name '%s' in node %s." msgstr "El nom de la propietat Ãndex '%s' del node %s no és và lid ." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Definir %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funcions" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Redimensiona la Matriu" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Argument no và lid del tipus: " @@ -13772,6 +14081,10 @@ msgid ": Invalid arguments: " msgstr ": Arguments no và lids: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "Variable Get no trobada en l'Script: " @@ -13780,6 +14093,66 @@ msgid "VariableSet not found in script: " msgstr "Variable Set no trobada en l'Script: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Torna a Carregar" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Ãndex" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Ãndex" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Constant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Constant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Constant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Constant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "Habilitar Singleton GDNative" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Node cercaTemps" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Edició de l'arbre d'escenes" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Propi" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Talla els Nodes" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" "El node personalitzat no té cap mètode _step(), no es pot processar el graf." @@ -13792,14 +14165,76 @@ msgstr "" "El Valor retornat per _step() no és và lid. Ha de ser un nombre enter (seq " "out), o una cadena de text (error)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Crides" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Constants" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Utilitzar Espai Local" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Utilitzar Espai Local" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Acció" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp #, fuzzy msgid "Search VisualScript" msgstr "Elimina el Node de VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Obtenir %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Enganxa el Fotograma" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Fotograma de FÃsica %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Senyal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Senyal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instà ncia" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14447,7 +14882,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14710,7 +15154,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/cs.po b/editor/translations/cs.po index eba90c7fe3..24933836f4 100644 --- a/editor/translations/cs.po +++ b/editor/translations/cs.po @@ -386,6 +386,7 @@ msgstr "VytvoÅ™it %d NOVÃCH stop a vložit klÃÄe?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -855,6 +856,7 @@ msgstr "PÅ™idat" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -904,8 +906,7 @@ msgstr "PÅ™ipojit Signál" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1964,7 +1965,6 @@ msgid "New Folder..." msgstr "Nová složka..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Obnovit" @@ -2081,7 +2081,8 @@ msgstr "Složky a soubory:" msgid "Preview:" msgstr "Náhled:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Soubor:" @@ -2256,7 +2257,7 @@ msgstr "Metoda" msgid "Signal" msgstr "Signál" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "KonstantnÃ" @@ -2287,6 +2288,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Nastav %s" @@ -3037,8 +3040,9 @@ msgid "Install Android Build Template..." msgstr "Nainstalovat kompilaÄnà šablonu pro Android..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "OtevÅ™Ãt složku s daty projektu" +#, fuzzy +msgid "Open User Data Folder" +msgstr "OtevÅ™Ãt složku s daty editoru" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3194,10 +3198,6 @@ msgid "Toggle Fullscreen" msgstr "PÅ™epnout celou obrazovku" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Zapnout/Vypnout systémovou konzoli" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "OtevÅ™Ãt složku s daty a nastavenÃm editoru" @@ -3427,6 +3427,7 @@ msgid "Load Errors" msgstr "NaÄÃst chyby" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Vybrat" @@ -3503,7 +3504,6 @@ msgid "Author" msgstr "Autor" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Status" @@ -3747,6 +3747,12 @@ msgstr "Cesta ke scénÄ›:" msgid "Import From Node:" msgstr "Import z uzlu:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Chyba" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "OtevÅ™Ãt složku obsahujÃcà tyto Å¡ablony." @@ -4632,6 +4638,7 @@ msgid "Subfolder:" msgstr "Podsložka:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Autor:" @@ -6323,6 +6330,7 @@ msgid "Zoom to 1600%" msgstr "PÅ™iblÞenà na 1600 %" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "PÅ™idat %s" @@ -9727,7 +9735,8 @@ msgid "TileSet" msgstr "TileSet (Sada dlaždic)" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "K dispozici nejsou žádná VCS rozÅ¡ÃÅ™enÃ." #: editor/plugins/version_control_editor_plugin.cpp @@ -9735,16 +9744,56 @@ msgid "Error" msgstr "Chyba" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "Zádné soubory nebyly pÅ™idány k zápisu" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Nebylo poskytnuto žádné jméno." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "Commit" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "VCS rozÅ¡ÃÅ™enà nejnà inicializováno" +#, fuzzy +msgid "Staged Changes" +msgstr "ZmÄ›ny shaderu:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "ZmÄ›ny shaderu:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Commit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Podstrom" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Jste si jisti, že chcete otevÅ™it vÃce než jeden projekt?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Resetovat" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9755,16 +9804,148 @@ msgid "Initialize" msgstr "Inicializovat" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "K zápsánÃ" +#, fuzzy +msgid "Remote Login" +msgstr "Odstranit bod" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "PÅ™ejmenovat" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Detekovat nové zmÄ›ny" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "ZmÄ›ny" +#, fuzzy +msgid "Discard all changes" +msgstr "ZavÅ™Ãt a uložit zmÄ›ny?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Ukládám lokálnà zmÄ›ny..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "ZmÄ›ny materiálu:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Commitnout zmÄ›ny" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "Commitnout zmÄ›ny" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Commit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Shody:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "VytvoÅ™it nový projekt" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Odstranit stopu animace" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Vzdálený" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "VytvoÅ™it nový projekt" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Odstranit položku" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Vzdálený " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Vzdálený " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Zdrojová mesh:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9783,28 +9964,23 @@ msgid "Typechange" msgstr "ZmÄ›nit typ" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "PÅ™ipravit vybrané k zapsánÃ" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "PÅ™ipravit k zapsánà vÅ¡e" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "Commitnout zmÄ›ny" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "PodÃvat se na rozdÃly, než se commitnou jako nejnovÄ›jšàverze" +#, fuzzy +msgid "View:" +msgstr "ZobrazenÃ" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "Žádné aktivnà porovnánà zmÄ›n" +#, fuzzy +msgid "Split" +msgstr "RozdÄ›lit cestu" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "Zjistit zmÄ›ny v souborech" +#, fuzzy +msgid "Unified" +msgstr "Úpravy" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12474,6 +12650,7 @@ msgid "Export list to a CSV file" msgstr "Exportovat seznam do CSV" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Cesta ke zdroji" @@ -13322,6 +13499,40 @@ msgstr "Obnovit graf" msgid "Edit Member" msgstr "Upravit Äleny" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Nastavit výraz" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animace" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "VstupnÃm typem nelze iterovat: " @@ -13334,6 +13545,88 @@ msgstr "Iterátor se stal neplatným" msgid "Iterator became invalid: " msgstr "Iterátor se stal neplatným: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "PÅ™ejmenovánà složky:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "StoupánÃ:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Typy:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Tento objekt" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Na znaku %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "PÅ™idat %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Nastav %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "PÅ™idat %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "PÅ™ijmi %d" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Neplatné jméno vlastnosti." @@ -13350,6 +13643,21 @@ msgstr "Cesta nevede k uzlu!" msgid "Invalid index property name '%s' in node %s." msgstr "Neplatné jméno vlastnosti '%s' v uzlu %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Nastav %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funkce" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "ZmÄ›nit velikost pole" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Neplatný argument typu: " @@ -13359,6 +13667,10 @@ msgid ": Invalid arguments: " msgstr ": Neplatné argumenty: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "PromÄ›nná pro zÃskánà nebyla ve skriptu nalezena: " @@ -13367,6 +13679,66 @@ msgid "VariableSet not found in script: " msgstr "PromÄ›nná pro nastavenà nebyla ve skriptu nalezena: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Znovu naÄÃst" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Z-Index" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Z-Index" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "KonstantnÃ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "KonstantnÃ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "KonstantnÃ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "KonstantnÃ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "Zapnutý GDNative Singleton" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Uzel TimeSeek" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Úpravy stromu scény" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Tento objekt" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Vyjmout uzly" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "Vlastnà uzel nemá metodu _step(), takže nelze postupovat grafem." @@ -13378,13 +13750,75 @@ msgstr "" "Neplatná návratová hodnota z funkce _step(). Musà být celé ÄÃslo (výstupnà " "posloupnost), nebo Å™etÄ›zec (chyba)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "VolánÃ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Konstanty" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "PoužÃt mÃstnà prostor" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "PoužÃt mÃstnà prostor" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Akce" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Hledat VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "PÅ™ijmi %d" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Posunout snÃmek" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Fyzikálnà snÃmek %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Signál" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Signál" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instance" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14010,15 +14444,25 @@ msgstr "" "Uzel ParallaxLayer funguje pouze když je dÃtÄ›tem uzlu ParallaxBackground." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "Grafický ovladaÄ GLES2 nepodporuje Äástice založené na GPU.\n" "Použijte uzel CPUParticles2D. Na pÅ™evod lze použÃt \"PÅ™evést na CPUParticles" "\"." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14264,10 +14708,11 @@ msgid "Only uniform scales are supported." msgstr "" #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "Video driver GLES2 nepodporuje Äástice na GPU.\n" "MÃsto toho použijte uzel CPUParticles. K pÅ™evodu můžete použÃt \"PÅ™evést na " @@ -14275,6 +14720,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" "Nic nenà viditelné, protože mřÞky nebyly pÅ™iÅ™azeny do vykreslovacà fronty." diff --git a/editor/translations/da.po b/editor/translations/da.po index f35a125640..94f5d4b033 100644 --- a/editor/translations/da.po +++ b/editor/translations/da.po @@ -381,6 +381,7 @@ msgstr "Opret %d NYE spor og indsæt nøgler?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -873,6 +874,7 @@ msgstr "Tilføj" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -926,8 +928,7 @@ msgstr "Kan ikke forbinde signal" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -2041,7 +2042,6 @@ msgid "New Folder..." msgstr "Opret mappe..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Opdater" @@ -2166,7 +2166,8 @@ msgstr "Mapper & Filer:" msgid "Preview:" msgstr "ForhÃ¥ndsvisning:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Fil:" @@ -2343,7 +2344,7 @@ msgstr "Metoder" msgid "Signal" msgstr "Signaler" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Konstant" @@ -2376,6 +2377,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -3132,7 +3135,8 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +#, fuzzy +msgid "Open User Data Folder" msgstr "Ã…bn Projekt datamappe" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3297,11 +3301,6 @@ msgid "Toggle Fullscreen" msgstr "Skifter fuldskærm" #: editor/editor_node.cpp -#, fuzzy -msgid "Toggle System Console" -msgstr "Skifter Modus" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Ã…bn redaktør Data/Indstillinger-mappe" @@ -3532,6 +3531,7 @@ msgid "Load Errors" msgstr "Indlæs Fejl" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Vælg" @@ -3615,7 +3615,6 @@ msgid "Author" msgstr "Forfattere" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3849,6 +3848,12 @@ msgstr "Scene Sti:" msgid "Import From Node:" msgstr "Importer Fra Node:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Fejl!" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4797,6 +4802,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Forfatter:" @@ -6558,6 +6564,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -10092,7 +10099,7 @@ msgid "TileSet" msgstr "TileSet..." #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -10100,19 +10107,58 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy +msgid "No commit message was provided." +msgstr "Intet navn angivet." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy msgid "Commit" msgstr "Fællesskab" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "Skift Shader" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Skift Shader" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Fællesskab" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Er du sikker pÃ¥ at du vil fjerne alle forbindelser fra dette signal?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Anvende nulstilling" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -10121,7 +10167,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Fjern punkt" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Omdøb" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -10131,53 +10207,145 @@ msgstr "Opret Ny %s" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Changes" -msgstr "Skift" +msgid "Discard all changes" +msgstr "Skift Shader" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +#, fuzzy +msgid "Stage all changes" +msgstr "Gemmer lokale ændringer..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Skift Shader" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Synkroniser Script Ændringer" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Changes" +msgstr "Synkroniser Script Ændringer" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Fællesskab" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "Omdøb" +msgid "Branches" +msgstr "Matches:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "Slet" +msgid "Create New Branch" +msgstr "Opret Ny %s" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Typechange" -msgstr "Skift" +msgid "Remove Branch" +msgstr "Fjern Anim Spor" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "Slet Valgte" +msgid "Remotes" +msgstr "Fjern" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "Vælg alle" +msgid "Create New Remote" +msgstr "Opret Ny %s" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" -msgstr "Synkroniser Script Ændringer" +msgid "Remove Remote" +msgstr "Fjern Template" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Fjern" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Fjern" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Modified" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +#, fuzzy +msgid "Renamed" +msgstr "Omdøb" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "Slet" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Typechange" +msgstr "Skift" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +#, fuzzy +msgid "View:" +msgstr "ForhÃ¥ndsvisning:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Split" +msgstr "Rediger Node Kurve" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12829,6 +12997,7 @@ msgid "Export list to a CSV file" msgstr "Eksporter Projekt" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13715,6 +13884,40 @@ msgstr "Opdater" msgid "Edit Member" msgstr "Medlemmer" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Skift udtryk" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Animation" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Input type ikke iterabel: " @@ -13727,6 +13930,84 @@ msgstr "Iterator blev ugyldig" msgid "Iterator became invalid: " msgstr "Iterator blev ugyldig: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Omdøber mappe:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Basis Type:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Selv" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Gyldige karakterer:" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Ugyldigt index egenskabsnavn." @@ -13743,6 +14024,20 @@ msgstr "Stien fører ikke til Node!" msgid "Invalid index property name '%s' in node %s." msgstr "Ugyldigt indeks egenskabsnavn '%s' i noden %s." +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funktioner:" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Ændre størrelsen pÃ¥ Array" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Ugyldigt argument af typen: " @@ -13752,6 +14047,10 @@ msgid ": Invalid arguments: " msgstr ": Ugyldige argumenter: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet blev ikke fundet i scriptet: " @@ -13760,6 +14059,63 @@ msgid "VariableSet not found in script: " msgstr "VariableSet blev ikke fundet i scriptet: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Tilføj Preload Node" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Tidssøgning Node" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Gem Scene" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Selv" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Indsæt Node" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" "Brugerdefinerede node har ingen _step() metode, kan ikke behandle graf." @@ -13772,15 +14128,75 @@ msgstr "" "Ugyldig retur værdi fra _step(), skal være heltal (seq ud), eller en streng " "(fejl)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Kald" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Konstanter" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Tilføj Funktion" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp #, fuzzy msgid "Search VisualScript" msgstr "Fjern VisualScript Node" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Flyt Node(s)" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Fysik Frame %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" msgstr "" +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Signaler" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Signaler" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instans" + #: platform/android/export/export_plugin.cpp msgid "Package name is missing." msgstr "" @@ -14399,7 +14815,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14633,7 +15058,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/de.po b/editor/translations/de.po index 27b04cd77b..33f5042f4d 100644 --- a/editor/translations/de.po +++ b/editor/translations/de.po @@ -23,7 +23,7 @@ # Peter Friedland <peter_friedland@gmx.de>, 2016. # No need for a name <endoplasmatik@gmx.net>, 2016. # Sönke <me@eknoes.de>, 2018. -# So Wieso <sowieso@dukun.de>, 2016-2018, 2019, 2020, 2021. +# So Wieso <sowieso@dukun.de>, 2016-2018, 2019, 2020, 2021, 2022. # Tim Schellenberg <smwleod@gmail.com>, 2017. # Timo Schwarzer <account@timoschwarzer.com>, 2016-2018. # viernullvier <hannes.breul+github@gmail.com>, 2016. @@ -80,8 +80,8 @@ msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-01-03 03:55+0000\n" -"Last-Translator: Antonio Noack <corperateraider@gmail.com>\n" +"PO-Revision-Date: 2022-01-12 16:52+0000\n" +"Last-Translator: So Wieso <sowieso@dukun.de>\n" "Language-Team: German <https://hosted.weblate.org/projects/godot-engine/" "godot/de/>\n" "Language: de\n" @@ -392,9 +392,8 @@ msgid "Duplicate Key(s)" msgstr "Schlüsselbilder duplizieren" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add RESET Value(s)" -msgstr "%d Frame(s) hinzufügen" +msgstr "RESET Wert(e) hinzufügen" #: editor/animation_track_editor.cpp msgid "Delete Key(s)" @@ -431,6 +430,7 @@ msgstr "%d NEUE Spuren erstellen und Schlüsselbilder hinzufügen?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -567,9 +567,8 @@ msgstr "" "sich nur um eine einzige Spur handelt." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Add RESET Keys" -msgstr "Schlüsselbilder skalieren" +msgstr "Anim RESET Werte hinzufügen" #: editor/animation_track_editor.cpp msgid "" @@ -902,6 +901,7 @@ msgstr "Hinzufügen" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -953,8 +953,7 @@ msgstr "Signal kann nicht verbunden werden" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1562,7 +1561,7 @@ msgstr "Ungültiger Name." #: editor/editor_autoload_settings.cpp msgid "Cannot begin with a digit." -msgstr "" +msgstr "Darf nicht mit Ziffer beginnen." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" @@ -2031,7 +2030,6 @@ msgid "New Folder..." msgstr "Neuer Ordner..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Aktualisieren" @@ -2148,7 +2146,8 @@ msgstr "Verzeichnisse & Dateien:" msgid "Preview:" msgstr "Vorschau:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Datei:" @@ -2198,9 +2197,8 @@ msgid "Properties" msgstr "Eigenschaften" #: editor/editor_help.cpp -#, fuzzy msgid "overrides %s:" -msgstr "Überschreibungen:" +msgstr "Überschreibt %s:" #: editor/editor_help.cpp msgid "default:" @@ -2323,7 +2321,7 @@ msgstr "Methode" msgid "Signal" msgstr "Ereignis" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Konstante" @@ -2340,20 +2338,23 @@ msgid "Property:" msgstr "Eigenschaft:" #: editor/editor_inspector.cpp -#, fuzzy msgid "Pin value" -msgstr "(Wert)" +msgstr "Wert anheften" #: editor/editor_inspector.cpp msgid "" "Pinning a value forces it to be saved even if it's equal to the default." msgstr "" +"Einen Wert anzuheften bedeutet dass er selbst dann gespeichert wird, wenn er " +"sich nicht vom Standardwert unterscheidet." #: editor/editor_inspector.cpp msgid "Pin value [Disabled because '%s' is editor-only]" -msgstr "" +msgstr "Wert anheften [deaktiviert da ‚%s‘ Editor-exclusiv ist]" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "%s setzen" @@ -2364,26 +2365,23 @@ msgstr "Mehrfach festlegen:" #: editor/editor_inspector.cpp msgid "Pinned %s" -msgstr "" +msgstr "%s angeheftet" #: editor/editor_inspector.cpp msgid "Unpinned %s" -msgstr "" +msgstr "%s losgelöst" #: editor/editor_inspector.cpp -#, fuzzy msgid "Copy Property" -msgstr "Eigenschaften kopieren" +msgstr "Eigenschaft kopieren" #: editor/editor_inspector.cpp -#, fuzzy msgid "Paste Property" -msgstr "Eigenschaften einfügen" +msgstr "Eigenschaft einfügen" #: editor/editor_inspector.cpp -#, fuzzy msgid "Copy Property Path" -msgstr "Skriptpfad kopieren" +msgstr "Eigenschaft-Pfad kopieren" #: editor/editor_log.cpp msgid "Output:" @@ -3123,8 +3121,9 @@ msgid "Install Android Build Template..." msgstr "Android-Build-Vorlage installieren..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Projektdatenordner öffnen" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Editordateiverzeichnis öffnen" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3213,7 +3212,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Force Shader Fallbacks" -msgstr "" +msgstr "Shader-Fallbacks forcieren" #: editor/editor_node.cpp msgid "" @@ -3224,6 +3223,13 @@ msgid "" "Asynchronous shader compilation must be enabled in the project settings for " "this option to make a difference." msgstr "" +"Falls diese Option gesetzt ist, werden Shader die gesamte Laufzeit in ihrer " +"Fallback-Form genutzt (entweder sichtbar mittels Übershader oder " +"verborgen).\n" +"Dies ist hilfreich um Aussehen und Performance der Fallbacks zu überprüfen, " +"welche üblicherweise nur kurzfristig angezeigt werden.\n" +"Asynchrone Shader-Kompilierung muss in den Projekteinstellungen aktiviert " +"sein, sonst hat diese Option keine Auswirkung." #: editor/editor_node.cpp msgid "Synchronize Scene Changes" @@ -3283,10 +3289,6 @@ msgid "Toggle Fullscreen" msgstr "Vollbildmodus umschalten" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Systemkonsole umschalten" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Editordaten-/Einstellungenordner öffnen" @@ -3517,6 +3519,7 @@ msgid "Load Errors" msgstr "Ladefehler" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Auswählen" @@ -3593,7 +3596,6 @@ msgid "Author" msgstr "Autor" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Status" @@ -3838,6 +3840,12 @@ msgstr "Szenenpfad:" msgid "Import From Node:" msgstr "Aus Node importieren:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Fehler" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "Den Ordner der diese Exportvorlagen enthält öffnen." @@ -4380,9 +4388,8 @@ msgid "Replace..." msgstr "Ersetzen..." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Replace in Files" -msgstr "Alle ersetzen" +msgstr "In Dateien ersetzen" #: editor/find_in_files.cpp msgid "Find: " @@ -4393,9 +4400,8 @@ msgid "Replace: " msgstr "Ersetzen: " #: editor/find_in_files.cpp -#, fuzzy msgid "Replace All (NO UNDO)" -msgstr "Alle ersetzen" +msgstr "Alle ersetzen (KEIN RÜCKGÄNGIG MACHEN)" #: editor/find_in_files.cpp msgid "Searching..." @@ -4625,6 +4631,8 @@ msgid "" "Select a resource file in the filesystem or in the inspector to adjust " "import settings." msgstr "" +"Zum Anpassen der Importeinstellungen muss eine Ressourcendatei im " +"Dateisystem oder im Inspektor ausgewählt werden." #: editor/inspector_dock.cpp msgid "Failed to load resource." @@ -4734,6 +4742,7 @@ msgid "Subfolder:" msgstr "Unterverzeichnis:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Autor:" @@ -6091,9 +6100,8 @@ msgid "Alt+Drag: Move selected node." msgstr "Alt+Ziehen = Ausgewähltes Node verschieben." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Alt+Drag: Scale selected node." -msgstr "Alt+Ziehen = Ausgewähltes Node verschieben." +msgstr "Alt+Ziehen = Ausgewähltes Node skalieren." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "V: Set selected node's pivot position." @@ -6127,7 +6135,7 @@ msgstr "Skalierungsmodus" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Shift: Scale proportionally." -msgstr "" +msgstr "Umschalt: Proportionales Skalieren." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6228,9 +6236,8 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected Node(s)" -msgstr "Sperren ausgewählt" +msgstr "Gewählte Nodes sperren" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6239,9 +6246,8 @@ msgstr "Das ausgewählte Objekt entsperren (kann bewegt werden)." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected Node(s)" -msgstr "Auswahl entsperren" +msgstr "Gewählte Nodes entsperren" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6250,9 +6256,8 @@ msgstr "Verhindert das Auswählen von Unterobjekten dieses Nodes." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected Node(s)" -msgstr "Auswahl gruppieren" +msgstr "Gewählte Nodes gruppieren" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6261,9 +6266,8 @@ msgstr "Stellt die Auswählbarkeit aller Unterobjekte wieder her." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected Node(s)" -msgstr "Auswahl entgruppieren" +msgstr "Gruppierung gewählter Nodes auflösen" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Skeleton Options" @@ -6436,6 +6440,7 @@ msgid "Zoom to 1600%" msgstr "Auf 1600% vergrößern" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "%s hinzufügen" @@ -7914,9 +7919,8 @@ msgid "Find in Files..." msgstr "In Dateien suchen..." #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Replace in Files..." -msgstr "Ersetzen..." +msgstr "In Dateien ersetzen..." #: editor/plugins/script_text_editor.cpp msgid "Contextual Help" @@ -8449,16 +8453,15 @@ msgstr "Freie Kamera umschalten" #: editor/plugins/spatial_editor_plugin.cpp msgid "Decrease Field of View" -msgstr "" +msgstr "Sichtfeld verkleinern" #: editor/plugins/spatial_editor_plugin.cpp msgid "Increase Field of View" -msgstr "" +msgstr "Sichtfeld vergrößern" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Reset Field of View to Default" -msgstr "Auf Standardwerte zurücksetzen" +msgstr "Sichtfeld auf Standardwert zurücksetzen" #: editor/plugins/spatial_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9190,22 +9193,19 @@ msgstr "Typ hinzufügen" #: editor/plugins/theme_editor_plugin.cpp msgid "Filter the list of types or create a new custom type:" -msgstr "" +msgstr "Liste der Typen filtern oder neuen Typ anlegen:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Available Node-based types:" -msgstr "Verfügbare Profile:" +msgstr "Verfügbare Node-basierte Typen:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Type name is empty!" -msgstr "Dateiname ist leer." +msgstr "Name des Typs ist leer!" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Are you sure you want to create an empty type?" -msgstr "Sollen wirklich mehrere Projekte geöffnet werden?" +msgstr "Soll wirklich ein leerer Typ erstellt werden?" #: editor/plugins/theme_editor_plugin.cpp msgid "Confirm Item Rename" @@ -9830,7 +9830,8 @@ msgid "TileSet" msgstr "Kachelsatz" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "Keine Versionsverwaltungserweiterungen verfügbar." #: editor/plugins/version_control_editor_plugin.cpp @@ -9838,16 +9839,56 @@ msgid "Error" msgstr "Fehler" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "Es wurden keine Dateien zum protokollieren vorgemerkt" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Kein Name angegeben." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "Speicherpunkt" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "Versionsverwaltungserweiterung ist nicht initialisiert" +#, fuzzy +msgid "Staged Changes" +msgstr "Shader-Änderungen:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Shader-Änderungen:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Speicherpunkt" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Unterbaum" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Soll wirklich ein leerer Typ erstellt werden?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Zurücksetzen durchführen" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9858,16 +9899,148 @@ msgid "Initialize" msgstr "Initialisieren" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "Speicherauswahlbereich" +#, fuzzy +msgid "Remote Login" +msgstr "Punkt entfernen" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Umbenennen" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Neue Veränderungen beachten" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Veränderungen" +#, fuzzy +msgid "Discard all changes" +msgstr "Schließen und Änderungen speichern?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Speichere lokale Änderungen..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Materialänderungen:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Änderungen als Speicherpunkt sichern" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "Änderungen als Speicherpunkt sichern" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Speicherpunkt" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Treffer:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Erstelle neues Projekt" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Spur entfernen" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Fern" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Erstelle neues Projekt" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Entferne Element" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Fern " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Fern " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Quell-Mesh:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9886,30 +10059,23 @@ msgid "Typechange" msgstr "Dateitypänderung" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "Ausgewähltes zum speichern vormerken" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "Alles zum speichern vormerken" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "Änderungen als Speicherpunkt sichern" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "" -"Dateiänderungen anzeigen bevor sie nach der aktuellsten Version gespeichert " -"werden" +#, fuzzy +msgid "View:" +msgstr "Ansicht" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "Kein Dateiunterschied ist aktiv" +#, fuzzy +msgid "Split" +msgstr "Pfad aufteilen" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "Änderungen in Dateiänderung verfolgen" +#, fuzzy +msgid "Unified" +msgstr "Bearbeitet" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12068,6 +12234,11 @@ msgid "" "To save this branch into its own scene, open the original scene, right click " "on this branch, and select \"Save Branch as Scene\"." msgstr "" +"Ein Zweig, der unter einer bereits instantiierten Szene eingehängt ist, kann " +"nicht gespeichert werden.\n" +"Um den Zweig als eigene Szene zu speichern, muss er in der originalen Szene " +"ausgewählt und mittels Rechtsklick auf ihn und folgendem Klick auf „Zweig " +"als Szene speichern“ gespeichert werden." #: editor/scene_tree_dock.cpp msgid "" @@ -12075,6 +12246,11 @@ msgid "" "To save this branch into its own scene, open the original scene, right click " "on this branch, and select \"Save Branch as Scene\"." msgstr "" +"Ein Zweig, der Teil einer instantiierten Szene ist, kann nicht gespeichert " +"werden.\n" +"Um den Zweig als eigene Szene zu speichern, muss er in der originalen Szene " +"ausgewählt und mittels Rechtsklick auf ihn und folgendem Klick auf „Zweig " +"als Szene speichern“ gespeichert werden." #: editor/scene_tree_dock.cpp msgid "Save New Scene As..." @@ -12615,6 +12791,7 @@ msgid "Export list to a CSV file" msgstr "Liste als CSV-Datei exportieren" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Ressourcenpfad" @@ -13465,6 +13642,40 @@ msgstr "Graph aktualisieren" msgid "Edit Member" msgstr "Mitglied bearbeiten" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Ausdruck eintragen" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Animation" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Eingabetyp nicht wiederholbar: " @@ -13477,6 +13688,88 @@ msgstr "Iterator wurde ungültig" msgid "Iterator became invalid: " msgstr "Iterator wurde ungültig: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Benenne Ordner um:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Neigung:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Typen:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Selbst" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Bei Zeichen %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "%s hinzufügen" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "%s setzen" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "%s angeheftet" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "%s abrufen" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Ungültiger Name der Index-Eigenschaft." @@ -13493,6 +13786,21 @@ msgstr "Pfad führt nicht zu einem Node!" msgid "Invalid index property name '%s' in node %s." msgstr "Ungültiger Indexeigenschaftsname ‚%s‘ in Node %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "%s setzen" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funktionen" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Größe des Arrays ändern" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Ungültiger Parameter vom Typ: " @@ -13502,6 +13810,10 @@ msgid ": Invalid arguments: " msgstr ": Ungültige Parameter: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet nicht im Skript gefunden: " @@ -13510,6 +13822,66 @@ msgid "VariableSet not found in script: " msgstr "VariableSet nicht im Skript gefunden: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Neu laden" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Z-Index" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Z-Index" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Konstante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Konstante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Konstante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Konstante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "GDNative Singleton wurde aktiviert" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Zeitsuch-Node" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Szenenbaum-Bearbeitung" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Selbst" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Nodes trennen" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" "Eigens erstelltes Node hat keine _step()-Methode, Graph kann nicht " @@ -13523,13 +13895,75 @@ msgstr "" "Ungültiger Rückgabewert von _step(), muss Integer (für Sequenzausgabe) oder " "String (für Fehler) sein." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Aufrufe" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Konstanten" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Lokalkoordinaten verwenden" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Lokalkoordinaten verwenden" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Aktion" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "VisualScript suchen" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "%s abrufen" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Frame verschieben" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Physik-relative Renderzeit %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Ereignis" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Ereignis" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instanz" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14150,13 +14584,15 @@ msgstr "" #: scene/2d/navigation_agent_2d.cpp msgid "The NavigationAgent2D can be used only under a Node2D node." -msgstr "" +msgstr "NavigationAgent2D kann nur unter einem Node2D-Node genutzt werden." #: scene/2d/navigation_obstacle_2d.cpp msgid "" "The NavigationObstacle2D only serves to provide collision avoidance to a " "Node2D object." msgstr "" +"Der einzige Zweck eines NavigationObstacle2D ist es, Kollisionsvermeidung " +"für ein Node2D-Objekt bereitzustellen." #: scene/2d/navigation_polygon.cpp msgid "" @@ -14184,15 +14620,25 @@ msgstr "" "ParallaxBackground-Node verwenden." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "GPU-basierte Partikel werden vom GLES2-Grafiktreiber nicht unterstützt.\n" "Stattdessen bitte CPUParticles2D-Nodes verwenden. Die „In CPU-Partikel " "konvertieren“-Funktion kann dazu verwendet werden." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14428,7 +14874,7 @@ msgstr "" #: scene/3d/navigation_agent.cpp msgid "The NavigationAgent can be used only under a spatial node." -msgstr "" +msgstr "NavigationAgent kann nur unter einem Spatial-Node genutzt werden." #: scene/3d/navigation_mesh_instance.cpp msgid "" @@ -14443,6 +14889,8 @@ msgid "" "The NavigationObstacle only serves to provide collision avoidance to a " "spatial object." msgstr "" +"Der einzige Zweck eines NavigationObstacle ist es, Kollisionsvermeidung für " +"ein Spatial-Objekt bereitzustellen." #: scene/3d/occluder.cpp msgid "No shape is set." @@ -14453,10 +14901,11 @@ msgid "Only uniform scales are supported." msgstr "Es werden nur gleichförmige Skalierungen unterstützt." #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "GPU-basierte Partikel werden vom GLES2-Grafiktreiber nicht unterstützt.\n" "Stattdessen bitte CPUParticles-Nodes verwenden. Die „In CPU-Partikel " @@ -14464,6 +14913,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" "Nichts ist sichtbar da keine Meshe den Zeichendurchläufen zugewiesen wurden." diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot index ab1796503c..e41400290d 100644 --- a/editor/translations/editor.pot +++ b/editor/translations/editor.pot @@ -352,6 +352,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -801,6 +802,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -850,8 +852,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1874,7 +1875,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -1991,7 +1991,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2159,7 +2160,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2189,6 +2190,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2882,7 +2885,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3017,10 +3020,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3237,6 +3236,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3313,7 +3313,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3538,6 +3537,11 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +msgid "%s Error" +msgstr "" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4393,6 +4397,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6036,6 +6041,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9318,7 +9324,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9326,7 +9332,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9334,7 +9345,35 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9346,39 +9385,55 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +msgid "Remote Login" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect new changes" +msgid "Username" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Password" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "SSH Public Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +msgid "Select SSH public key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" +msgid "SSH Private Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect new changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +msgid "Stage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Unstage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9386,15 +9441,107 @@ msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Commit List" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Create New Branch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Remove Branch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remotes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remove Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote URL" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -11903,6 +12050,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12731,6 +12879,38 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Condition" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12743,6 +12923,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12759,6 +13013,18 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Function" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12768,6 +13034,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12776,6 +13046,54 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Node" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Tree" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "CustomNode" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12785,12 +13103,64 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Action %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13352,7 +13722,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13565,7 +13944,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/el.po b/editor/translations/el.po index 1235fd00fe..b24b443b09 100644 --- a/editor/translations/el.po +++ b/editor/translations/el.po @@ -371,6 +371,7 @@ msgstr "ΔημιουÏγία %d νÎων κομματιών και εισαγωΠ#: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -847,6 +848,7 @@ msgstr "Î Ïοσθήκη" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -898,8 +900,7 @@ msgstr "ΑδÏνατη η σÏνδεση σήματος" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1980,7 +1981,6 @@ msgid "New Folder..." msgstr "ÎÎος φάκελος..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "ΑνανÎωση" @@ -2097,7 +2097,8 @@ msgstr "Φάκελοι & ΑÏχεία:" msgid "Preview:" msgstr "Î Ïοεπισκόπηση:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "ΑÏχείο:" @@ -2276,7 +2277,7 @@ msgstr "ΜÎθοδος" msgid "Signal" msgstr "Σήμα" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "ΣταθεÏή" @@ -2307,6 +2308,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "ΘÎσε %s" @@ -3073,8 +3076,9 @@ msgid "Install Android Build Template..." msgstr "Εγκατάσταση Î ÏοτÏπου Δόμησης Android..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Άνοιγμα φακÎλου δεδομÎνων ÎÏγου" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Άνοιγμα φακÎλου δεδομÎνων επεξεÏγαστή" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3236,10 +3240,6 @@ msgid "Toggle Fullscreen" msgstr "Εναλλαγή πλήÏους οθόνης" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Εναλλαγή Κονσόλας Συστήματος" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Άνοιγμα φακÎλου δεδομÎνων/Ïυθμίσεων επεξεÏγαστή" @@ -3479,6 +3479,7 @@ msgid "Load Errors" msgstr "Σφάλματα φόÏτωσης" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Επιλογή" @@ -3559,7 +3560,6 @@ msgid "Author" msgstr "ΣυγγÏαφείς" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Κατάσταση" @@ -3800,6 +3800,12 @@ msgstr "ΔιαδÏομή σκηνής:" msgid "Import From Node:" msgstr "Εισαγωγή σκηνής από κόμβο:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Σφάλμα" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4719,6 +4725,7 @@ msgid "Subfolder:" msgstr "Υποφάκελος:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "ΣυγγÏαφÎας:" @@ -6441,6 +6448,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Î Ïόσθεσε %s" @@ -9939,7 +9947,8 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "ΚανÎνα Ï€Ïόσθετο VCS δεν είναι διαθÎσιμο." #: editor/plugins/version_control_editor_plugin.cpp @@ -9947,16 +9956,56 @@ msgid "Error" msgstr "Σφάλμα" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "ΚανÎνα αÏχείο δεν Ï€ÏοστÎθηκε στο στάδιο" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Δεν δόθηκε όνομα." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "Υποβολή" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "Το Î Ïόσθετο VCS δεν αÏχικοποιήθηκε" +#, fuzzy +msgid "Staged Changes" +msgstr "ΑλλαγÎÏ‚ Ï€ÏογÏάμματος σκίασης" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "ΑλλαγÎÏ‚ Ï€ÏογÏάμματος σκίασης" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Υποβολή" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "ΥπόδεντÏο" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Είστε σίγουÏοι πως θÎλετε να ανοίξετε πεÏισσότεÏα από Îνα ÎÏγα;" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "ΕπαναφοÏά" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9967,16 +10016,148 @@ msgid "Initialize" msgstr "ΑÏχικοποιήστε" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "Σταθμός ανάπαυσης" +#, fuzzy +msgid "Remote Login" +msgstr "ΑφαίÏεση Σημείου" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Μετονομασία" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Εντόπισε νÎες αλλαγÎÏ‚" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "ΑλλαγÎÏ‚" +#, fuzzy +msgid "Discard all changes" +msgstr "Κλείσιμο και αποθήκευση αλλαγών;" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Αποθήκευση τοπικών αλλαγών..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "ΑλλαγÎÏ‚ υλικοÏ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "ΑλλαγÎÏ‚ ΔÎσμευσης" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "ΑλλαγÎÏ‚ ΔÎσμευσης" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Υποβολή" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Αντιστοιχίες:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "ΔημιουÏγία νÎου ÎÏγου" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "ΑφαίÏεση ÎšÎ¿Î¼Î¼Î±Ï„Î¹Î¿Ï ÎšÎ¯Î½Î·ÏƒÎ·Ï‚" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "ΑπομακÏυσμÎνο" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "ΔημιουÏγία νÎου ÎÏγου" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "ΑφαίÏεση στοιχείου" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "ΑπομακÏυσμÎνο " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "ΑπομακÏυσμÎνο " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Πηγαίο πλÎγμα:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9995,28 +10176,23 @@ msgid "Typechange" msgstr "ΑλλαγήτÏπου" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "Στάδιο ΕπιλÎχθηκε" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "Διεξαγωγή Όλων" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "ΑλλαγÎÏ‚ ΔÎσμευσης" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "Δείτε τις διαφοÏÎÏ‚ αÏχείων Ï€Ïιν τις δεσμεÏσετε στην τελική Îκδοση" +#, fuzzy +msgid "View:" +msgstr "ΘÎα" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "Καμία διαφοÏά αÏχείων δεν είναι ενεÏγή" +#, fuzzy +msgid "Split" +msgstr "ΔιαχωÏισμός διαδÏομής" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "ΕλÎγξτε αλλαγÎÏ‚ στις διαφοÏÎÏ‚ αÏχείων" +#, fuzzy +msgid "Unified" +msgstr "ΤÏοποποιήθηκε" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12726,6 +12902,7 @@ msgid "Export list to a CSV file" msgstr "Εξαγωγή λίστας σε αÏχείο CSV" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "ΔιαδÏομή πόÏου" @@ -13593,6 +13770,40 @@ msgstr "ΑνανÎωση ΓÏαφήματος" msgid "Edit Member" msgstr "ΕπεξεÏγασία ΜÎλους" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "ΟÏισμός ÎκφÏασης" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Κίνηση" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Δεν μποÏεί να γίνει επανάληψη στον εισηγμÎνο Ï„Ïπο: " @@ -13605,6 +13816,88 @@ msgstr "Ο επαναλήπτης Îγινε άκυÏος" msgid "Iterator became invalid: " msgstr "Ο επαναλήπτης Îγινε άκυÏος: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Μετονομασία καταλόγου:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Τόνος" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "ΤÏπος:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Εαυτός" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Στον χαÏακτήÏα %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Î Ïόσθεσε %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "ΘÎσε %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Î Ïόσθεσε %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Διάβασε %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "ΆκυÏο όνομα ιδιότητας δείκτη." @@ -13621,6 +13914,21 @@ msgstr "Η διαδÏομή δεν οδηγεί σε κόμβο!" msgid "Invalid index property name '%s' in node %s." msgstr "ΆκυÏο όνομα ιδιότητας δείκτη '%s' στον κόμβο %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "ΘÎσε %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "ΣυναÏτήσεις" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Αλλαγή μεγÎθους πίνακα" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": ΆκυÏη παÏάμετÏος Ï„Ïπου: " @@ -13630,6 +13938,10 @@ msgid ": Invalid arguments: " msgstr ": ΆκυÏοι παÏάμετÏοι: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "Το VariableGet δεν βÏÎθηκε στη δÎσμη ενεÏγειών: " @@ -13638,6 +13950,66 @@ msgid "VariableSet not found in script: " msgstr "Το VariableSet δεν βÏÎθηκε στη δÎσμη ενεÏγειών: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "ΕπαναφόÏτωση" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Δείκτης Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Δείκτης Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "ΣταθεÏή" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "ΣταθεÏή" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "ΣταθεÏή" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "ΣταθεÏή" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "ΕνεÏγοποίηση Μονοσυνόλου GDNative" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Κόμβος εÏÏεσης χÏόνου" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "ΕπεξεÏγασία ΔÎντÏου Σκηνής" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Εαυτός" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Αποκοπή κόμβων" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" "Ο κόμβος δεν Îχει τη μÎθοδο _step(), αδÏνατη η επεξεÏγασία του γÏαφήματος." @@ -13650,13 +14022,75 @@ msgstr "" "ΆκυÏος Ï„Ïπος επιστÏοφής από την _step(), Ï€ÏÎπει να είναι ακÎÏαιος (seq out) " "ή ακολουθία χαÏακτήÏων (error)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Κλήσεις" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "ΣταθεÏÎÏ‚" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "ΧÏησιμοποιείστε Τοπικό ΧώÏο" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "ΧÏησιμοποιείστε Τοπικό ΧώÏο" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "ΕνÎÏγεια" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Αναζήτηση VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Διάβασε %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Μετακίνηση ΚαÏÎ" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "KαÏΠφυσικής %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Σήμα" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Σήμα" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Στιγμιότυπο" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14310,15 +14744,25 @@ msgstr "" "ParallaxBackground." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "Τα σωματίδια GPU δεν υποστηÏίζονται από τον οδηγό βίντεο GLES2.\n" "ΧÏησιμοποιήστε τον κόμβο CPUParticles2D. ΜποÏείτε να χÏησιμοποιήσετε την " "επιλογή «Convert to CPUParticles» για αυτόν τον σκοπό." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14578,10 +15022,11 @@ msgid "Only uniform scales are supported." msgstr "" #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "Τα σωματίδια GPU δεν υποστηÏίζονται από τον οδηγό βίντεο GLES2.\n" "ΧÏησιμοποιήστε τον κόμβο CPUParticles. ΜποÏείτε να χÏησιμοποιήσετε την " @@ -14589,6 +15034,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" "Τίποτα δεν είναι οÏατό, επειδή δεν Îχουν οÏιστεί πεÏάσματα για τα πλÎγματα." diff --git a/editor/translations/eo.po b/editor/translations/eo.po index f3aa813e83..0049194bfe 100644 --- a/editor/translations/eo.po +++ b/editor/translations/eo.po @@ -366,6 +366,7 @@ msgstr "Krei %d NOVAJN trakojn kaj enmeti Ålosilojn?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -833,6 +834,7 @@ msgstr "Aldoni" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -884,8 +886,7 @@ msgstr "Ne povas konekti signalo" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1949,7 +1950,6 @@ msgid "New Folder..." msgstr "Nova dosierujo..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Aktualigi" @@ -2066,7 +2066,8 @@ msgstr "Dosierujoj kaj dosieroj:" msgid "Preview:" msgstr "AntaÅrigardo:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Dosiero:" @@ -2242,7 +2243,7 @@ msgstr "Metodo" msgid "Signal" msgstr "Signalo" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Konstanto" @@ -2273,6 +2274,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Agordis %s" @@ -3028,8 +3031,9 @@ msgid "Install Android Build Template..." msgstr "Instali Androidan muntadan Åablonon..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Malfermi projektan datuman dosierujon" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Malfermi datumajn dosierujon de la redaktilo" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3187,10 +3191,6 @@ msgid "Toggle Fullscreen" msgstr "Baskuli plenekranon" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Baskuli la konzolon de sistemo" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Malfermi datumajn/agordajn dosierujon de la redaktilo" @@ -3416,6 +3416,7 @@ msgid "Load Errors" msgstr "Åœargaj eraroj" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Elekti" @@ -3497,7 +3498,6 @@ msgid "Author" msgstr "AÅtoroj" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3740,6 +3740,12 @@ msgstr "Scena dosierindiko:" msgid "Import From Node:" msgstr "Enporti el nodo:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Eraro!" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4654,6 +4660,7 @@ msgid "Subfolder:" msgstr "Subdosierujo:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "AÅtoro:" @@ -6358,6 +6365,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Aldoni %s" @@ -9759,7 +9767,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9767,18 +9775,57 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Ne nomon provizis." + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "ÅœanÄu" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "ÅœanÄu" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Komunumo" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Ĉu vi certe volas malfermi plurajn projektojn?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Almeti rekomencigon" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -9787,7 +9834,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Forigi punkton" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Renomi" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9796,54 +9873,147 @@ msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Changes" +msgid "Discard all changes" +msgstr "Parametro ÅanÄiÄis" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Memoras lokajn ÅanÄojn..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Parametro ÅanÄiÄis" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" msgstr "ÅœanÄu" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" -msgstr "Modifita" +#, fuzzy +msgid "Commit Changes" +msgstr "ÅœanÄu" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +#, fuzzy +msgid "Commit List" +msgstr "ÅœanÄu" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "Forigi Åœlosilo(j)n" +msgid "Branches" +msgstr "Matĉoj:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Typechange" -msgstr "ÅœanÄu" +msgid "Create New Branch" +msgstr "Krei novan projekton" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "Skali Elektaron" +msgid "Remove Branch" +msgstr "Forigi animacian trakon" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "Elektaro ĉiuj" +msgid "Remotes" +msgstr "Fora" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" -msgstr "ÅœanÄu" +msgid "Create New Remote" +msgstr "Krei novan projekton" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Forigi elementon" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Fora " #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +#, fuzzy +msgid "Remote URL" +msgstr "Fora " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Pull" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Push" msgstr "" +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Risurca Vojo" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "Modifita" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "Forigi Åœlosilo(j)n" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Typechange" +msgstr "ÅœanÄu" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "View:" +msgstr "Vido" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unified" +msgstr "Modifita" + #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" msgstr "" @@ -12423,6 +12593,7 @@ msgid "Export list to a CSV file" msgstr "Eksporti liston al CSV dosiero" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Risurca Vojo" @@ -13270,6 +13441,40 @@ msgstr "Aktualigi" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Uzi regulesprimojn" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animacio" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -13282,6 +13487,86 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Renomas dosierujon:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Tipo" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Memo" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Aldoni %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Agordis %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Aldoni %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -13298,6 +13583,21 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Agordis %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funkcioj:" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Regrandigi Vicon" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -13307,6 +13607,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -13315,6 +13619,65 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "ReÅargi" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Indekso:" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Defini stirilon" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Konstanto" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Konstanto" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Konstanto" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Konstanto" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Nova radiko de sceno" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Redaktado de scenoarbo" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Memo" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Eltondi nodo(j)n" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -13324,14 +13687,76 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Alvokoj" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Konstantoj" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Uzi lokan spacon" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Uzi lokan spacon" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Faro" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Posta tabo" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Fiziko-kadro %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" msgstr "" +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Signalo" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Signalo" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Ekzemplodoni" + #: platform/android/export/export_plugin.cpp msgid "Package name is missing." msgstr "" @@ -13911,7 +14336,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14124,7 +14558,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/es.po b/editor/translations/es.po index 156a3a5ec5..058549cbd4 100644 --- a/editor/translations/es.po +++ b/editor/translations/es.po @@ -72,13 +72,14 @@ # davidrogel <david.rogel.pernas@icloud.com>, 2021. # Anderson Guzman Abreu <chicobello1111@gmail.com>, 2021. # Manuel Cantón Guillén <manuelcanton8@gmail.com>, 2021. +# Alfonso V <alfonsov96@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-12-21 10:39+0000\n" -"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n" +"PO-Revision-Date: 2022-01-12 16:52+0000\n" +"Last-Translator: Alfonso V <alfonsov96@gmail.com>\n" "Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/" "godot/es/>\n" "Language: es\n" @@ -86,7 +87,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.10\n" +"X-Generator: Weblate 4.10.1\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -430,6 +431,7 @@ msgstr "¿Crear %d nuevas pistas e insertar claves?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -901,6 +903,7 @@ msgstr "Añadir" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -952,8 +955,7 @@ msgstr "No se puede conectar la señal" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -2027,7 +2029,6 @@ msgid "New Folder..." msgstr "Nueva Carpeta..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Recargar" @@ -2144,7 +2145,8 @@ msgstr "Directorios y Archivos:" msgid "Preview:" msgstr "Vista Previa:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Archivo:" @@ -2175,7 +2177,7 @@ msgstr "Clase:" #: editor/editor_help.cpp editor/scene_tree_editor.cpp #: editor/script_create_dialog.cpp msgid "Inherits:" -msgstr "Hereda:" +msgstr "Hereda de:" #: editor/editor_help.cpp msgid "Inherited by:" @@ -2319,7 +2321,7 @@ msgstr "Método" msgid "Signal" msgstr "Señal" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Constante" @@ -2350,6 +2352,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Establecer %s" @@ -2947,8 +2951,9 @@ msgstr "Eliminar Layout" #: editor/editor_node.cpp editor/import_dock.cpp #: editor/script_create_dialog.cpp +#, fuzzy msgid "Default" -msgstr "Predeterminado" +msgstr "Por defecto" #: editor/editor_node.cpp editor/editor_resource_picker.cpp #: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp @@ -3115,8 +3120,9 @@ msgid "Install Android Build Template..." msgstr "Instalar plantilla de compilación de Android..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Abrir Carpeta de Datos del Proyecto" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Abrir Carpeta de Editor de Datos" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3276,10 +3282,6 @@ msgid "Toggle Fullscreen" msgstr "Cambiar a Pantalla Completa" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Act./Desact. Consola del Sistema" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Abrir Editor de Datos/Carpeta de Configuración" @@ -3512,6 +3514,7 @@ msgid "Load Errors" msgstr "Errores de carga" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Seleccionar" @@ -3588,7 +3591,6 @@ msgid "Author" msgstr "Autor" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Estado" @@ -3834,6 +3836,12 @@ msgstr "Ruta de la Escena:" msgid "Import From Node:" msgstr "Importar Desde Nodo:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Error" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "Abra la carpeta que contiene estas plantillas." @@ -4730,6 +4738,7 @@ msgid "Subfolder:" msgstr "Subcarpeta:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Autor:" @@ -6436,6 +6445,7 @@ msgid "Zoom to 1600%" msgstr "Zoom al 1600%" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Añadir %s" @@ -9824,7 +9834,8 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "No hay addons de VCS disponibles." #: editor/plugins/version_control_editor_plugin.cpp @@ -9832,16 +9843,56 @@ msgid "Error" msgstr "Error" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "No se agregaron archivos al stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Nombre no proporcionado." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "Confirmar" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "El Addon de VCS no está inicializado" +#, fuzzy +msgid "Staged Changes" +msgstr "Cambios de sombreado:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Cambios de sombreado:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Confirmar" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Subárbol" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "¿Seguro que quieres abrir más de un proyecto?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Aplicar Restablecer" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9852,16 +9903,148 @@ msgid "Initialize" msgstr "Inicializar" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "Ãrea de Staging" +#, fuzzy +msgid "Remote Login" +msgstr "Eliminar Punto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Renombrar" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Detectar nuevos cambios" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Cambios" +#, fuzzy +msgid "Discard all changes" +msgstr "¿Cerrar y guardar cambios?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Guardando cambios locales..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Cambios del Material:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Confirmar Cambios" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "Confirmar Cambios" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Confirmar" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Coincidencias:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Crear Nuevo Proyecto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Eliminar Pista de Animación" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Remoto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Crear Nuevo Proyecto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Eliminar Elemento" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Remoto " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Remoto " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Malla de Origen:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9880,29 +10063,23 @@ msgid "Typechange" msgstr "Cambio de Tipo" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "Hacer Staging de Selección" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "Hacer Staging de Todo" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "Confirmar Cambios" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "" -"Ver las diferencias de los archivos antes de confirmar la última versión" +#, fuzzy +msgid "View:" +msgstr "Ver" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "No hay diferencias de archivo disponibles" +#, fuzzy +msgid "Split" +msgstr "Dividir Ruta" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "Detectar diferencias entre los archivos" +#, fuzzy +msgid "Unified" +msgstr "Modificado/s" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12607,6 +12784,7 @@ msgid "Export list to a CSV file" msgstr "Exportar lista a un archivo CSV" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Ruta de Recursos" @@ -13458,6 +13636,40 @@ msgstr "Refrescar Gráfico" msgid "Edit Member" msgstr "Editar Miembro" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Establecer expresión" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animación" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "El tipo de entrada no es iterable: " @@ -13470,6 +13682,88 @@ msgstr "El iterador ya no es correcto" msgid "Iterator became invalid: " msgstr "El iterador ya no es correcto: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Renombrar carpeta:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Eje de paso:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Tipos:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Propio" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "En el carácter %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Añadir %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Establecer %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Añadir %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Obtener %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Ãndice del nombre de la propiedad inválido." @@ -13486,6 +13780,21 @@ msgstr "¡La ruta no apunta a un Nodo!" msgid "Invalid index property name '%s' in node %s." msgstr "Ãndice inválido de nombre de propiedad '%s' en el nodo %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Establecer %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funciones" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Redimensionar Array" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Argumento incorrecto de tipo: " @@ -13495,6 +13804,10 @@ msgid ": Invalid arguments: " msgstr ": Argumentos incorrectos: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet no encontrado en el script: " @@ -13503,6 +13816,66 @@ msgid "VariableSet not found in script: " msgstr "VariableSet no encontrado en el script: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Recargar" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Ãndice Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Ãndice Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "Activar Singleton GDNative" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Nodo TimeSeek" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Editor del Ãrbol de Escenas" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Propio" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Cortar Nodos" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" "El nodo personalizado no tiene ningún método _step(), no se puede procesar " @@ -13516,13 +13889,75 @@ msgstr "" "El valor devuelto por _step() no es correcto, debe ser un entero (seq out), " "o string/cadena (error)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Llamadas" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Constantes" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Usar Espacio Local" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Usar Espacio Local" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Acción" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Buscar en VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Obtener %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Mover Fotograma" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Fotogramas de FÃsica %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Señal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Señal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instanciar" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14190,16 +14625,26 @@ msgstr "" "nodo ParallaxBackground." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "Las partÃculas basadas en la GPU no son compatibles con el controlador de " "vÃdeo GLES2.\n" "En su lugar, utiliza el nodo CPUParticles2D. Para ello puedes utilizar la " "opción \"Convertir a CPUParticles\"." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14452,10 +14897,11 @@ msgid "Only uniform scales are supported." msgstr "Sólo se admiten escalas uniformes." #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "Las partÃculas basadas en la GPU no son compatibles con el controlador de " "vÃdeo GLES2.\n" @@ -14464,6 +14910,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" "No hay nada visible porque no se han asignado mallas para los pases de " diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po index 23020a7573..b7dd76951e 100644 --- a/editor/translations/es_AR.po +++ b/editor/translations/es_AR.po @@ -376,6 +376,7 @@ msgstr "Crear %d NUEVOS tracks e insertar claves?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -845,6 +846,7 @@ msgstr "Agregar" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -896,8 +898,7 @@ msgstr "No se puede conectar la señal" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1969,7 +1970,6 @@ msgid "New Folder..." msgstr "Nueva Carpeta..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Refrescar" @@ -2086,7 +2086,8 @@ msgstr "Directorios y Archivos:" msgid "Preview:" msgstr "Vista Previa:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Archivo:" @@ -2261,7 +2262,7 @@ msgstr "Método" msgid "Signal" msgstr "Señal" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Constante" @@ -2292,6 +2293,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Asignar %s" @@ -3058,8 +3061,9 @@ msgid "Install Android Build Template..." msgstr "Instalar Plantilla de Compilación de Android..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Abrir Carpeta de Datos del Proyecto" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Abrir Carpeta de Datos del Editor" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3217,10 +3221,6 @@ msgid "Toggle Fullscreen" msgstr "Act./Desact. Pantalla Completa" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Act/Desact. Consola de Sistema" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Abrir Carpeta de Datos/Configuración del Editor" @@ -3453,6 +3453,7 @@ msgid "Load Errors" msgstr "Erroes de carga" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Seleccionar" @@ -3529,7 +3530,6 @@ msgid "Author" msgstr "Autor" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Estado" @@ -3774,6 +3774,12 @@ msgstr "Ruta a la Escena:" msgid "Import From Node:" msgstr "Importar Desde Nodo:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Error" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "Abrir la carpeta que contiene estas plantillas." @@ -4672,6 +4678,7 @@ msgid "Subfolder:" msgstr "Subcarpeta:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Autor:" @@ -6376,6 +6383,7 @@ msgid "Zoom to 1600%" msgstr "Zoom a 1600%" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Agregar %s" @@ -9756,7 +9764,8 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "No hay addons de VCS disponibles." #: editor/plugins/version_control_editor_plugin.cpp @@ -9764,16 +9773,56 @@ msgid "Error" msgstr "Error" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "No se agregaron archivos al stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "No se indicó ningún nombre." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "Commit" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "El Addon de VCS no está inicializado" +#, fuzzy +msgid "Staged Changes" +msgstr "Cambios de Shaders:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Cambios de Shaders:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Commit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Subárbol" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "¿Estás seguro/a que quieres abrir más de un proyecto?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Aplicar Reset" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9784,16 +9833,148 @@ msgid "Initialize" msgstr "Inicializar" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "Ãrea de Staging" +#, fuzzy +msgid "Remote Login" +msgstr "Quitar Punto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Renombrar" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Detectar nuevos cambios" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Cambios" +#, fuzzy +msgid "Discard all changes" +msgstr "¿Cerrar y guardar cambios?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Guardando cambios locales..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Cambios de Material:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Commitear Cambios" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "Commitear Cambios" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Commit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Coincidencias:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Crear Proyecto Nuevo" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Quitar pista de animación" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Remoto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Crear Proyecto Nuevo" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Remover Item" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Remoto " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Remoto " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Mesh de Origen:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9812,28 +9993,23 @@ msgid "Typechange" msgstr "Cambio de Tipo" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "Hacer Staging de Selección" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "Hacer Staging de Todo" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "Commitear Cambios" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "Ver diferencias de archivos antes de commitearlos a la última versión" +#, fuzzy +msgid "View:" +msgstr "Vista" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "No hay ningún diff de archivos activo" +#, fuzzy +msgid "Split" +msgstr "Partir Path" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "Detectar cambios en el diff de archivo" +#, fuzzy +msgid "Unified" +msgstr "Modificado/s" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12542,6 +12718,7 @@ msgid "Export list to a CSV file" msgstr "Exportar lista a un archivo CSV" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Ruta de Recursos" @@ -13389,6 +13566,40 @@ msgstr "Refrescar el Gráfico" msgid "Edit Member" msgstr "Editar Miembros" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Establecer expresión" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animación" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Tipo de input no iterable: " @@ -13401,6 +13612,88 @@ msgstr "El iterador se volvió inválido" msgid "Iterator became invalid: " msgstr "El iterador se volvió inválido: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Renombrar carpeta:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Cabeceo:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Tipos:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Propio" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "En el carácter %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Agregar %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Asignar %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Agregar %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Obtener %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Nombre de propiedad indÃce inválido." @@ -13417,6 +13710,21 @@ msgstr "La ruta no apunta a un Nodo!" msgid "Invalid index property name '%s' in node %s." msgstr "Nombre de propiedad Ãndice '%s' inválido en nodo %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Asignar %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funciones" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Redimensionar Array" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Argumento inválido de tipo: " @@ -13426,6 +13734,10 @@ msgid ": Invalid arguments: " msgstr ": Argumentos inválidos: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet no encontrado en el script: " @@ -13434,6 +13746,66 @@ msgid "VariableSet not found in script: " msgstr "VariableSet no encontrado en el script: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Volver a Cargar" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Z Index" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Z Index" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "Activar Singleton GDNative" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Nodo TimeSeek" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Edición de Ãrbol de Escenas" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Propio" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Cortar Nodos" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" "El nodo personalizado no tiene ningún método _step(), no se puede procesar " @@ -13447,13 +13819,75 @@ msgstr "" "Valor de retorno inválido de _step(), debe ser un entero (seq out), o string " "(error)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Llamadas" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Constantes" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Usar Espacio Local" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Usar Espacio Local" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Acción" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Buscar en VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Obtener %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Mover Fotograma" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Frames de FÃsica %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Señal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Señal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instancia" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14115,16 +14549,26 @@ msgstr "" "ParallaxBackground." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "Las partÃculas basadas en la GPU no son compatibles con el controlador de " "vÃdeo GLES2.\n" "En su lugar, utiliza el nodo CPUParticles2D. Para ello podés utilizar la " "opción \"Convertir a CPUParticles\"." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14378,10 +14822,11 @@ msgid "Only uniform scales are supported." msgstr "Sólo se admiten escalas uniformes." #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "Las partÃculas basadas en la GPU no son compatibles con el controlador de " "vÃdeo GLES2.\n" @@ -14390,6 +14835,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "Nada visible ya que no se asigno pasadas de dibujado a los meshes." diff --git a/editor/translations/et.po b/editor/translations/et.po index acb2a18bcf..db162ecca8 100644 --- a/editor/translations/et.po +++ b/editor/translations/et.po @@ -360,6 +360,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -817,6 +818,7 @@ msgstr "Lisa" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -866,8 +868,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1930,7 +1931,6 @@ msgid "New Folder..." msgstr "Uus kaust..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Värskenda" @@ -2047,7 +2047,8 @@ msgstr "Kataloogid ja failid:" msgid "Preview:" msgstr "Eelvaade:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Fail:" @@ -2218,7 +2219,7 @@ msgstr "Meetod" msgid "Signal" msgstr "Signaal" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Konstant" @@ -2249,6 +2250,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2960,8 +2963,9 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Ava fail" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3097,10 +3101,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3319,6 +3319,7 @@ msgid "Load Errors" msgstr "Laadimisvead" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Vali" @@ -3398,7 +3399,6 @@ msgid "Author" msgstr "Autorid" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Olek" @@ -3626,6 +3626,12 @@ msgstr "Stseeni tee:" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Viga:" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4496,6 +4502,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Autor:" @@ -6146,6 +6153,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9494,7 +9502,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9502,7 +9510,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9510,7 +9523,38 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "Varjutaja muutused" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Varjutaja muutused" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Kogukond" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9522,57 +9566,179 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Kustuta profiil" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Nimeta ümber" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect new changes" +msgid "SSH Public Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Select SSH public key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "SSH Private Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +msgid "Select SSH private key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" -msgstr "Kustutatud" +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Detect new changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "Kustuta Valitud Võti (Võtmed)" +msgid "Discard all changes" +msgstr "Materjali muutused" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "Vali Kõik" +msgid "Stage all changes" +msgstr "Salvestan kohalikud muudatused..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Materjali muutused" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +#, fuzzy +msgid "Commit List" +msgstr "Kogukond" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +#, fuzzy +msgid "Branches" +msgstr "Vasted:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Loo stseen" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Eemalda animatsiooni rada" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Eemalda" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Lisa/loo uus sõlm." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Eemalda" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Sõlme nimi:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Eemalda" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Ressursi tee" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "Kustutatud" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "View:" +msgstr "Kuva" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12101,6 +12267,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Ressursi tee" @@ -12937,6 +13104,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Animatsioon" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12949,6 +13149,82 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Frontaal" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Tüüp:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12965,6 +13241,19 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funktsioonid" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12974,6 +13263,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12982,6 +13275,61 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Kustuta sõlm(ed)" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Stseenipuu redigeerimine" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Kustuta sõlm(ed)" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12991,12 +13339,72 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Kutsungid" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Konstandid" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Kasuta kohalikku ruumi" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Kasuta kohalikku ruumi" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Funktsioonid" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Virnakaadrid" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Signaal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Signaal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13568,7 +13976,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13782,7 +14199,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/eu.po b/editor/translations/eu.po index 4006cdc00d..448788dc2e 100644 --- a/editor/translations/eu.po +++ b/editor/translations/eu.po @@ -360,6 +360,7 @@ msgstr "%d pista berri sortu eta giltzak sartu?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -817,6 +818,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -866,8 +868,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1913,7 +1914,6 @@ msgid "New Folder..." msgstr "Karpeta berria..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2030,7 +2030,8 @@ msgstr "Direktorioak eta fitxategiak:" msgid "Preview:" msgstr "Aurrebista:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Fitxategia:" @@ -2199,7 +2200,7 @@ msgstr "Metodoa" msgid "Signal" msgstr "Seinalea" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Konstantea" @@ -2230,6 +2231,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2929,8 +2932,9 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Ireki proiektuaren datu karpeta" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Ireki editorearen datu karpeta" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3065,10 +3069,6 @@ msgid "Toggle Fullscreen" msgstr "Txandakatu pantaila osoa" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Txandakatu sistemaren kontsola" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3289,6 +3289,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3368,7 +3369,6 @@ msgid "Author" msgstr "Egileak" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3594,6 +3594,11 @@ msgstr "Eszenaren bidea:" msgid "Import From Node:" msgstr "Inportatu nodotik:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +msgid "%s Error" +msgstr "" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4474,6 +4479,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6124,6 +6130,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9453,7 +9460,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9461,7 +9468,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9469,7 +9481,36 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Komunitatea" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9481,39 +9522,56 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Ezabatu profila" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Username" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect new changes" +msgid "Password" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "SSH Public Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "Select SSH public key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +msgid "SSH Private Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" +msgid "Select SSH private key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "SSH Passphrase" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect new changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Stage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9521,15 +9579,113 @@ msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +#, fuzzy +msgid "Commit List" +msgstr "Komunitatea" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Branches" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Create New Branch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Ezabatu Animazio Pista" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Kendu elementu guztiak" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Kendu elementu guztiak" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Kendu guztiak" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "View:" +msgstr "Aurrebista:" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12058,6 +12214,7 @@ msgid "Export list to a CSV file" msgstr "Esportatu zerrenda CSV fitxategi batera" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12888,6 +13045,40 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Erabili adierazpen erregularrak" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Kargatu animazioa" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12900,6 +13091,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12916,6 +13181,19 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funtzioak:" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12925,6 +13203,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12933,6 +13215,60 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Konstantea" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Konstantea" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Konstantea" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Konstantea" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Blend4 nodoa" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Txertatu gakoa hemen" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "CustomNode" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12942,12 +13278,69 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Konstanteak" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Funtzioak:" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Hurrengo karpeta/fitxategia" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Seinalea" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Seinalea" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13519,7 +13912,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13732,7 +14134,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/fa.po b/editor/translations/fa.po index cea2728671..dee445a3d1 100644 --- a/editor/translations/fa.po +++ b/editor/translations/fa.po @@ -23,13 +23,14 @@ # duniyal ras <duniyalr@gmail.com>, 2021. # عبدالرئو٠عابدی <abdolraoofabedi@gmail.com>, 2021. # Alireza Khodabande <alirezakhodabande74@gmail.com>, 2021. +# Seyed Fazel Alavi <fazel8195@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-09-29 02:21+0000\n" -"Last-Translator: Alireza Khodabande <alirezakhodabande74@gmail.com>\n" +"PO-Revision-Date: 2022-01-12 16:52+0000\n" +"Last-Translator: Seyed Fazel Alavi <fazel8195@gmail.com>\n" "Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/" "godot/fa/>\n" "Language: fa\n" @@ -37,7 +38,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.9-dev\n" +"X-Generator: Weblate 4.10.1\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -62,7 +63,7 @@ msgstr "ورودی نامعتبر i% (تایید نشده) در عبارت" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" -msgstr "نمی توان self را بکار Ú¯Ø±ÙØª چون instance = null هست (تایید نشده)" +msgstr "از self نمی‌توان Ø§Ø³ØªÙØ§Ø¯Ù‡ کرد زیرا نمونه ØµÙØ± است (رد نشده است)" #: core/math/expression.cpp msgid "Invalid operands to operator %s, %s and %s." @@ -342,7 +343,7 @@ msgstr "تکرار کلید(ها)" #: editor/animation_track_editor.cpp msgid "Add RESET Value(s)" -msgstr "" +msgstr "اضاÙÙ‡ کردن مقدار(های) ریست" #: editor/animation_track_editor.cpp msgid "Delete Key(s)" @@ -379,6 +380,7 @@ msgstr "ساختن %d قطعه جدید Ùˆ درج کلیدها؟" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -391,9 +393,8 @@ msgstr "در انیمیشن درج Ú©Ù†" #. TRANSLATORS: This describes the target of new animation track, will be inserted into another string. #: editor/animation_track_editor.cpp -#, fuzzy msgid "node '%s'" -msgstr "در ØØ§Ù„ اتصال..." +msgstr "گره '%s'" #. TRANSLATORS: This describes the target of new animation track, will be inserted into another string. #: editor/animation_track_editor.cpp @@ -512,9 +513,8 @@ msgid "" msgstr "این گزینه برای Ø§ØµÙ„Ø§Ø Ø¨ÙØ²ÛŒÙر کار نمی کند, چون تنها یک مسیر ÙˆØ§ØØ¯ است." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Add RESET Keys" -msgstr "اندازه کلید های Ù…ØªØØ±Ú©" +msgstr "اضاÙÙ‡ کردن کلید های ریست انیمیشن" #: editor/animation_track_editor.cpp msgid "" @@ -844,6 +844,7 @@ msgstr "Ø§ÙØ²ÙˆØ¯Ù†" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -895,8 +896,7 @@ msgstr "نمی توان سیگنال را متصل کرد" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -947,7 +947,7 @@ msgstr "" #: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp msgid "Signals" -msgstr "سیگنال‌ها" +msgstr "سیگنال ها" #: editor/connections_dialog.cpp msgid "Filter signals" @@ -983,9 +983,8 @@ msgid "Create New %s" msgstr "ساختن %s جدید" #: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "No results for \"%s\"." -msgstr "هیچ نتیجه ای برای \"Ùª s\" وجود ندارد." +msgstr "هیچ نتیجه ای برای \"%s\" وجود ندارد." #: editor/create_dialog.cpp editor/property_selector.cpp msgid "No description available for %s." @@ -1089,18 +1088,16 @@ msgid "Owners Of:" msgstr "مالکانÙ:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Remove the selected files from the project? (Cannot be undone.)\n" "Depending on your filesystem configuration, the files will either be moved " "to the system trash or deleted permanently." msgstr "" -"ÙØ§ÛŒÙ„های انتخابی از پروژه ØØ°Ù شوند؟ (قابل واگرد نیست.)\n" +"ÙØ§ÛŒÙ„های انتخابی از پروژه ØØ°Ù شوند؟ (قابل برگشت نیست.)\n" "بسته به پیکربندی سیستم ÙØ§ÛŒÙ„ شما ØŒ ÙØ§ÛŒÙ„ ها یا به سطل زباله سیستم منتقل Ù…ÛŒ " "شوند Ùˆ یا برای همیشه ØØ°Ù Ù…ÛŒ شوند." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "The files being removed are required by other resources in order for them to " "work.\n" @@ -1280,41 +1277,36 @@ msgid "Licenses" msgstr "گواهینامه" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "Error opening asset file for \"%s\" (not in ZIP format)." -msgstr "خطای گشودن بسته بندی پرونده، به Ø´Ú©Ù„ ZIP نیست." +msgstr "خطا در بازکردن ÙØ§ÛŒÙ„ برای \"%s\" (ÙØ±Ù…ت ZIP نمیباشد)." #: editor/editor_asset_installer.cpp -#, fuzzy msgid "%s (already exists)" -msgstr "%s (موجود است)" +msgstr "\"%s\" (در ØØ§Ù„ ØØ§Ø¶Ø± موجود است)" #: editor/editor_asset_installer.cpp msgid "Contents of asset \"%s\" - %d file(s) conflict with your project:" -msgstr "" +msgstr "Ù…ØØªÙˆØ§ÛŒ دارایی \"%s\" - %d ÙØ§ÛŒÙ„(ها) با پروژه شما تضاد دارد:" #: editor/editor_asset_installer.cpp msgid "Contents of asset \"%s\" - No files conflict with your project:" -msgstr "" +msgstr "Ù…ØØªÙˆÛŒØ§Øª دارایی \"%s\" - هیچ ÙØ§ÛŒÙ„ÛŒ با پروژه شما مغایرت ندارد:" #: editor/editor_asset_installer.cpp msgid "Uncompressing Assets" msgstr "ÙØ´Ø±Ø¯Ù‡ نشدن Ø§ÙŽØ³ÙØª ها" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "The following files failed extraction from asset \"%s\":" -msgstr "استخراج پرونده های زیر از بسته بندی انجام نشد:" +msgstr "ÙØ§ÛŒÙ„‌های زیر از دارایی \"%s\" استخراج نشدند:" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "(and %s more files)" -msgstr "Ùˆ %s بیش تر پرونده ها." +msgstr "(Ùˆ %s دیگر ÙØ§ÛŒÙ„ ها)" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "Asset \"%s\" installed successfully!" -msgstr "بسته با موÙقیت نصب شد!" +msgstr "دارایی \"%s\" با موÙقیت نصب شد!" #: editor/editor_asset_installer.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -1326,9 +1318,8 @@ msgid "Install" msgstr "نصب کردن" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "Asset Installer" -msgstr "نصب کننده پکیج ها" +msgstr "نصب کننده دارایی" #: editor/editor_audio_buses.cpp msgid "Speakers" @@ -1391,7 +1382,6 @@ msgid "Bypass" msgstr "‌گذرگاه ÙØ±Ø¹ÛŒ" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Bus Options" msgstr "گزینه های اتوبوس" @@ -1508,7 +1498,7 @@ msgstr "نام نامعتبر." #: editor/editor_autoload_settings.cpp msgid "Cannot begin with a digit." -msgstr "" +msgstr "نمی توان با یک رقم شروع کرد." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" @@ -1563,13 +1553,12 @@ msgid "Can't add autoload:" msgstr "اضاÙÙ‡ کردن خودکار امکان پذیر نیست:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "%s is an invalid path. File does not exist." -msgstr "پرونده موجود نیست." +msgstr "%s یک مسیر نامعتبر است. ÙØ§ÛŒÙ„ موجود نمیباشد." #: editor/editor_autoload_settings.cpp msgid "%s is an invalid path. Not in resource path (res://)." -msgstr "" +msgstr "%s یک مسیر نامعتبر است. در مسیر منبع نیست (//:res)." #: editor/editor_autoload_settings.cpp msgid "Add AutoLoad" @@ -1593,9 +1582,8 @@ msgid "Name" msgstr "نام" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Global Variable" -msgstr "تغییر متغیر" +msgstr "متغیر عمومی" #: editor/editor_data.cpp msgid "Paste Params" @@ -1671,12 +1659,16 @@ msgid "" "Target platform requires 'ETC' texture compression for GLES2. Enable 'Import " "Etc' in Project Settings." msgstr "" +"Ù¾Ù„ØªÙØ±Ù… مورد نظر به ÙØ´Ø±Ø¯Ù‡ سازی تکستچر 'ETC' برای GLES2 نیاز دارد . 'واردکردن " +"ETC' را در تنظیمات پروژه ÙØ¹Ø§Ù„ کنید." #: editor/editor_export.cpp msgid "" "Target platform requires 'ETC2' texture compression for GLES3. Enable " "'Import Etc 2' in Project Settings." msgstr "" +"Ù¾Ù„ØªÙØ±Ù… مورد نظر به ÙØ´Ø±Ø¯Ù‡ سازی تکستچر 'ETC' برای GLES2 نیاز دارد . 'واردکردن " +"ETC' را در تنظیمات پروژه ÙØ¹Ø§Ù„ کنید." #: editor/editor_export.cpp msgid "" @@ -1685,18 +1677,26 @@ msgid "" "Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback " "Enabled'." msgstr "" +"Ù¾Ù„ØªÙØ±Ù… هد٠به ÙØ´Ø±Ø¯Ù‡â€ŒØ³Ø§Ø²ÛŒ Ø¨Ø§ÙØª 'ETC' برای بازگرداندن درایور به GLES2 نیاز " +"دارد.\n" +"'استخراج Etc' را در تنظیمات پروژه ÙØ¹Ø§Ù„ کنید یا \"Driver Fallback Enabled\" " +"را ØºÛŒØ±ÙØ¹Ø§Ù„ کنید." #: editor/editor_export.cpp msgid "" "Target platform requires 'PVRTC' texture compression for GLES2. Enable " "'Import Pvrtc' in Project Settings." msgstr "" +"پلت ÙØ±Ù… هد٠به ÙØ´Ø±Ø¯Ù‡ سازی Ø¨Ø§ÙØª 'PVRTC' برای GLES2 نیاز دارد. 'استخراج Pvrtc' " +"را در تنظیمات پروژه ÙØ¹Ø§Ù„ کنید." #: editor/editor_export.cpp msgid "" "Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. " "Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings." msgstr "" +"پلت ÙØ±Ù… هد٠برای GLES3 به ÙØ´Ø±Ø¯Ù‡ سازی Ø¨Ø§ÙØª 'ETC2' یا 'PVRTC' نیاز دارد. " +"\"Import Etc 2\" یا \"Import Pvrtc\" را در تنظیمات پروژه ÙØ¹Ø§Ù„ کنید." #: editor/editor_export.cpp msgid "" @@ -1957,7 +1957,6 @@ msgid "New Folder..." msgstr "ساختن پوشه..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2074,7 +2073,8 @@ msgstr "پوشه‌ها Ùˆ پرونده‌ها:" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "پرونده:" @@ -2131,7 +2131,7 @@ msgstr "پیش ÙØ±Ø¶:" #: editor/editor_help.cpp msgid "Methods" -msgstr "توابع" +msgstr "روش ها" #: editor/editor_help.cpp msgid "Theme Properties" @@ -2242,7 +2242,7 @@ msgstr "روش" msgid "Signal" msgstr "سیگنال‌" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "ثابت" @@ -2273,6 +2273,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "تنظیم %s" @@ -2972,7 +2974,8 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +#, fuzzy +msgid "Open User Data Folder" msgstr "گشودن پوشه اطلاعات طرØ" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3112,11 +3115,6 @@ msgstr "ØØ§Ù„ت تمام ØµÙØÙ‡" #: editor/editor_node.cpp #, fuzzy -msgid "Toggle System Console" -msgstr "یک Breakpoint درج Ú©Ù†" - -#: editor/editor_node.cpp -#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "ویرایشگر ØªØ±Ø¬ÛŒØØ§Øª" @@ -3348,6 +3346,7 @@ msgid "Load Errors" msgstr "خطاهای بارگذاری" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3431,7 +3430,6 @@ msgid "Author" msgstr "Ù…Ø¤Ù„ÙØ§Ù†" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp #, fuzzy msgid "Status" @@ -3665,6 +3663,12 @@ msgstr "" msgid "Import From Node:" msgstr "وارد کردن از گره:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "بازتاب" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4600,6 +4604,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "خالق:" @@ -6360,6 +6365,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -6489,7 +6495,7 @@ msgstr "" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat 1" -msgstr "" +msgstr "تخت 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" @@ -9917,7 +9923,7 @@ msgid "TileSet" msgstr "صدور مجموعه کاشی" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9925,7 +9931,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9934,10 +9945,43 @@ msgid "Commit" msgstr "انجمن" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "تغییر بده" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "تغییر بده" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "انجمن" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "آیا مطمئن هستید Ú©Ù‡ Ù…ÛŒ خواهید همه اتصالات را از این سیگنال ØØ°Ù کنید؟" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "بازنشانی را اعمال کنید" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -9946,7 +9990,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "برداشتن نقطه" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "تغییر نام" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9956,53 +10030,145 @@ msgstr "ساختن %s جدید" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Changes" +msgid "Discard all changes" msgstr "تغییر بده" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" -msgstr "" +#, fuzzy +msgid "Stage all changes" +msgstr "ذخیره تغییرات Ù…ØÙ„ÛŒ ..." #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "تغییر نام" +msgid "Unstage all changes" +msgstr "تغییر بده" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "ØØ°Ù Ú©Ù†" +msgid "Commit Message" +msgstr "تغییر بده" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Typechange" +msgid "Commit Changes" msgstr "تغییر بده" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "انتخاب شده را ØØ°Ù Ú©Ù†" +msgid "Commit List" +msgstr "انجمن" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "انتخاب همه" +msgid "Branches" +msgstr "تطبیق‌ها:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" -msgstr "تغییر بده" +msgid "Create New Branch" +msgstr "ساختن پروژه جدید" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "ØØ°Ù ترک انیمشین" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Branch Name" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +#, fuzzy +msgid "Remotes" +msgstr "از راه دور" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "ساختن پروژه جدید" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "ØØ°Ù قالب" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "برداشتن" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "برداشتن" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "تغییر نام" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "ØØ°Ù Ú©Ù†" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Typechange" +msgstr "تغییر بده" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "View:" +msgstr "پرونده:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Split" +msgstr "ویرایش منØÙ†ÛŒ گره" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12666,6 +12832,7 @@ msgid "Export list to a CSV file" msgstr "صدور پروژه" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13566,6 +13733,40 @@ msgstr "" msgid "Edit Member" msgstr "عضوها" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "انتقال را در انیمیشن تغییر بده" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "انیمیشن" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "نوع ورودی قابل تکرار نیست: " @@ -13580,6 +13781,85 @@ msgstr "تکرارگر نامعتبر شد" msgid "Iterator became invalid: " msgstr "تکرارگر نامعتبر شد: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "ساختن پوشه" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "سوییچ" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "نوع پایه:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "کاراکترهای معتبر:" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "تنظیم %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Ú¯Ø±ÙØªÙ† %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "نام دارایی ایندکس نامعتبر." @@ -13596,6 +13876,21 @@ msgstr "مسیر به یک نود نمیرسد!" msgid "Invalid index property name '%s' in node %s." msgstr "نام دارایی ایندکس نامعتبر '%s' در نود %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "تنظیم %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "توابع" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "آرایه را تغییر اندازه بده" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": آرگومان نوع نامعتبر " @@ -13605,6 +13900,10 @@ msgid ": Invalid arguments: " msgstr ": آرگومان‌های نامعتبر: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet در اسکریپت پیدا نشد: " @@ -13613,6 +13912,64 @@ msgid "VariableSet not found in script: " msgstr "VariableSet در اسکریپت پیدا نشد: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Ø§ÙØ²ÙˆØ¯Ù† گره" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "اندیس:" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "اندیس:" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "ثابت" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "ثابت" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "ثابت" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "ثابت" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "صØÙ†Ù‡ جدید" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "ساختن گره" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "ساختن گره" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "گره Ø³ÙØ§Ø±Ø´ÛŒ بدون متد ()step_ نمی‌تواند گرا٠را پردازش کند." @@ -13625,14 +13982,74 @@ msgstr "" "مقدار بازگشتی نامعتبر از ()step_ ØŒ باید integer (seq out) ØŒ یا string " "(error) باشد." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "ÙØ±Ø§Ø®ÙˆØ§Ù†ÛŒ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "ثابت ها" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Ù…ØÙ„ÛŒ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Ù…ØÙ„ÛŒ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Ø§ÙØ²ÙˆØ¯Ù† وظیÙÙ‡" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp #, fuzzy msgid "Search VisualScript" msgstr "ØØ°Ù گره اسکریپت٠دیداری" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Ú¯Ø±ÙØªÙ† %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "ØØ±Ú©Øª دادن گره(ها)" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "سیگنال‌" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "سیگنال‌" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" +msgstr "" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14248,7 +14665,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14484,7 +14910,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/fi.po b/editor/translations/fi.po index f461bb0074..ab1acf1db8 100644 --- a/editor/translations/fi.po +++ b/editor/translations/fi.po @@ -8,7 +8,7 @@ # Jarmo Riikonen <amatrelan@gmail.com>, 2017. # Nuutti Varvikko <nvarvikko@gmail.com>, 2018. # Sami Lehtilä <sami.lehtila@gmail.com>, 2018. -# Tapani Niemi <tapani.niemi@kapsi.fi>, 2018, 2019, 2020, 2021. +# Tapani Niemi <tapani.niemi@kapsi.fi>, 2018, 2019, 2020, 2021, 2022. # Tuomas Lähteenmäki <lahtis@gmail.com>, 2019. # Matti Niskanen <matti.t.niskanen@gmail.com>, 2020. # Severi Vidnäs <severi.vidnas@gmail.com>, 2021. @@ -17,7 +17,7 @@ msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-12-11 06:25+0000\n" +"PO-Revision-Date: 2022-01-12 16:52+0000\n" "Last-Translator: Tapani Niemi <tapani.niemi@kapsi.fi>\n" "Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/" "godot/fi/>\n" @@ -26,7 +26,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.10-dev\n" +"X-Generator: Weblate 4.10.1\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -329,9 +329,8 @@ msgid "Duplicate Key(s)" msgstr "Kahdenna avainruudut" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add RESET Value(s)" -msgstr "Lisää %d ruutua" +msgstr "Lisää RESET arvo(t)" #: editor/animation_track_editor.cpp msgid "Delete Key(s)" @@ -368,6 +367,7 @@ msgstr "Luo %d uutta raitaa ja lisää avaimet?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -500,9 +500,8 @@ msgid "" msgstr "Tämä valinta ei käy Bezier-editoinnille, koska se on vain yksi raita." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Add RESET Keys" -msgstr "Animaatio: Skaalaa avaimia" +msgstr "Animaatio: Lisää RESET avaimet" #: editor/animation_track_editor.cpp msgid "" @@ -832,6 +831,7 @@ msgstr "Lisää" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -882,8 +882,7 @@ msgstr "Ei voida yhdistää signaalia" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1487,7 +1486,7 @@ msgstr "Virheellinen nimi." #: editor/editor_autoload_settings.cpp msgid "Cannot begin with a digit." -msgstr "" +msgstr "Ei voi alkaa numerolla." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" @@ -1951,7 +1950,6 @@ msgid "New Folder..." msgstr "Uusi kansio..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Päivitä" @@ -2068,7 +2066,8 @@ msgstr "Hakemistot ja tiedostot:" msgid "Preview:" msgstr "Esikatselu:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Tiedosto:" @@ -2117,9 +2116,8 @@ msgid "Properties" msgstr "Ominaisuudet" #: editor/editor_help.cpp -#, fuzzy msgid "overrides %s:" -msgstr "ylikirjoita:" +msgstr "ylikirjoittaa %s:" #: editor/editor_help.cpp msgid "default:" @@ -2242,7 +2240,7 @@ msgstr "Metodi" msgid "Signal" msgstr "Signaali" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Vakio" @@ -2259,20 +2257,24 @@ msgid "Property:" msgstr "Ominaisuus:" #: editor/editor_inspector.cpp -#, fuzzy msgid "Pin value" -msgstr "(arvo)" +msgstr "Kiinnitä arvo" #: editor/editor_inspector.cpp msgid "" "Pinning a value forces it to be saved even if it's equal to the default." msgstr "" +"Arvon kiinnittäminen pakottaa tallentamaan sen, vaikka se olisi sama kuin " +"oletusarvo." #: editor/editor_inspector.cpp msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" +"Kiinnitä arvo [Poistettu käytöstä, koska '%s' on käytössä vain editorissa]" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Aseta %s" @@ -2283,26 +2285,23 @@ msgstr "Aseta useita:" #: editor/editor_inspector.cpp msgid "Pinned %s" -msgstr "" +msgstr "Kiinnitetty %s" #: editor/editor_inspector.cpp msgid "Unpinned %s" -msgstr "" +msgstr "Poistettu kiinnitys %s" #: editor/editor_inspector.cpp -#, fuzzy msgid "Copy Property" -msgstr "Kopioi ominaisuudet" +msgstr "Kopioi ominaisuus" #: editor/editor_inspector.cpp -#, fuzzy msgid "Paste Property" -msgstr "Liitä ominaisuudet" +msgstr "Liitä ominaisuus" #: editor/editor_inspector.cpp -#, fuzzy msgid "Copy Property Path" -msgstr "Kopioi skriptin polku" +msgstr "Kopioi ominaisuuden polku" #: editor/editor_log.cpp msgid "Output:" @@ -3024,8 +3023,9 @@ msgid "Install Android Build Template..." msgstr "Asenna Androidin käännösmalli..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Avaa projektin datakansio" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Avaa editorin datakansio" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3114,7 +3114,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Force Shader Fallbacks" -msgstr "" +msgstr "Pakota varasävyttimien käyttö" #: editor/editor_node.cpp msgid "" @@ -3125,6 +3125,12 @@ msgid "" "Asynchronous shader compilation must be enabled in the project settings for " "this option to make a difference." msgstr "" +"Kun tämä valinta on päällä, sävyttimet käyttävät varasävytintään (joko " +"näkyvissä ubersävyttimenä tai piilotettuna) aina ajon aikana.\n" +"Tämä on hyödyllistä normaalisti pikaisesti näytettävien varasävyttimien " +"ulkonäön ja tehokkuuden varmistamiseksi.\n" +"Asynkroninen sävyttimien kääntäminen täytyy olla päällä projektin " +"asetuksissa, jotta tällä valinnalla olisi vaikutusta." #: editor/editor_node.cpp msgid "Synchronize Scene Changes" @@ -3183,10 +3189,6 @@ msgid "Toggle Fullscreen" msgstr "Siirry koko näytön tilaan" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Aseta järjestelmäkonsolin näkyvyys päälle/pois" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Avaa editorin data/asetuskansio" @@ -3416,6 +3418,7 @@ msgid "Load Errors" msgstr "Latausvirheet" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Valitse" @@ -3492,7 +3495,6 @@ msgid "Author" msgstr "Tekijä" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Tila" @@ -3738,6 +3740,12 @@ msgstr "Skenen polku:" msgid "Import From Node:" msgstr "Tuo solmusta:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Virhe" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "Avaa kansio, joka sisältää nämä vientimallit." @@ -4277,9 +4285,8 @@ msgid "Replace..." msgstr "Korvaa..." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Replace in Files" -msgstr "Korvaa kaikki" +msgstr "Korvaa tiedostoissa" #: editor/find_in_files.cpp msgid "Find: " @@ -4290,9 +4297,8 @@ msgid "Replace: " msgstr "Korvaa: " #: editor/find_in_files.cpp -#, fuzzy msgid "Replace All (NO UNDO)" -msgstr "Korvaa kaikki" +msgstr "Korvaa kaikki (EI VOI KUMOTA)" #: editor/find_in_files.cpp msgid "Searching..." @@ -4521,6 +4527,8 @@ msgid "" "Select a resource file in the filesystem or in the inspector to adjust " "import settings." msgstr "" +"Valitse resurssitiedosto tiedostojärjestelmästä tai tarkastelijasta " +"säätääksesi tuontiasetuksia." #: editor/inspector_dock.cpp msgid "Failed to load resource." @@ -4629,6 +4637,7 @@ msgid "Subfolder:" msgstr "Alikansio:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Tekijä:" @@ -5984,9 +5993,8 @@ msgid "Alt+Drag: Move selected node." msgstr "Alt+Vedä: Siirrä valittua solmua." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Alt+Drag: Scale selected node." -msgstr "Alt+Vedä: Siirrä valittua solmua." +msgstr "Alt+Vedä: Skaalaa valittua solmua." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "V: Set selected node's pivot position." @@ -6020,7 +6028,7 @@ msgstr "Skaalaustila" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Shift: Scale proportionally." -msgstr "" +msgstr "Shift: Skalaa suhteellisesti." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6119,9 +6127,8 @@ msgstr "Lukitse valitut objektit paikalleen (ei voi liikutella)." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected Node(s)" -msgstr "Lukitse valitut" +msgstr "Lukitse valitut solmut" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6130,9 +6137,8 @@ msgstr "Poista valittujen objektien lukitus (voi liikutella)." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected Node(s)" -msgstr "Vapauta valitut" +msgstr "Vapauta valitut solmut" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6141,9 +6147,8 @@ msgstr "Varmistaa, ettei objektin alisolmuja voi valita." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected Node(s)" -msgstr "Ryhmitä valitut" +msgstr "Ryhmitä valitut solmut" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6152,9 +6157,8 @@ msgstr "Palauttaa objektin aliobjektien mahdollisuuden tulla valituksi." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected Node(s)" -msgstr "Poista ryhmitys valituilta" +msgstr "Poista ryhmitys valituilta solmuilta" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Skeleton Options" @@ -6327,6 +6331,7 @@ msgid "Zoom to 1600%" msgstr "Aseta lähennystasoksi 1600%" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Lisää %s" @@ -7800,9 +7805,8 @@ msgid "Find in Files..." msgstr "Etsi tiedostoista..." #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Replace in Files..." -msgstr "Korvaa..." +msgstr "Korvaa tiedostoissa..." #: editor/plugins/script_text_editor.cpp msgid "Contextual Help" @@ -8330,16 +8334,15 @@ msgstr "Kytke liikkuminen päälle/pois" #: editor/plugins/spatial_editor_plugin.cpp msgid "Decrease Field of View" -msgstr "" +msgstr "Kavenna näkymäkenttää" #: editor/plugins/spatial_editor_plugin.cpp msgid "Increase Field of View" -msgstr "" +msgstr "Laajenna näkymäkenttää" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Reset Field of View to Default" -msgstr "Palauta oletusarvoihin" +msgstr "Palauta näkymäkenttä oletusarvoon" #: editor/plugins/spatial_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9067,22 +9070,19 @@ msgstr "Lisää tyyppi" #: editor/plugins/theme_editor_plugin.cpp msgid "Filter the list of types or create a new custom type:" -msgstr "" +msgstr "Suodata tyyppien luetteloa tai luo uusi mukautettu tyyppi:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Available Node-based types:" -msgstr "Saatavilla olevat profiilit:" +msgstr "Saatavilla olevat Node-pohjaiset tyypit:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Type name is empty!" -msgstr "Tiedostonimi on tyhjä." +msgstr "Tyypin nimi on tyhjä!" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Are you sure you want to create an empty type?" -msgstr "Haluatko varmasti avata useamman kuin yhden projektin?" +msgstr "Haluatko varmasti luoda tyhjän tyypin?" #: editor/plugins/theme_editor_plugin.cpp msgid "Confirm Item Rename" @@ -9705,7 +9705,8 @@ msgid "TileSet" msgstr "Laattavalikoima" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "VCS-lisäosia ei ole saatavilla." #: editor/plugins/version_control_editor_plugin.cpp @@ -9713,16 +9714,56 @@ msgid "Error" msgstr "Virhe" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "Tiedostoja ei ole lisätty valmisteluun" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Nimeä ei annettu." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "Vahvista muutos" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "VCS-lisäosaa ei ole alustettu" +#, fuzzy +msgid "Staged Changes" +msgstr "Sävytinmuutokset:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Sävytinmuutokset:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Vahvista muutos" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Alipuu" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Haluatko varmasti luoda tyhjän tyypin?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Tee palautus" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9733,16 +9774,148 @@ msgid "Initialize" msgstr "Alusta" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "Valmistelualue" +#, fuzzy +msgid "Remote Login" +msgstr "Poista piste" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Nimeä uudelleen" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Havaitse uudet muutokset" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Muutokset" +#, fuzzy +msgid "Discard all changes" +msgstr "Sulje ja tallenna muutokset?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Varastoidaan paikalliset muutokset..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Materiaalimuutokset:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Vahvista muutokset" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "Vahvista muutokset" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Vahvista muutos" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Osumat:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Luo uusi projekti" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Poista animaatioraita" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Etäinen" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Luo uusi projekti" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Poista" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Etäinen " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Etäinen " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Lähde Mesh:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9761,30 +9934,23 @@ msgid "Typechange" msgstr "Tyyppimuunnos" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "Valmistele valitut" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "Valmistele kaikki" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "Vahvista muutokset" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "" -"Katso tiedostojen eroavaisuudet ennen niiden vahvistamista viimeisimpään " -"versioon" +#, fuzzy +msgid "View:" +msgstr "Näytä" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "Mitään tiedostovertailua ei ole aktiivisena" +#, fuzzy +msgid "Split" +msgstr "Puolita polku" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "Havaitse muutokset tiedostovertailussa" +#, fuzzy +msgid "Unified" +msgstr "Muutettu" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -11928,6 +12094,10 @@ msgid "" "To save this branch into its own scene, open the original scene, right click " "on this branch, and select \"Save Branch as Scene\"." msgstr "" +"Ei voida tallentaa haaraa, joka on skenen ilmentymän alisolmu.\n" +"Tallentaaksesi tämän haaran omaksi skeneksi, avaa alkuperäinen skene, " +"napsauta hiiren oikealla painikkella kyseistä haaraa ja valitse \"Tallenna " +"haara skenenä\"." #: editor/scene_tree_dock.cpp msgid "" @@ -11935,6 +12105,10 @@ msgid "" "To save this branch into its own scene, open the original scene, right click " "on this branch, and select \"Save Branch as Scene\"." msgstr "" +"Ei voida tallentaa haaraa, joka on periytetyn skenen alisolmu.\n" +"Tallentaaksesi tämän haaran omaksi skeneksi, avaa alkuperäinen skene, " +"napsauta hiiren oikealla painikkella kyseistä haaraa ja valitse \"Tallenna " +"haara skenenä\"." #: editor/scene_tree_dock.cpp msgid "Save New Scene As..." @@ -12474,6 +12648,7 @@ msgid "Export list to a CSV file" msgstr "Vie lista CSV tiedostoon" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Resurssipolku" @@ -13323,6 +13498,40 @@ msgstr "Päivitä kaaviokuva" msgid "Edit Member" msgstr "Muokkaa jäsentä" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Aseta lauseke" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animaatio" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Syötetyyppi ei ole iteroitavissa: " @@ -13335,6 +13544,88 @@ msgstr "Iteraattori muuttui epäkelvoksi" msgid "Iterator became invalid: " msgstr "Iteraattori muuttui epäkelvoksi: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Nimetään kansio uudelleen:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Nyökkäyskulma:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Tyypit:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Itse" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Merkissä %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Lisää %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Aseta %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Kiinnitetty %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Hae %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Virheellinen osoitinominaisuuden nimi." @@ -13351,6 +13642,21 @@ msgstr "Polku ei johda solmuun!" msgid "Invalid index property name '%s' in node %s." msgstr "Virheellinen osoitinominaisuuden nimi '%s' solmussa %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Aseta %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funktiot" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Muuta taulukon kokoa" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Virheellinen argumentti tyyppiä: " @@ -13360,6 +13666,10 @@ msgid ": Invalid arguments: " msgstr ": Virheelliset argumentit: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet ei löytynyt skriptistä: " @@ -13368,6 +13678,66 @@ msgid "VariableSet not found in script: " msgstr "VariableSet ei löytynyt skriptistä: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Lataa uudelleen" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Z-indeksi" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Z-indeksi" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Vakio" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Vakio" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Vakio" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Vakio" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "GDNative singleton on otettu käyttöön" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Ajanhakusolmu" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Skenepuun muokkaus" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Itse" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Leikkaa solmut" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" "Mukautetulla solmulla ei ole _step() metodia, graafia ei voida käsitellä." @@ -13380,13 +13750,75 @@ msgstr "" "Virheellinen paluuarvo _step() metodilta, täytyy olla kokonaisluku (seq out) " "tai merkkijono (virhe)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Kutsuja" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Vakiot" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Käytä paikallisavaruutta" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Käytä paikallisavaruutta" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Toiminto" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Hae VisualScriptistä" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Hae %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Siirrä ruutua" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Fysiikkaruutujen %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Signaali" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Signaali" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Luo ilmentymä" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -13998,12 +14430,15 @@ msgstr "Tämän peittäjän peittopolygoni on tyhjä. Ole hyvä ja piirrä polyg #: scene/2d/navigation_agent_2d.cpp msgid "The NavigationAgent2D can be used only under a Node2D node." msgstr "" +"NavigationAgent2D solmua voidaan käyttää ainoastaan Node2D solmun alla." #: scene/2d/navigation_obstacle_2d.cpp msgid "" "The NavigationObstacle2D only serves to provide collision avoidance to a " "Node2D object." msgstr "" +"NavigationObstacle2D on olemassa ainoastaan tarjotakseen Node2D objektille " +"törmäyksen välttämistä." #: scene/2d/navigation_polygon.cpp msgid "" @@ -14029,15 +14464,25 @@ msgstr "" "alla." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "GPU-pohjaiset partikkelit eivät ole tuettuja GLES2 näyttöajurilla.\n" "Käytä sen sijaan CPUParticles2D solmua. Voit käyttää \"Muunna " "CPUPartikkeleiksi\" toimintoa tähän tarkoitukseen." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14267,7 +14712,7 @@ msgstr "" #: scene/3d/navigation_agent.cpp msgid "The NavigationAgent can be used only under a spatial node." -msgstr "" +msgstr "NavigationAgent solmua voidaan käyttää ainoastaan Spatial solmun alla." #: scene/3d/navigation_mesh_instance.cpp msgid "" @@ -14282,6 +14727,8 @@ msgid "" "The NavigationObstacle only serves to provide collision avoidance to a " "spatial object." msgstr "" +"NavigationObstacle on olemassa ainoastaan tarjotakseen Spatial objektille " +"törmäyksen välttämistä." #: scene/3d/occluder.cpp msgid "No shape is set." @@ -14292,10 +14739,11 @@ msgid "Only uniform scales are supported." msgstr "Vain uniform-skaalat ovat tuettuja." #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "GPU-pohjaiset partikkelit eivät ole tuettuja GLES2 näyttöajurilla.\n" "Käytä sen sijaan CPUParticles solmua. Voit käyttää \"Muunna CPUPartikkeleiksi" @@ -14303,6 +14751,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" "Mitään ei näy, koska mesheille ei ole asetettu piirtopyyhkäisyjä (draw " diff --git a/editor/translations/fil.po b/editor/translations/fil.po index 3993213b38..200793ff14 100644 --- a/editor/translations/fil.po +++ b/editor/translations/fil.po @@ -366,6 +366,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -816,6 +817,7 @@ msgstr "Maglagay" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -865,8 +867,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1892,7 +1893,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2009,7 +2009,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2178,7 +2179,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2209,6 +2210,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2904,7 +2907,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3039,10 +3042,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3262,6 +3261,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3339,7 +3339,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3565,6 +3564,12 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Salamin" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4426,6 +4431,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6076,6 +6082,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9376,7 +9383,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9384,7 +9391,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9392,7 +9404,37 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "Baguhin" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Komunidad" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9404,7 +9446,36 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Ilipat Ang Mga Bezier Points" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Username" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9412,48 +9483,132 @@ msgid "Detect new changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "Stage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +msgid "Unstage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" +msgid "Commit Message" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "Burahin ang (mga) Napiling Key" +msgid "Commit List" +msgstr "Komunidad" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Commit list size" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" +msgid "10" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "20" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Branches" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Branch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Ilipat Ang Mga Bezier Points" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Alisin" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Ilipat Ang Mga Bezier Points" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Alisin" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -11966,6 +12121,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12801,6 +12957,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Pagulit ng Animation" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12813,6 +13002,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12829,6 +13092,20 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Mga Functions:" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Baguhin ang Laki ng Array" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12838,6 +13115,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12846,6 +13127,55 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Node" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Mag-insert ng Key dito" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "CustomNode" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12855,12 +13185,65 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Mga Functions:" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13422,7 +13805,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13635,7 +14027,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/fr.po b/editor/translations/fr.po index ae81d3dbdd..722d9bdbf8 100644 --- a/editor/translations/fr.po +++ b/editor/translations/fr.po @@ -73,7 +73,7 @@ # Kevin Bouancheau <kevin.bouancheau@gmail.com>, 2020. # LaurentOngaro <laurent@gameamea.com>, 2020. # Julien Humbert <julroy67@gmail.com>, 2020. -# Nathan <bonnemainsnathan@gmail.com>, 2020, 2021. +# Nathan <bonnemainsnathan@gmail.com>, 2020, 2021, 2022. # Léo Vincent <l009.vincent@gmail.com>, 2020. # Joseph Boudou <joseph.boudou@matabio.net>, 2020. # Vincent Foulon <vincent.foulon80@gmail.com>, 2020. @@ -90,8 +90,8 @@ msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-01-03 03:55+0000\n" -"Last-Translator: Pierre Caye <pierrecaye@laposte.net>\n" +"PO-Revision-Date: 2022-01-12 16:52+0000\n" +"Last-Translator: Nathan <bonnemainsnathan@gmail.com>\n" "Language-Team: French <https://hosted.weblate.org/projects/godot-engine/" "godot/fr/>\n" "Language: fr\n" @@ -441,6 +441,7 @@ msgstr "Créer %d NOUVELLES pistes et insérer des clés ?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -916,6 +917,7 @@ msgstr "Ajouter" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -967,8 +969,7 @@ msgstr "Impossible de connecter le signal" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1575,7 +1576,7 @@ msgstr "Nom invalide." #: editor/editor_autoload_settings.cpp msgid "Cannot begin with a digit." -msgstr "" +msgstr "Ne peut pas commencer par un chiffre." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" @@ -2045,7 +2046,6 @@ msgid "New Folder..." msgstr "Nouveau dossier..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Rafraîchir" @@ -2162,7 +2162,8 @@ msgstr "Répertoires et fichiers :" msgid "Preview:" msgstr "Aperçu :" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Fichier :" @@ -2212,9 +2213,8 @@ msgid "Properties" msgstr "Propriétés" #: editor/editor_help.cpp -#, fuzzy msgid "overrides %s:" -msgstr "redéfinition :" +msgstr "écrase %s :" #: editor/editor_help.cpp msgid "default:" @@ -2337,7 +2337,7 @@ msgstr "Méthode" msgid "Signal" msgstr "Signaux" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Constante" @@ -2368,6 +2368,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Définir %s" @@ -2378,26 +2380,23 @@ msgstr "Définir plusieurs :" #: editor/editor_inspector.cpp msgid "Pinned %s" -msgstr "" +msgstr "Épinglé %s" #: editor/editor_inspector.cpp msgid "Unpinned %s" -msgstr "" +msgstr "Désépinglé %s" #: editor/editor_inspector.cpp -#, fuzzy msgid "Copy Property" -msgstr "Copier les propriétés" +msgstr "Copier la propriété" #: editor/editor_inspector.cpp -#, fuzzy msgid "Paste Property" -msgstr "Coller les propriétés" +msgstr "Coller la propriété" #: editor/editor_inspector.cpp -#, fuzzy msgid "Copy Property Path" -msgstr "Copier le chemin du script" +msgstr "Copier le chemin de la propriété" #: editor/editor_log.cpp msgid "Output:" @@ -3139,8 +3138,9 @@ msgid "Install Android Build Template..." msgstr "Installer un modèle de compilation Android..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Ouvrir le dossier de données du projets" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Ouvrir le dossier de données de l'éditeur" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3301,10 +3301,6 @@ msgid "Toggle Fullscreen" msgstr "Activer/Désactiver le plein écran" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Activer/désactiver la console système" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Ouvrir le dossier de données/paramètres de l'éditeur" @@ -3536,6 +3532,7 @@ msgid "Load Errors" msgstr "Erreurs de chargement" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Sélectionner" @@ -3612,7 +3609,6 @@ msgid "Author" msgstr "Auteur" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "État" @@ -3857,6 +3853,12 @@ msgstr "Chemin de la scène :" msgid "Import From Node:" msgstr "Importer à partir d'un nÅ“ud :" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Erreur" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "Ouvrir le dossier contenant ces modèles." @@ -4405,9 +4407,8 @@ msgid "Replace..." msgstr "Remplacer…" #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Replace in Files" -msgstr "Remplacer tout" +msgstr "Remplacer dans les fichiers" #: editor/find_in_files.cpp msgid "Find: " @@ -4418,9 +4419,8 @@ msgid "Replace: " msgstr "Remplacer : " #: editor/find_in_files.cpp -#, fuzzy msgid "Replace All (NO UNDO)" -msgstr "Remplacer tout" +msgstr "Remplacer tout (IRRÉVERSIBLE)" #: editor/find_in_files.cpp msgid "Searching..." @@ -4756,6 +4756,7 @@ msgid "Subfolder:" msgstr "Sous-dossier :" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Auteur :" @@ -6120,9 +6121,8 @@ msgid "Alt+Drag: Move selected node." msgstr "Alt + Glisser : Déplacer le nÅ“ud sélectionné." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Alt+Drag: Scale selected node." -msgstr "Alt + Glisser : Déplacer le nÅ“ud sélectionné." +msgstr "Alt + Glisser : Redimensionner le nÅ“ud sélectionné." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "V: Set selected node's pivot position." @@ -6156,7 +6156,7 @@ msgstr "Mode mise à l'échelle" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Shift: Scale proportionally." -msgstr "" +msgstr "Maj : Redimensionner proportionnellement." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6255,9 +6255,8 @@ msgstr "Verrouiller l'objet sélectionné (il ne pourra plus être déplacé)." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected Node(s)" -msgstr "Verrouillage Sélectionné" +msgstr "Verrouiller le(s) nÅ“ud(s) sélectionné(s)" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6266,9 +6265,8 @@ msgstr "Déverrouiller l'objet sélectionné (il pourra être déplacé de nouve #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected Node(s)" -msgstr "Déverrouillage Sélectionné" +msgstr "Déverrouiller le(s) nÅ“ud(s) sélectionné(s)" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6277,9 +6275,8 @@ msgstr "Rendre la sélection des enfants de l'objet impossible." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected Node(s)" -msgstr "Groupe sélectionné" +msgstr "Grouper le(s) nÅ“ud(s) sélectionné(s)" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6288,9 +6285,8 @@ msgstr "Rendre la sélection des enfants de l'objet de nouveau possible." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected Node(s)" -msgstr "Dégrouper Sélectionné" +msgstr "Dégrouper le(s) nÅ“ud(s) sélectionné(s)" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Skeleton Options" @@ -6463,6 +6459,7 @@ msgid "Zoom to 1600%" msgstr "Zoomer à 1600%" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Ajouter %s" @@ -7950,9 +7947,8 @@ msgid "Find in Files..." msgstr "Rechercher dans les fichiers…" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Replace in Files..." -msgstr "Remplacer…" +msgstr "Remplacer dans les fichiers…" #: editor/plugins/script_text_editor.cpp msgid "Contextual Help" @@ -9238,14 +9234,12 @@ msgid "Available Node-based types:" msgstr "Profils disponibles :" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Type name is empty!" -msgstr "Le nom de fichier est vide." +msgstr "Le nom du type est vide !" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Are you sure you want to create an empty type?" -msgstr "Voulez-vous vraiment ouvrir plus d'un projet à la fois ?" +msgstr "Voulez-vous vraiment créer plus un type vide ?" #: editor/plugins/theme_editor_plugin.cpp msgid "Confirm Item Rename" @@ -9871,7 +9865,8 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "Aucun addon VCS n'est disponible." #: editor/plugins/version_control_editor_plugin.cpp @@ -9879,16 +9874,56 @@ msgid "Error" msgstr "Erreur" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "Aucun fichier à ajouter" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Aucun nom renseigné." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "Enregistrer" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "VCS Addon n'est pas initialisé" +#, fuzzy +msgid "Staged Changes" +msgstr "Changements de shader :" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Changements de shader :" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Enregistrer" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Sous-arbre" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Voulez-vous vraiment créer plus un type vide ?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Appliquer la réinitialisation" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9899,16 +9934,148 @@ msgid "Initialize" msgstr "Initialiser" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "Zone de transit" +#, fuzzy +msgid "Remote Login" +msgstr "Supprimer un point" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Renommer" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Détecter de nouveaux changements" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Modifications" +#, fuzzy +msgid "Discard all changes" +msgstr "Quitter et sauvegarder les modifications ?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Stockage des modifications locales…" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Changements de matériau :" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Commiter les changements" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "Commiter les changements" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Enregistrer" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Correspondances :" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Créer un nouveau projet" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Supprimer la piste d’animation" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Distant" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Créer un nouveau projet" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Supprimer l'item" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Distant " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Distant " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Maillage source :" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9927,30 +10094,23 @@ msgid "Typechange" msgstr "Changement de type" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "Étape sélectionnée" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "Tout ajouter" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "Commiter les changements" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "" -"Vérifier les différences de fichier avant de les soumettre à la dernière " -"version" +#, fuzzy +msgid "View:" +msgstr "Affichage" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "Aucun fichier diff n'est actif" +#, fuzzy +msgid "Split" +msgstr "Diviser le chemin" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "Détecter les changements dans le fichier diff" +#, fuzzy +msgid "Unified" +msgstr "Modifié" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12664,6 +12824,7 @@ msgid "Export list to a CSV file" msgstr "Exporter la liste vers un fichier CSV" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Chemin de ressource" @@ -13516,6 +13677,40 @@ msgstr "Rafraîchir le graphique" msgid "Edit Member" msgstr "Modifier le membre" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Définir l'expression" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animation" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Type d'entrée non itérable : " @@ -13528,6 +13723,88 @@ msgstr "L'itérateur est devenu invalide" msgid "Iterator became invalid: " msgstr "L'itérateur est devenu invalide : " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Renommer le dossier :" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Tangage :" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Types :" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Self" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Au caractère %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Ajouter %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Définir %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Épinglé %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Obtenir %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Indice de nom de propriété invalide." @@ -13544,6 +13821,21 @@ msgstr "Le chemin ne mène pas au nÅ“ud !" msgid "Invalid index property name '%s' in node %s." msgstr "Nom de propriété invalide « %s » dans le nÅ“ud %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Définir %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Fonctions" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Redimensionner le tableau" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Argument invalide de type : " @@ -13553,6 +13845,10 @@ msgid ": Invalid arguments: " msgstr ": Arguments invalides : " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet introuvable dans le script : " @@ -13561,6 +13857,66 @@ msgid "VariableSet not found in script: " msgstr "VariableSet introuvable dans le script : " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Recharger" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Z Index" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Z Index" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "Activé le Singleton GDNative" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "NÅ“ud TimeSeek" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Édition de l'arbre de scène" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Self" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Couper les nÅ“uds" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" "Le nÅ“ud personnalisé n'a pas de méthode _step(), le graph ne peut pas être " @@ -13574,13 +13930,75 @@ msgstr "" "La valeur retournée par _step() est invalide, elle doit être un entier (seq " "out), ou une chaîne (erreur)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Appels" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Constantes" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Utiliser les coordonées locales" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Utiliser les coordonées locales" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Action" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Rechercher VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Obtenir %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Déplacer le cadre" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Image physique %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Signaux" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Signaux" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instance" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14255,16 +14673,26 @@ msgstr "" "d'un nÅ“ud de type ParallaxBackground." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "Les particules de type GPU ne sont pas supportées par le pilote graphique " "GLES2.\n" "Utilisez le nÅ“ud CPUParticles2D à la place. Vous pouvez utiliser l'option « " "Convertir en CPUParticles » pour ce faire." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14522,10 +14950,11 @@ msgid "Only uniform scales are supported." msgstr "Seules les échelles uniformes sont prises en charge." #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "Les particules de type GPU ne sont pas supportées par le pilote graphique " "GLES2.\n" @@ -14534,6 +14963,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" "Rien n'est visible car les maillages n'ont pas été assignés au tirage des " diff --git a/editor/translations/ga.po b/editor/translations/ga.po index d0e6734463..03611eed78 100644 --- a/editor/translations/ga.po +++ b/editor/translations/ga.po @@ -357,6 +357,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -807,6 +808,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -856,8 +858,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1883,7 +1884,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2000,7 +2000,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2169,7 +2170,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2199,6 +2200,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2893,7 +2896,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3028,10 +3031,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3248,6 +3247,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3324,7 +3324,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3549,6 +3548,11 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +msgid "%s Error" +msgstr "" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4407,6 +4411,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6053,6 +6058,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9344,7 +9350,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9352,7 +9358,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9360,7 +9371,35 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9372,7 +9411,36 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +msgid "Remote Login" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Ainm nua:" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9380,49 +9448,131 @@ msgid "Detect new changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "Stage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit List" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "Ainm nua:" +msgid "Create New Branch" +msgstr "Cruthaigh" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remove Branch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remotes" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "Scrios ionchur" +msgid "Create New Remote" +msgstr "Cruthaigh" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Remove Remote" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +msgid "Remote Name" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Remote URL" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Force Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "Ainm nua:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "Scrios ionchur" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -11935,6 +12085,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12768,6 +12919,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "CrannBeochan" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12780,6 +12964,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12796,6 +13054,19 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Cruthaigh" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12805,6 +13076,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12813,6 +13088,56 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Nód Cumaisc2" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Cruthaigh" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "CustomNode" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12822,12 +13147,65 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Cruthaigh" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13390,7 +13768,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13603,7 +13990,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/gl.po b/editor/translations/gl.po index 02e2a982b8..f98288945e 100644 --- a/editor/translations/gl.po +++ b/editor/translations/gl.po @@ -360,6 +360,7 @@ msgstr "Crear %d novas pistas e engadir chaves?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -829,6 +830,7 @@ msgstr "Engadir" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -880,8 +882,7 @@ msgstr "No se pode conectar a sinal" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1960,7 +1961,6 @@ msgid "New Folder..." msgstr "Novo Cartafol..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Actualizar" @@ -2077,7 +2077,8 @@ msgstr "Directorios e Arquivos:" msgid "Preview:" msgstr "Vista Previa:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Arquivo:" @@ -2254,7 +2255,7 @@ msgstr "Método" msgid "Signal" msgstr "Sinal" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Constante" @@ -2285,6 +2286,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -3047,8 +3050,9 @@ msgid "Install Android Build Template..." msgstr "Instalar plantilla de compilación de Android..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Abrir Cartafol de Datos do Proxecto" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Abrir Cartafol de Datos do Editor" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3206,10 +3210,6 @@ msgid "Toggle Fullscreen" msgstr "Act./Desact. Pantalla Completa" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Act./Desact. Consola do Sistema" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Abrir Cartafol de Datos/Configuración do Editor" @@ -3433,6 +3433,7 @@ msgid "Load Errors" msgstr "Erros durante a Carga" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Elixir" @@ -3513,7 +3514,6 @@ msgid "Author" msgstr "Autores" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Estado" @@ -3751,6 +3751,12 @@ msgstr "Ruta da Escena:" msgid "Import From Node:" msgstr "Importar Desde Nodo:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Erro" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4640,6 +4646,7 @@ msgid "Subfolder:" msgstr "Subcartafol:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Autor:" @@ -6322,6 +6329,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Engadir %s" @@ -9743,7 +9751,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9751,18 +9759,58 @@ msgid "Error" msgstr "Erro" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Nome non proporcionado." + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "Cambios" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Cambios" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Comunidade" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Subárbore" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Está seguro de que quere abrir máis dun proxecto?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Restablecer" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -9771,7 +9819,37 @@ msgid "Initialize" msgstr "Inicializar" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Eliminar Punto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Renomear" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9779,49 +9857,143 @@ msgid "Detect new changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Cambios" +#, fuzzy +msgid "Discard all changes" +msgstr "Parámetro Cambiado" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" -msgstr "Modificado" +#, fuzzy +msgid "Stage all changes" +msgstr "Gardando cambios locales..." #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" -msgstr "Renomeado" +#, fuzzy +msgid "Unstage all changes" +msgstr "Parámetro Cambiado" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" -msgstr "Eliminado" +msgid "Commit Message" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Commit Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Comunidade" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +msgid "10" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "20" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +#, fuzzy +msgid "Branches" +msgstr "Coincidencias:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Crear Novo Proxecto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Eliminar Pista de Animación" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +#, fuzzy +msgid "Remotes" +msgstr "Remoto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Crear Novo Proxecto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Eliminar Elemento" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Remoto " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Remoto " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Push" msgstr "" +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "Modificado" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "Renomeado" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "Eliminado" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "View:" +msgstr "Ver" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unified" +msgstr "Modificado" + #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" msgstr "" @@ -12433,6 +12605,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13268,6 +13441,39 @@ msgstr "" msgid "Edit Member" msgstr "Editar Membro" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animación" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -13280,6 +13486,86 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Renomeando Cartafol:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Cabeceo" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Tipo:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Propio" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Engadir %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Engadir %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -13296,6 +13582,20 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funcións" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Redimensionar Array" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -13305,6 +13605,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -13313,6 +13617,65 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Recargar" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Ãndice:" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Ãndice:" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Eliminar Nodo" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Edición de Ãrbore de Escenas" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Propio" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Cortar Nodos" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -13322,14 +13685,76 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Chamadas" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Constantes" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Usar Espazo Local" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Usar Espazo Local" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Acción" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Buscar en VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Seguinte pestana" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Fotograma de FÃsica %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" msgstr "" +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Sinal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Sinal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instanciar" + #: platform/android/export/export_plugin.cpp msgid "Package name is missing." msgstr "" @@ -13929,16 +14354,26 @@ msgid "" msgstr "" #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "As partÃculas baseadas na GPU non están soportas por o controlador de vÃdeo " "de GLES2.\n" "Usa o nodo CPUParticles2D no seu lugar. Podes usar a opción \"Converter a " "CPUParticles\" con tal motivo." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14166,10 +14601,11 @@ msgid "Only uniform scales are supported." msgstr "" #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "As partÃculas baseadas na GPU non están soportas por o controlador de vÃdeo " "de GLES2.\n" @@ -14178,6 +14614,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" diff --git a/editor/translations/he.po b/editor/translations/he.po index 3c2ce4ff95..73da4945f9 100644 --- a/editor/translations/he.po +++ b/editor/translations/he.po @@ -376,6 +376,7 @@ msgstr "×”×× ×œ×™×¦×•×¨ %d רצועות חדשות ×•×œ×”×›× ×™×¡ מפתחות #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -837,6 +838,7 @@ msgstr "הוספה" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -886,8 +888,7 @@ msgstr "×ין ×פשרות לחבר ×ות" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1937,7 +1938,6 @@ msgid "New Folder..." msgstr "תיקייה חדשה…" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "×¨×¢× ×•×Ÿ" @@ -2054,7 +2054,8 @@ msgstr "תיקיות וקבצי×:" msgid "Preview:" msgstr "תצוגה מקדימה:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "קובץ:" @@ -2228,7 +2229,7 @@ msgstr "מתודה" msgid "Signal" msgstr "×ות" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "קבוע" @@ -2259,6 +2260,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "קביעת %s" @@ -2992,8 +2995,9 @@ msgid "Install Android Build Template..." msgstr "×”×ª×§× ×ª ×ª×‘× ×™×ª ×‘× ×™×™×” ל×× ×“×¨×•×יד..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "פתיחת תיקיית × ×ª×•× ×™ המיז×" +#, fuzzy +msgid "Open User Data Folder" +msgstr "פתיחת תיקיית × ×ª×•× ×™ העורך" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3146,10 +3150,6 @@ msgid "Toggle Fullscreen" msgstr "הפעלת/ביטול מסך מל×" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "הפעלת/ביטול מסוף מערכת" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "פתיחת תיקיית × ×ª×•× ×™/הגדרות העורך" @@ -3380,6 +3380,7 @@ msgid "Load Errors" msgstr "שגי×ות ×˜×¢×™× ×”" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "בחירה" @@ -3461,7 +3462,6 @@ msgid "Author" msgstr "יוצרי×" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3694,6 +3694,12 @@ msgstr "× ×ª×™×‘ ×¡×¦× ×•×ª:" msgid "Import From Node:" msgstr "×™×™×‘×•× ×ž×ž×¤×¨×§:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "שגי××”!" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4622,6 +4628,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "יוצר:" @@ -6358,6 +6365,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9889,7 +9897,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9897,19 +9905,58 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy +msgid "No commit message was provided." +msgstr "×œ× ×¦×•×™×Ÿ ש×." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy msgid "Commit" msgstr "קהילה" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "×©×™× ×•×™×™ חומרי×" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "×©×™× ×•×™×™ חומרי×" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "קהילה" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "×”×× ×תה בטוח ש×תה רוצה להסיר ×ת כל ×”×—×™×‘×•×¨×™× ×ž×”×ות ×”×–×”?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "החל ×יפוס" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -9919,7 +9966,37 @@ msgid "Initialize" msgstr "הגדלת ×ות ר××©×•× ×”" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "הסרת × ×§×•×“×” ×‘× ×ª×™×‘" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "×©×™× ×•×™ ש×" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9929,53 +10006,146 @@ msgstr "יצירת %s חדש" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Changes" -msgstr "×©×™× ×•×™" +msgid "Discard all changes" +msgstr "לסגור ולשמור ×ת ×”×©×™× ×•×™×™×?" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +#, fuzzy +msgid "Stage all changes" +msgstr "×”×©×™× ×•×™×™× ×”×ž×§×•×ž×™×™× ×ž××•×—×¡× ×™×…" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "×©×™× ×•×™×™ חומרי×" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "×¡× ×›×¨×•×Ÿ ×”×©×™× ×•×™×™× ×‘×¡×§×¨×™×¤×˜" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Changes" +msgstr "×¡× ×›×¨×•×Ÿ ×”×©×™× ×•×™×™× ×‘×¡×§×¨×™×¤×˜" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "קהילה" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "×©×™× ×•×™ ש×" +msgid "Branches" +msgstr "הת×מות:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "למחוק" +msgid "Create New Branch" +msgstr "יצירת %s חדש" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Typechange" -msgstr "×©×™× ×•×™" +msgid "Remove Branch" +msgstr "מחיקת רצועת ×”× ×¤×©×”" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "מחובר" +msgid "Remotes" +msgstr "מרוחק" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "לשמור הכול" +msgid "Create New Remote" +msgstr "יצירת %s חדש" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" -msgstr "×¡× ×›×¨×•×Ÿ ×”×©×™× ×•×™×™× ×‘×¡×§×¨×™×¤×˜" +msgid "Remove Remote" +msgstr "הסרת ×ª×‘× ×™×ª" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "מרוחק " #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +#, fuzzy +msgid "Remote URL" +msgstr "מרוחק " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +#, fuzzy +msgid "Force Push" +msgstr "× ×ª×™×‘ המש×ב" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "×©×™× ×•×™ ש×" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "למחוק" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Typechange" +msgstr "×©×™× ×•×™" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "View:" +msgstr "תצוגה מקדימה:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Split" +msgstr "פיצול × ×ª×™×‘" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12588,6 +12758,7 @@ msgid "Export list to a CSV file" msgstr "×™×™×¦×•× ×¨×©×™×ž×” לקובץ CSV" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "× ×ª×™×‘ המש×ב" @@ -13435,6 +13606,40 @@ msgstr "×¨×¢× ×•×Ÿ תרשי×" msgid "Edit Member" msgstr "עריכת שדה" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "גרסה × ×•×›×—×™×ª:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "×”× ×¤×©×”" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "סוג הקלט ×œ× ×–×ž×™×Ÿ למחזוריות: " @@ -13447,6 +13652,85 @@ msgstr "×יטרטור הפך ×œ×œ× ×—×•×§×™" msgid "Iterator became invalid: " msgstr "×יטרטור הפך ×œ×œ× ×—×•×§×™: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "×©×™× ×•×™ ×©× ×”×ª×™×§×™×™×”:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "סוג" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "עצמי" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "×ª×•×•×™× ×ª×§×¤×™×:" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "קביעת %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "קבלת %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "×©× ×ž×פיין ×”××™× ×“×§×¡ שגוי." @@ -13463,6 +13747,21 @@ msgstr "×”× ×ª×™×‘ ×œ× ×ž×•×‘×™×œ מפרק!" msgid "Invalid index property name '%s' in node %s." msgstr "×©× ×ž×פיין ××™× ×“×§×¡ ×œ× ×—×•×§×™ '%s' במפרק %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "קביעת %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "×¤×•× ×§×¦×™×•×ª" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "×©×™× ×•×™ גודל המערך" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": ××¨×’×•×ž× ×˜ שגוי מסוג: " @@ -13472,6 +13771,10 @@ msgid ": Invalid arguments: " msgstr ": ××¨×’×•×ž× ×˜×™× ×©×’×•×™×™×: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "×œ× × ×ž×¦× VariableGet בסקריפט: " @@ -13480,6 +13783,66 @@ msgid "VariableSet not found in script: " msgstr "×œ× × ×ž×¦× VariableSet בסקריפט: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "×¨×¢× ×•×Ÿ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "×”×–×—×” ×וטומטית" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "×”×–×—×” ×וטומטית" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "קבוע" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "קבוע" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "קבוע" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "קבוע" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "×¡×™× ×’×œ×˜×•×Ÿ GDNative מ×ופשר" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "מפרק TimeSeek" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "עריכת ×¢×¥ ×”×¡×¦× ×•×ª" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "עצמי" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "גזירת מפרקי×" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "למפרק המות×× ×ין שיטת ‎_step()‎, ×ין ×פשרות לעבד תרשי×." @@ -13490,13 +13853,75 @@ msgid "" msgstr "" "ערך מוחזר ×œ× ×—×•×§×™ מ-_step(), חייב להיות מספר ×©×œ× (seq out) ×ו מחרוזת (שגי××”)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "קרי×ות" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "קבועי×" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "מצב מרחב מקומי (%s)" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "מצב מרחב מקומי (%s)" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "כל הבחירה" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "חיפוש VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "קבלת %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "מצב ×”×–×–×” (W)" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "שקופית פיזיקלית %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "×ות" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "×ות" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "עותק" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14122,15 +14547,25 @@ msgstr "" "מפרק ParallaxLayer עובד רק ×›×שר ×”×•× ×ž×•×’×“×¨ כצ××¦× ×©×œ מפרק ParallaxBackground." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "×—×œ×§×™×§×™× ×ž×‘×•×¡×¡×™ GPU ××™× × × ×ª×ž×›×™× ×¢×œ-ידי ×ž× ×”×œ וויד×ו GLES2.\n" "השתמש בצומת CPUParticles2D במקו×. למטרה זו ×”×פשרות \"המר ×œ×—×œ×§×™×§×™× ×©×œ CPU\" " "קיימת." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14367,10 +14802,11 @@ msgid "Only uniform scales are supported." msgstr "" #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "×—×œ×§×™×§×™× ×ž×‘×•×¡×¡×™ GPU ××™× × × ×ª×ž×›×™× ×¢×œ-ידי ×ž× ×”×œ וויד×ו GLES2.\n" "השתמש בצומת CPUParticles במקו×. למטרה זו ×”×פשרות \"המר ×œ×—×œ×§×™×§×™× ×©×œ CPU\" " @@ -14378,6 +14814,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "×©×•× ×“×‘×¨ ××™× ×• גלוי ×›×™ רשתות ×œ× ×”×•×§×¦×• למעברי ההדפסה." diff --git a/editor/translations/hi.po b/editor/translations/hi.po index 29d59d3ee1..65e129c224 100644 --- a/editor/translations/hi.po +++ b/editor/translations/hi.po @@ -369,6 +369,7 @@ msgstr "% D नठटà¥à¤°à¥ˆà¤• बनाà¤à¤‚ और कà¥à¤‚जियाà #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -835,6 +836,7 @@ msgstr "जोड़िये" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -886,8 +888,7 @@ msgstr "इशारा कनेकà¥à¤Ÿ नहीं कर सकते" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1957,7 +1958,6 @@ msgid "New Folder..." msgstr "नया फ़ोलà¥à¤¡à¤°..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "रिफ़à¥à¤°à¥‡à¤¶" @@ -2074,7 +2074,8 @@ msgstr "डायरेकà¥à¤Ÿà¤°à¤¿à¤œ & फ़ाइले:" msgid "Preview:" msgstr "पूरà¥à¤µ दरà¥à¤¶à¤¨:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "फ़ाइल:" @@ -2248,7 +2249,7 @@ msgstr "मेथड" msgid "Signal" msgstr "सिगà¥à¤¨à¤²" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ" @@ -2279,6 +2280,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -3016,8 +3019,9 @@ msgid "Install Android Build Template..." msgstr "à¤à¤‚डà¥à¤°à¥‰à¤¯à¤¡ बिलà¥à¤¡ टेमà¥à¤ªà¤²à¥‡à¤Ÿ सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करें..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ डेटा फ़ोलà¥à¤¡à¤° खोलिये" +#, fuzzy +msgid "Open User Data Folder" +msgstr "संपादक डेटा फ़ोलà¥à¤¡à¤° खोलें" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3173,10 +3177,6 @@ msgid "Toggle Fullscreen" msgstr "पूरà¥à¤£à¤¸à¥à¤•à¥à¤°à¥€à¤¨ चालू करें" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "टॉगल सिसà¥à¤Ÿà¤® कंसोल" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "संपादक डेटा / सेटिंगà¥à¤¸ फ़ोलà¥à¤¡à¤° खोलें" @@ -3409,6 +3409,7 @@ msgid "Load Errors" msgstr "लोड तà¥à¤°à¥à¤Ÿà¤¿à¤¯à¤¾à¤‚" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "चà¥à¤¨à¥‡à¤‚" @@ -3489,7 +3490,6 @@ msgid "Author" msgstr "लेखक" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3726,6 +3726,12 @@ msgstr "दृशà¥à¤¯ पथ:" msgid "Import From Node:" msgstr "नोड से आयात:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "पà¥à¤°à¤¤à¤¿à¤®à¤¾" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4625,6 +4631,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "लेखक:" @@ -6286,6 +6293,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9707,7 +9715,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9715,19 +9723,57 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy +msgid "No commit message was provided." +msgstr "कोई नाम पà¥à¤°à¤¦à¤¾à¤¨ नहीं किया गया।" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy msgid "Commit" msgstr "समà¥à¤¦à¤¾à¤¯" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "बदली" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "समà¥à¤¦à¤¾à¤¯" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "कà¥à¤¯à¤¾ आप सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ हैं कि आप इस सिगà¥à¤¨à¤² से सà¤à¥€ कनेकà¥à¤¶à¤¨ हटाना चाहते हैं?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "रीसेट आकार" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -9736,7 +9782,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "मिटाना" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "नाम बदली" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9745,50 +9821,143 @@ msgid "Detect new changes" msgstr "à¤à¤• नया बनाà¤à¤‚" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +#, fuzzy +msgid "Stage all changes" +msgstr "लोकल बदलीया सà¥à¤Ÿà¥‹à¤° कर रहा है..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "लोकल बदलीया सà¥à¤Ÿà¥‹à¤° कर रहा है..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "समà¥à¤¦à¤¾à¤¯" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "ऑडियो बस का नाम बदलें" +msgid "Commit List" +msgstr "समà¥à¤¦à¤¾à¤¯" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "को हटा दें" +msgid "Branches" +msgstr "à¤à¤• जैसा:" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +#, fuzzy +msgid "Create New Branch" +msgstr "नया%s बनाà¤à¤‚" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "अनीम टà¥à¤°à¥ˆà¤• निकालें" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "जà¥à¤¡à¤¿à¤¯à¥‡" +msgid "Remotes" +msgstr "मिटाइये" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "नया%s बनाà¤à¤‚" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "आइटम निकालें" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "नोड का नाम:" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +#, fuzzy +msgid "Remote URL" +msgstr "मिटाइये" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" +msgid "Pull" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Force Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "ऑडियो बस का नाम बदलें" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "को हटा दें" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "View:" +msgstr "पूरà¥à¤µ दरà¥à¤¶à¤¨:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Split" +msgstr "नोड वकà¥à¤° संपादित करें" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12357,6 +12526,7 @@ msgid "Export list to a CSV file" msgstr "â€à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13212,6 +13382,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "à¤à¤¨à¤¿à¤®à¥‡à¤¶à¤¨" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -13224,6 +13427,82 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "फ़ोलà¥à¤¡à¤° का नाम बदल रहे है:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "सà¥à¤µà¤¯à¤‚" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -13240,6 +13519,20 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "कारà¥à¤¯à¥‹à¤‚" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Array को बड़ा या छोटा करना" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -13249,6 +13542,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -13257,6 +13554,63 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "पà¥à¤¨à¤ƒ लोड करें" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "नोड हटाà¤à¤‚" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "सीन टà¥à¤°à¥€ à¤à¤¡à¤¿à¤Ÿà¤¿à¤‚ग" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "सà¥à¤µà¤¯à¤‚" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -13266,14 +13620,74 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "कॉल" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "कारà¥à¤¯" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "अगला टैब" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "फिजिकà¥à¤¸ फà¥à¤°à¥‡à¤® %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" msgstr "" +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "सिगà¥à¤¨à¤²" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "सिगà¥à¤¨à¤²" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "इनसà¥à¤Ÿà¤¨à¥à¤¸" + #: platform/android/export/export_plugin.cpp msgid "Package name is missing." msgstr "" @@ -13858,7 +14272,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14073,7 +14496,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/hr.po b/editor/translations/hr.po index a5279a9099..b722aa151a 100644 --- a/editor/translations/hr.po +++ b/editor/translations/hr.po @@ -359,6 +359,7 @@ msgstr "Napravi %d NOVIH staza i umetni kljuÄeve?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -814,6 +815,7 @@ msgstr "Dodaj" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -863,8 +865,7 @@ msgstr "Ne mogu spojiti signal" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1910,7 +1911,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2027,7 +2027,8 @@ msgstr "Direktoriji i datoteke:" msgid "Preview:" msgstr "Pregled:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Datoteka:" @@ -2195,7 +2196,7 @@ msgstr "Metoda" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2226,6 +2227,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2922,8 +2925,9 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Otvori datoteku" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3058,10 +3062,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3280,6 +3280,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3358,7 +3359,6 @@ msgid "Author" msgstr "Autori" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3585,6 +3585,12 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "GreÅ¡ka!" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4455,6 +4461,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6109,6 +6116,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9425,7 +9433,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9433,7 +9441,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9441,7 +9454,39 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "Promijeni" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Promijeni" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Zajednica" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Jesi li siguran da želiÅ¡ ukloniti sve veze s ovog signala?" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9453,7 +9498,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "ObriÅ¡i Bezier ToÄku" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Preimenuj zvuÄnu sabirnicu" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9461,53 +9536,143 @@ msgid "Detect new changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Promjene" +msgid "Discard all changes" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +#, fuzzy +msgid "Stage all changes" +msgstr "Promijeni" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "Preimenuj zvuÄnu sabirnicu" +msgid "Commit Message" +msgstr "Promijeni" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "ObriÅ¡i" +msgid "Commit Changes" +msgstr "Promijeni" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Typechange" +msgid "Commit List" msgstr "Promijeni" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "Brisati odabrani kljuÄ/odabrane kljuÄeve" +msgid "Branches" +msgstr "Podudaranja:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "Zamijeni sve" +msgid "Create New Branch" +msgstr "Napravi novi %s" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" +msgid "Remove Branch" +msgstr "Ukloni Stazu Animacije" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Ukloni" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Napravi novi %s" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "ObriÅ¡i Bezier ToÄku" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Naziv ÄŒvora(node):" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Ukloni" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "Preimenuj zvuÄnu sabirnicu" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "ObriÅ¡i" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Typechange" msgstr "Promijeni" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Unmerged" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +#, fuzzy +msgid "View:" +msgstr "Pregled:" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12027,6 +12192,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12868,6 +13034,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Animacija" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12880,6 +13079,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12896,6 +13169,19 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funkcije" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12905,6 +13191,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12913,6 +13203,56 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Premjesti Ävor(node)" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Kreiraj Scenu" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "CustomNode" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12922,12 +13262,67 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Funkcije" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Premjesti Okvir" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Signal:" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13490,7 +13885,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13703,7 +14107,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/hu.po b/editor/translations/hu.po index 722be28839..9130ef9507 100644 --- a/editor/translations/hu.po +++ b/editor/translations/hu.po @@ -377,6 +377,7 @@ msgstr "Létrehoz %d ÚJ sávot és beszúrja a kulcsokat?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -851,6 +852,7 @@ msgstr "Hozzáadás" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -901,8 +903,7 @@ msgstr "Nem lehet csatlakoztatni a jelet" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1974,7 +1975,6 @@ msgid "New Folder..." msgstr "Új Mappa..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "FrissÃtés" @@ -2091,7 +2091,8 @@ msgstr "Könyvtárak és Fájlok:" msgid "Preview:" msgstr "ElÅ‘nézet:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Fájl:" @@ -2268,7 +2269,7 @@ msgstr "Metódus" msgid "Signal" msgstr "Jelzés" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Ãllandó" @@ -2299,6 +2300,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -3066,8 +3069,9 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Projektadat-mappa megnyitása" +#, fuzzy +msgid "Open User Data Folder" +msgstr "SzerkesztÅ‘ Adatmappájának Megnyitása" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3220,10 +3224,6 @@ msgid "Toggle Fullscreen" msgstr "Teljes KépernyÅ‘" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Rendszerkonzol be- és kikapcsolása" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "SzerkesztÅ‘ adatok/beállÃtások mappa megnyitása" @@ -3453,6 +3453,7 @@ msgid "Load Errors" msgstr "Betöltési Hibák" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Kiválasztás" @@ -3533,7 +3534,6 @@ msgid "Author" msgstr "SzerzÅ‘k" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3763,6 +3763,12 @@ msgstr "Scene elérési Út:" msgid "Import From Node:" msgstr "Importálás Node-ból:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Hiba!" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4664,6 +4670,7 @@ msgid "Subfolder:" msgstr "Almappa:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "SzerzÅ‘:" @@ -6353,6 +6360,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "%s Hozzáadása" @@ -9749,7 +9757,7 @@ msgid "TileSet" msgstr "Csempekészlet" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9757,18 +9765,57 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Nincs név megadva." + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "Változások" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Változások" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Közösség" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Biztos, hogy egynél több projektet nyit meg?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "VisszaállÃtás" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -9777,7 +9824,37 @@ msgid "Initialize" msgstr "Inicializálás" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Pont eltávolÃtása" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Ãtnevezés" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9785,49 +9862,145 @@ msgid "Detect new changes" msgstr "Új változások észlelése" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Változások" +#, fuzzy +msgid "Discard all changes" +msgstr "Bezárja és menti a változásokat?" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" -msgstr "MódosÃtott" +#, fuzzy +msgid "Stage all changes" +msgstr "Helyi módosÃtások eltárolása..." #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" -msgstr "Ãtnevezve" +#, fuzzy +msgid "Unstage all changes" +msgstr "A paraméter megváltozott" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" -msgstr "Törölve" +msgid "Commit Message" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" -msgstr "TÃpusmódosÃtás" +msgid "Commit Changes" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +#, fuzzy +msgid "Commit List" +msgstr "Közösség" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "10" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" +msgid "20" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +#, fuzzy +msgid "Branches" +msgstr "Egyezések:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Új Projekt Létrehozása" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Animáció Sáv EltávolÃtása" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +#, fuzzy +msgid "Remotes" +msgstr "EltávolÃtás" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Új Projekt Létrehozása" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Elem eltávolÃtása" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Node neve:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "EltávolÃtás" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" msgstr "" +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Forrás Mesh:" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "MódosÃtott" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "Ãtnevezve" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "Törölve" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "TÃpusmódosÃtás" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "View:" +msgstr "Nézet" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Split" +msgstr "Útvonal Felosztása" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unified" +msgstr "MódosÃtott" + #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" msgstr "" @@ -12353,6 +12526,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13199,6 +13373,40 @@ msgstr "Grafikon frissÃtése" msgid "Edit Member" msgstr "Tag szerkesztése" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Kifejezés beállÃtása" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animáció" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Beviteli tÃpus nem iterálható: " @@ -13211,6 +13419,86 @@ msgstr "Az iterátor érvénytelenné vált" msgid "Iterator became invalid: " msgstr "Az iterátor érvénytelenné vált: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Mappa átnevezése:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "TÃpus:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Saját" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "A(z) %s karakternél" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "%s Hozzáadása" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "%s Hozzáadása" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -13227,6 +13515,20 @@ msgstr "Az út nem vezeti a csomópontot!" msgid "Invalid index property name '%s' in node %s." msgstr "Érvénytelen index tulajdonság név: '%s' a(z) %s node-ban." +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Függvények" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Tömb átméretezése" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Érvénytelen tÃpusargumentum: " @@ -13236,6 +13538,10 @@ msgid ": Invalid arguments: " msgstr ": Érvénytelen argumentumok: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet nem található a szkriptben: " @@ -13244,6 +13550,65 @@ msgid "VariableSet not found in script: " msgstr "VariableSet nem található a szkriptben: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Újratöltés" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Z index" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Z index" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Ãllandó" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Ãllandó" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Ãllandó" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Ãllandó" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "IdÅ‘KeresÅ‘ Node" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Jelenetfa szerkesztése" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Saját" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Node-ok kivágása" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -13253,14 +13618,74 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "HÃvások" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Ãllandók" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Művelet" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Keret mozgatása" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Fizika Keret %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" msgstr "" +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Jelzés" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Jelzés" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Példány" + #: platform/android/export/export_plugin.cpp msgid "Package name is missing." msgstr "" @@ -13840,7 +14265,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14055,7 +14489,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/id.po b/editor/translations/id.po index 686536da75..524562bec9 100644 --- a/editor/translations/id.po +++ b/editor/translations/id.po @@ -391,6 +391,7 @@ msgstr "Buat track BARU %d dan masukkan tombol-tombol?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -859,6 +860,7 @@ msgstr "Tambah" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -909,8 +911,7 @@ msgstr "Tidak dapat menghubungkan sinyal" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1974,7 +1975,6 @@ msgid "New Folder..." msgstr "Buat Direktori..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Segarkan" @@ -2091,7 +2091,8 @@ msgstr "Direktori-direktori & File-file:" msgid "Preview:" msgstr "Pratinjau:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "File:" @@ -2270,7 +2271,7 @@ msgstr "Fungsi" msgid "Signal" msgstr "Sinyal" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Konstan" @@ -2301,6 +2302,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Setel %s" @@ -3057,8 +3060,9 @@ msgid "Install Android Build Template..." msgstr "Pasang Templat Build Android..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Buka Project Data Manager" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Buka Folder Data Editor" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3215,10 +3219,6 @@ msgid "Toggle Fullscreen" msgstr "Mode Layar Penuh" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Jungkitkan Konsol Sistem" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Buka Direktori Data/Pengaturan Editor" @@ -3448,6 +3448,7 @@ msgid "Load Errors" msgstr "Muat Galat" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Pilih" @@ -3524,7 +3525,6 @@ msgid "Author" msgstr "Pencipta" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Status" @@ -3768,6 +3768,12 @@ msgstr "Lokasi Skena:" msgid "Import From Node:" msgstr "Impor dari Node:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Galat" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "Buka folder yang berisi template ini." @@ -4649,6 +4655,7 @@ msgid "Subfolder:" msgstr "Subdirektori:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Pembuat:" @@ -6340,6 +6347,7 @@ msgid "Zoom to 1600%" msgstr "Perbesar 1600%" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Tambah %s" @@ -9766,7 +9774,8 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "Tidak ada ekstensi VCS yang tersedia." #: editor/plugins/version_control_editor_plugin.cpp @@ -9774,16 +9783,56 @@ msgid "Error" msgstr "Galat" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "Tidak ada berkas yang ditambahkan ke staging" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Nama masih kosong." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "Komit" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "Pengaya VCS tidak diinisialisasi" +#, fuzzy +msgid "Staged Changes" +msgstr "Perubahan Shader:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Perubahan Shader:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Komit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Subpohon" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Apakah Anda yakin membuka lebih dari satu proyek?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Terapkan Reset" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9794,16 +9843,148 @@ msgid "Initialize" msgstr "Inisialisasi" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "Area staging" +#, fuzzy +msgid "Remote Login" +msgstr "Hapus Titik" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Ubah Nama" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Deteksi perubahan baru" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Perubahan" +#, fuzzy +msgid "Discard all changes" +msgstr "Tutup dan simpan perubahan?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Menyimpan perubahan-perubahan lokal..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Perubahan Material:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Komit Perubahan" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "Komit Perubahan" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Komit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Kecocokan:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Buat Projek Baru" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Hapus Trek Anim" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Remot" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Buat Projek Baru" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Hapus item" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Remot " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Remot " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Sumber Mesh:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9822,28 +10003,23 @@ msgid "Typechange" msgstr "Jenis perubahan" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "Stage Hanya yang Dipilih" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "Stage Semua" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "Komit Perubahan" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "Tampilkan perbedaan berkas sebelum mengkomitnya ke versi terbaru" +#, fuzzy +msgid "View:" +msgstr "Pandangan" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "Tidak ada berkas diff yang sedang aktif" +#, fuzzy +msgid "Split" +msgstr "Pisahkan Tapak" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "Deteksi perubahan dalam berkas diff" +#, fuzzy +msgid "Unified" +msgstr "Dimodifikasi" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12545,6 +12721,7 @@ msgid "Export list to a CSV file" msgstr "Ekspor daftar ke berkas CSV" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Lokasi Resource" @@ -13402,6 +13579,40 @@ msgstr "Segarkan Grafik" msgid "Edit Member" msgstr "Sunting Anggota" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Tetapkan ekspresi" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animasi" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Tipe masukan tidak iterable: " @@ -13414,6 +13625,88 @@ msgstr "Iterator menjadi tidak sah" msgid "Iterator became invalid: " msgstr "Iterator menjadi tidak sah: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Mengubah nama folder dengan:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Dongak:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Jenis:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Sendiri" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Pada karakter %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Tambah %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Setel %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Tambah %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Dapatkan %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Nama properti index tidak sah." @@ -13430,6 +13723,21 @@ msgstr "Path tidak menunjukkan Node!" msgid "Invalid index property name '%s' in node %s." msgstr "Nama properti index '%s' tidak sah dalam node %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Setel %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Fungsi" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Ubah ukuran Array" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Argumen tidak sah dari tipe: " @@ -13439,6 +13747,10 @@ msgid ": Invalid arguments: " msgstr ": Argumen-argumen tidak sah: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet tidak ditemukan dalam script: " @@ -13447,6 +13759,66 @@ msgid "VariableSet not found in script: " msgstr "VariableSet tidak ditemukan dalam script: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Muat Ulang" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Indeks Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Indeks Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Konstan" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Konstan" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Konstan" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Konstan" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "Aktifkan Singleton GDNative" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Node TimeSeek" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Menyunting Pohon Skena" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Sendiri" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Potong Node" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" "Node modifikasi tidak memiliki method _step(), tidak bisa memproses grafik." @@ -13459,13 +13831,75 @@ msgstr "" "Nilai kembali dari _step() tidak sah, seharusnya integer (seq out), atau " "string (error)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Panggil" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Konstanta" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Gunakan Ruang Lokal" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Gunakan Ruang Lokal" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Aksi" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Cari VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Dapatkan %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Geser Frame" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Frame Fisika %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Sinyal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Sinyal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instansi" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14104,15 +14538,25 @@ msgstr "" "node ParallaxBackground." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "Partikel berbasis GPU tidak didukung oleh video driver GLES2.\n" "Gunakan node CPUParticles2D sebagai gantinya. Anda dapat menggunakan opsi " "\"Konversikan jadi CPUParticles\" untuk tujuan ini." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14366,10 +14810,11 @@ msgid "Only uniform scales are supported." msgstr "" #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "Partikel berbasis GPU tidak didukung oleh driver video GLES2.\n" "Gunakan CPUParticles saja. Anda dapat menggunakan opsi \"Konversikan ke " @@ -14377,6 +14822,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" "Tidak ada yang ditampilkan karena mesh tidak ditetapkan untuk menggambar " diff --git a/editor/translations/is.po b/editor/translations/is.po index 99a2daa775..773a89394f 100644 --- a/editor/translations/is.po +++ b/editor/translations/is.po @@ -380,6 +380,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -842,6 +843,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -891,8 +893,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1923,7 +1924,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2040,7 +2040,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2208,7 +2209,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2238,6 +2239,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2937,7 +2940,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3073,10 +3076,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3295,6 +3294,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3372,7 +3372,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3599,6 +3598,11 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +msgid "%s Error" +msgstr "" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4460,6 +4464,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6133,6 +6138,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9474,7 +9480,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9482,7 +9488,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9490,7 +9501,35 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9502,7 +9541,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Fjarlægja val" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Endurnefning Anim track" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9510,50 +9579,135 @@ msgid "Detect new changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "Stage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit List" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "Endurnefning Anim track" +msgid "Create New Branch" +msgstr "Val á kvarða" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "Anim DELETE-lyklar" +msgid "Remove Branch" +msgstr "Fjarlægja Anim track" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Branch Name" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "Val á kvarða" +msgid "Remotes" +msgstr "Fjarlægja val" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Create New Remote" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" +#, fuzzy +msgid "Remove Remote" +msgstr "Fjarlægja val" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Fjarlægja val" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote URL" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Force Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "Endurnefning Anim track" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "Anim DELETE-lyklar" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Split" +msgstr "Breyta hnútnum Ferill" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12091,6 +12245,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12939,6 +13094,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Stillið breyting á:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12951,6 +13139,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12967,6 +13229,19 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Val á kvarða" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12976,6 +13251,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12984,6 +13263,56 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Anim DELETE-lyklar" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Tree" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "TvÃteknir lyklar" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12993,12 +13322,66 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Allt úrvalið" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Hreyfa Viðbótar Lykil" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13561,7 +13944,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13774,7 +14166,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/it.po b/editor/translations/it.po index 18b4fe4bce..0d2c6a07e6 100644 --- a/editor/translations/it.po +++ b/editor/translations/it.po @@ -420,6 +420,7 @@ msgstr "Creare %d NUOVE tracce e inserirci i fotogrammi chiavi?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -893,6 +894,7 @@ msgstr "Aggiungi" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -944,8 +946,7 @@ msgstr "Impossibile connettere il segnale" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -2018,7 +2019,6 @@ msgid "New Folder..." msgstr "Nuova cartella..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Aggiorna" @@ -2135,7 +2135,8 @@ msgstr "File e cartelle:" msgid "Preview:" msgstr "Anteprima:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "File:" @@ -2310,7 +2311,7 @@ msgstr "Metodo" msgid "Signal" msgstr "Segnale" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Costante" @@ -2341,6 +2342,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Imposta %s" @@ -3107,8 +3110,9 @@ msgid "Install Android Build Template..." msgstr "Installa il modello di costruzione per Android…" #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Apri la cartella del progetto" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Apri la cartella dei dati dell'editor" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3266,10 +3270,6 @@ msgid "Toggle Fullscreen" msgstr "Commuta la modalità a schermo intero" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Commuta la console di sistema" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Apri cartella dei dati/impostazioni editor" @@ -3502,6 +3502,7 @@ msgid "Load Errors" msgstr "Errori di caricamento" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Seleziona" @@ -3578,7 +3579,6 @@ msgid "Author" msgstr "Autore" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Stato" @@ -3825,6 +3825,12 @@ msgstr "Percorso Scena:" msgid "Import From Node:" msgstr "Importa Da Nodo:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Errore" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "Apre la cartella che contiene questi modelli." @@ -4731,6 +4737,7 @@ msgid "Subfolder:" msgstr "Sottocartella:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Autore:" @@ -6459,6 +6466,7 @@ msgid "Zoom to 1600%" msgstr "Zoom a 1600%" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Aggiungi %s" @@ -9905,7 +9913,8 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "Non sono disponibili estensioni VCS." #: editor/plugins/version_control_editor_plugin.cpp @@ -9913,16 +9922,56 @@ msgid "Error" msgstr "Errore" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "Nessun file aggiunto allo stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Nessun nome fornito." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "Commit" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "L'Estenzione VCS non è inizializzata" +#, fuzzy +msgid "Staged Changes" +msgstr "Cambiamenti degli shader:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Cambiamenti degli shader:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Commit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Sottoalbero" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Sei sicuro di voler aprire più di un progetto?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Reimposta" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9933,16 +9982,148 @@ msgid "Initialize" msgstr "Inizializza" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "Area di Staging" +#, fuzzy +msgid "Remote Login" +msgstr "Rimuovi punto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Rinomina" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Rileva nuove modifiche" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Cambiamenti" +#, fuzzy +msgid "Discard all changes" +msgstr "Chiudi e salva le modifiche?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Memorizzazione dei cambiamenti locali…" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Cambiamenti dei materiali:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Commit Modifiche" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "Commit Modifiche" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Commit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Corrispondenze:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Crea Nuovo Progetto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Rimuovi una traccia d'animazione" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Remoto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Crea Nuovo Progetto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Rimuovi l'elemento" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Remoto " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Remoto " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Mesh Sorgente:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9961,30 +10142,23 @@ msgid "Typechange" msgstr "Cambio di tipo" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "Stage selezionato" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "Stage Tutto" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "Commit Modifiche" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "" -"Visualizza i file diffs prima di eseguire il commit nella versione più " -"recente" +#, fuzzy +msgid "View:" +msgstr "Vista" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "Nessun file diff è attivo" +#, fuzzy +msgid "Split" +msgstr "Dividi Percorso" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "Individua cambiamenti nei file diff" +#, fuzzy +msgid "Unified" +msgstr "Modificato" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12693,6 +12867,7 @@ msgid "Export list to a CSV file" msgstr "Esporta l'elenco in un file CSV" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Percorso Risorsa" @@ -13544,6 +13719,40 @@ msgstr "Aggiorna grafico" msgid "Edit Member" msgstr "Modifica membro" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Cambia espressione" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animazione" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Il tipo di input non è iterabile: " @@ -13556,6 +13765,88 @@ msgstr "L'iteratore è diventato invalido" msgid "Iterator became invalid: " msgstr "L'iteratore è diventato invalido: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Rinomina cartella:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Inclinazione:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Tipo:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Proprio" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Al carattere %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Aggiungi %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Imposta %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Aggiungi %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Ottieni %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Nome proprietà indice invalido." @@ -13572,6 +13863,21 @@ msgstr "Il percorso non conduce a un Nodo!" msgid "Invalid index property name '%s' in node %s." msgstr "Nome proprietà indice invalido \"%s\" nel nodo %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Imposta %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funzioni" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Ridimensiona lista" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Argomento invalido di tipo: " @@ -13581,6 +13887,10 @@ msgid ": Invalid arguments: " msgstr ": Argomenti invalidi: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet non trovato nello script: " @@ -13589,6 +13899,66 @@ msgid "VariableSet not found in script: " msgstr "VariableSet non trovato nello script: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Ricarica" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Indice Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Indice Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Costante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Costante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Costante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Costante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "Singleton GDNative abilitato" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Nodo TimeScale" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Modifica delle scene" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Proprio" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Taglia nodi" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" "Il nodo personalizzato non ha alcun metodo _step(), impossibile elaborare il " @@ -13602,13 +13972,75 @@ msgstr "" "Valore di ritorno di _step() non valido, deve essere un intero (seq out), " "oppure una stringa (errore)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Chiamate" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Costanti" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Usa Spazio Locale" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Usa Spazio Locale" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Azione" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Ricerca VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Ottieni %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Sposta Frame" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "% fotogramma fisico" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Segnale" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Segnale" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Istanza" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14281,15 +14713,25 @@ msgstr "" "ParallaxBackground." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "Le particelle basate su GPU non sono supportate dal driver video GLES2.\n" "Utilizzare invece il nodo CPUParticles2D. A tale scopo è possibile " "utilizzare l'opzione \"Converti in CPUParticles\"." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14546,10 +14988,11 @@ msgid "Only uniform scales are supported." msgstr "Solo scale uniformi sono supportate." #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "Le particelle basate su GPU non sono supportate dal driver video GLES2.\n" "Utilizzare invece il nodo CPUParticles. A tale scopo è possibile utilizzare " @@ -14557,6 +15000,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "Nulla é visibile perché le mesh non sono state assegnate ai draw pass." diff --git a/editor/translations/ja.po b/editor/translations/ja.po index 5ed1e5c5fe..1e6c425b50 100644 --- a/editor/translations/ja.po +++ b/editor/translations/ja.po @@ -390,6 +390,7 @@ msgstr "%d æ–°è¦ãƒˆãƒ©ãƒƒã‚¯ã‚’作æˆã—ã€ã‚ーを挿入ã—ã¾ã™ã‹ï¼Ÿ" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -860,6 +861,7 @@ msgstr "è¿½åŠ " #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -909,8 +911,7 @@ msgstr "ã‚·ã‚°ãƒŠãƒ«ã«æŽ¥ç¶šã§ãã¾ã›ã‚“" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1974,7 +1975,6 @@ msgid "New Folder..." msgstr "æ–°è¦ãƒ•ォルダー..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "å†èªã¿è¾¼ã¿" @@ -2091,7 +2091,8 @@ msgstr "ディレクトリã¨ãƒ•ァイル:" msgid "Preview:" msgstr "プレビュー:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "ファイル:" @@ -2266,7 +2267,7 @@ msgstr "メソッド" msgid "Signal" msgstr "シグナル" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "コンスタント" @@ -2297,6 +2298,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "%s ã‚’è¨å®š" @@ -3051,8 +3054,9 @@ msgid "Install Android Build Template..." msgstr "Androidビルドテンプレートã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆã®ãƒ‡ãƒ¼ã‚¿ãƒ•ォルダーを開ã" +#, fuzzy +msgid "Open User Data Folder" +msgstr "エディターã®ãƒ‡ãƒ¼ã‚¿ãƒ•ォルダーを開ã" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3211,10 +3215,6 @@ msgid "Toggle Fullscreen" msgstr "フルスクリーンを有効化 / 無効化" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "システムコンソールを有効化 / 無効化" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "エディターã®ãƒ‡ãƒ¼ã‚¿ / è¨å®šãƒ•ォルダーを開ã" @@ -3445,6 +3445,7 @@ msgid "Load Errors" msgstr "èªã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "é¸æŠž" @@ -3521,7 +3522,6 @@ msgid "Author" msgstr "作者" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "ステータス" @@ -3763,6 +3763,12 @@ msgstr "シーンã®ãƒ‘ス:" msgid "Import From Node:" msgstr "ノードã‹ã‚‰ã‚¤ãƒ³ãƒãƒ¼ãƒˆ:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "エラー" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "ã“れらã®ãƒ†ãƒ³ãƒ—レートãŒã‚るフォルダーを開ãã¾ã™ã€‚" @@ -4651,6 +4657,7 @@ msgid "Subfolder:" msgstr "サブフォルダー:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "作者:" @@ -6343,6 +6350,7 @@ msgid "Zoom to 1600%" msgstr "1600%ã«ã‚ºãƒ¼ãƒ " #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "%s ã‚’è¿½åŠ " @@ -9722,7 +9730,8 @@ msgid "TileSet" msgstr "タイルセット" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "VCSアドオンã¯åˆ©ç”¨ã§ãã¾ã›ã‚“。" #: editor/plugins/version_control_editor_plugin.cpp @@ -9730,16 +9739,56 @@ msgid "Error" msgstr "エラー" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "ステージã«è¿½åŠ ã•れã¦ã„るファイルãŒã‚りã¾ã›ã‚“" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "åå‰ãŒä»˜ã„ã¦ã„ã¾ã›ã‚“。" #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "コミット" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "VCSアドオンã¯åˆæœŸåŒ–ã•れã¦ã„ã¾ã›ã‚“" +#, fuzzy +msgid "Staged Changes" +msgstr "シェーダーã®å¤‰æ›´:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "シェーダーã®å¤‰æ›´:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "コミット" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "サブツリー" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "複数ã®ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆã‚’é–‹ã„ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "リセット" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9750,16 +9799,148 @@ msgid "Initialize" msgstr "åˆæœŸåŒ–" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "ステージングエリア" +#, fuzzy +msgid "Remote Login" +msgstr "ãƒã‚¤ãƒ³ãƒˆã‚’削除" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "åå‰ã®å¤‰æ›´" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "æ–°ã—ã„変更点を検出" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "変更点" +#, fuzzy +msgid "Discard all changes" +msgstr "変更をä¿å˜ã—ã¦é–‰ã˜ã¾ã™ã‹ï¼Ÿ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "ãƒãƒ¼ã‚«ãƒ«ã®å¤‰æ›´ã‚’ä¿å˜..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "マテリアルã®å¤‰æ›´:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "変更をコミットã™ã‚‹" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "変更をコミットã™ã‚‹" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "コミット" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "一致:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "æ–°è¦ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆã‚’作æˆ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "アニメーショントラックを除去" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "リモート" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "æ–°è¦ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆã‚’作æˆ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "アイテムを除去" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "リモート " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "リモート " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "ソースメッシュ:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9778,28 +9959,23 @@ msgid "Typechange" msgstr "タイプ変更" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "é¸æŠžå¯¾è±¡ã‚’ã‚¹ãƒ†ãƒ¼ã‚¸ã™ã‚‹" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "ã™ã¹ã¦ã‚’ステージã™ã‚‹" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "変更をコミットã™ã‚‹" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "最新ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ã‚³ãƒŸãƒƒãƒˆã™ã‚‹å‰ã«ãƒ•ァイルã®å·®åˆ†ã‚’表示" +#, fuzzy +msgid "View:" +msgstr "ビュー" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "有効ãªãƒ•ァイル差分ã¯ã‚りã¾ã›ã‚“" +#, fuzzy +msgid "Split" +msgstr "パスを分割" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "ファイル差分ã®å¤‰æ›´ã‚’検知" +#, fuzzy +msgid "Unified" +msgstr "変更済ã¿" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12481,6 +12657,7 @@ msgid "Export list to a CSV file" msgstr "リストをCSVファイルã«ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "リソース パス" @@ -13330,6 +13507,40 @@ msgstr "グラフを更新" msgid "Edit Member" msgstr "メンãƒãƒ¼ã‚’編集" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "å¼ã‚’è¨å®š" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "アニメーション" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "入力タイプã¯å復å¯èƒ½ã§ã¯ã‚りã¾ã›ã‚“: " @@ -13342,6 +13553,88 @@ msgstr "イテレーターãŒç„¡åйã«ãªã‚Šã¾ã—ãŸ" msgid "Iterator became invalid: " msgstr "イテレーターãŒç„¡åйã«ãªã‚Šã¾ã—ãŸ: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "フォルダーåを変更:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "ピッãƒ:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "åž‹:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "自己" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "æ–‡å— %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "%s ã‚’è¿½åŠ " + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "%s ã‚’è¨å®š" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "%s ã‚’è¿½åŠ " + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "%s ã‚’å–å¾—" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "インデックスã®ãƒ—ãƒãƒ‘ティåãŒç„¡åйã§ã™ã€‚" @@ -13358,6 +13651,21 @@ msgstr "パスãŒãƒŽãƒ¼ãƒ‰ã«é”ã—ã¾ã›ã‚“ï¼" msgid "Invalid index property name '%s' in node %s." msgstr "ノード%sã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®ãƒ—ãƒãƒ‘ティå'%s'ã¯ç„¡åйã§ã™ã€‚" +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "%s ã‚’è¨å®š" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "関数" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "é…列ã®ã‚µã‚¤ã‚ºã‚’変更" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ":無効ãªå¼•æ•° 引数ã®åž‹: " @@ -13367,6 +13675,10 @@ msgid ": Invalid arguments: " msgstr ": 無効ãªå¼•æ•°: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGetãŒã‚¹ã‚¯ãƒªãƒ—ト内ã«ã‚りã¾ã›ã‚“: " @@ -13375,6 +13687,66 @@ msgid "VariableSet not found in script: " msgstr "VariableSetãŒã‚¹ã‚¯ãƒªãƒ—ト内ã«ã‚りã¾ã›ã‚“: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "å†èªã¿è¾¼ã¿" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Zインデックス" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Zインデックス" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "コンスタント" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "コンスタント" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "コンスタント" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "コンスタント" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "有効ãªGDNativeシングルトン" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "タイムシーク ノード" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "シーンツリーã®ç·¨é›†" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "自己" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "ノードを切りå–ã‚‹" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "カスタムノードã«_step() メソッドãŒç„¡ã„ãŸã‚ã€ã‚°ãƒ©ãƒ•を処ç†ã§ãã¾ã›ã‚“。" @@ -13386,13 +13758,75 @@ msgstr "" "_step()ã®æˆ»ã‚Šå€¤ãŒç„¡åйã§ã™ã€‚integer (seq out)ã¾ãŸã¯string (error)ã§ãªã‘れã°ãª" "りã¾ã›ã‚“。" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "呼ã³å‡ºã—" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "定数" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "ãƒãƒ¼ã‚«ãƒ«ç©ºé–“を使用" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "ãƒãƒ¼ã‚«ãƒ«ç©ºé–“を使用" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "アクション(Action)" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "VisualScriptを検索" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "%s ã‚’å–å¾—" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "フレームã®ç§»å‹•" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "物ç†ãƒ•レーム%" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "シグナル" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "シグナル" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "インスタンス" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14030,16 +14464,26 @@ msgstr "" "ã®ã¿å‹•作ã—ã¾ã™ã€‚" #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "GPUベースã®ãƒ‘ーティクルã¯ã€GLES2ビデオドライãƒãƒ¼ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›" "ん。\n" "代ã‚りã«CPUParticles2Dノードを使用ã—ã¦ãã ã•ã„。ã“ã®ç›®çš„ã®ãŸã‚ã« \"CPUパー" "ティクルã«å¤‰æ›\" オプションを使用ã§ãã¾ã™ã€‚" +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14294,10 +14738,11 @@ msgid "Only uniform scales are supported." msgstr "uniform スケールã®ã¿ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™ã€‚" #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "GPUベースã®ãƒ‘ーティクルã¯ã€GLES2ビデオドライãƒãƒ¼ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›" "ん。\n" @@ -14306,6 +14751,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "æç”»ãƒ‘スã«ãƒ¡ãƒƒã‚·ãƒ¥ãŒå‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ãªã„ãŸã‚ã€ä½•も表示ã•れã¾ã›ã‚“。" diff --git a/editor/translations/ka.po b/editor/translations/ka.po index 09eea3dce4..d436b3b6d1 100644 --- a/editor/translations/ka.po +++ b/editor/translations/ka.po @@ -387,6 +387,7 @@ msgstr "áƒáƒ®áƒáƒšáƒ˜ %d ჩáƒáƒœáƒáƒ¬áƒ”რების შექმნრ#: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -869,6 +870,7 @@ msgstr "დáƒáƒ›áƒáƒ¢áƒ”ბáƒ" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -920,8 +922,7 @@ msgstr "დáƒáƒ›áƒáƒ™áƒáƒ•შირებელი სიგნáƒáƒšáƒ˜:" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1989,7 +1990,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2109,7 +2109,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2286,7 +2287,7 @@ msgstr "მáƒáƒœáƒ˜áƒ¨áƒœáƒ£áƒšáƒ˜ მხáƒáƒšáƒáƒ“" msgid "Signal" msgstr "სიგნáƒáƒšáƒ”ბი" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "მუდმივი" @@ -2317,6 +2318,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -3022,7 +3025,7 @@ msgstr "" #: editor/editor_node.cpp #, fuzzy -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "პრáƒáƒ”ქტის დáƒáƒ›áƒ¤áƒ£áƒ«áƒœáƒ”ბლები" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3159,10 +3162,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3381,6 +3380,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3460,7 +3460,6 @@ msgid "Author" msgstr "áƒáƒ•ტáƒáƒ ები" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3689,6 +3688,12 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "სáƒáƒ კე" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4578,6 +4583,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6292,6 +6298,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9705,7 +9712,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9713,7 +9720,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9721,10 +9733,41 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "ცვლილებáƒ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "ცვლილებáƒ" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "ზუმის სáƒáƒ¬áƒ§áƒ˜áƒ¡áƒ–ე დáƒáƒ§áƒ”ნებáƒ" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -9733,7 +9776,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "მáƒáƒœáƒ˜áƒ¨áƒ•ნის მáƒáƒ¨áƒáƒ ებáƒ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "áƒáƒ£áƒ“ირგáƒáƒ“áƒáƒ›áƒ¢áƒáƒœáƒ˜áƒ¡ სáƒáƒ®áƒ”ლის ცვლილებáƒ" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9742,54 +9815,143 @@ msgid "Detect new changes" msgstr "áƒáƒ®áƒáƒšáƒ˜ %s შექმნáƒ" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Discard all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Changes" -msgstr "ცვლილებáƒ" +msgid "Stage all changes" +msgstr "áƒáƒ®áƒáƒšáƒ˜ %s შექმნáƒ" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "Unstage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "áƒáƒ£áƒ“ირგáƒáƒ“áƒáƒ›áƒ¢áƒáƒœáƒ˜áƒ¡ სáƒáƒ®áƒ”ლის ცვლილებáƒ" +msgid "Commit Message" +msgstr "ცვლილებáƒ" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "წáƒáƒ¨áƒšáƒ" +msgid "Commit Changes" +msgstr "ცვლილებáƒ" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Typechange" +msgid "Commit List" msgstr "ცვლილებáƒ" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "მáƒáƒœáƒ˜áƒ¨áƒ•ნის მáƒáƒ¡áƒ¨áƒ¢áƒáƒ‘ის ცვლილებáƒ" +msgid "Branches" +msgstr "დáƒáƒ›áƒ—ხვევები:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "ყველáƒáƒ¡ ჩáƒáƒœáƒáƒªáƒ•ლებáƒ" +msgid "Create New Branch" +msgstr "áƒáƒ®áƒáƒšáƒ˜ %s შექმნáƒ" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" +msgid "Remove Branch" +msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ თრექის წáƒáƒ¨áƒšáƒ" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "მáƒáƒ¨áƒáƒ ებáƒ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "áƒáƒ®áƒáƒšáƒ˜ %s შექმნáƒ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "მáƒáƒœáƒ˜áƒ¨áƒ•ნის მáƒáƒ¨áƒáƒ ებáƒ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "მáƒáƒ¨áƒáƒ ებáƒ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "მáƒáƒ¨áƒáƒ ებáƒ" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "áƒáƒ£áƒ“ირგáƒáƒ“áƒáƒ›áƒ¢áƒáƒœáƒ˜áƒ¡ სáƒáƒ®áƒ”ლის ცვლილებáƒ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "წáƒáƒ¨áƒšáƒ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Typechange" msgstr "ცვლილებáƒ" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Unmerged" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "View:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +#, fuzzy +msgid "Split" +msgstr "კვáƒáƒœáƒ«áƒ˜áƒ¡ მრუდის რედáƒáƒ¥áƒ¢áƒ˜áƒ ებáƒ" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12368,6 +12530,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13222,6 +13385,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "ფუნქციები:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -13234,6 +13430,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -13250,6 +13520,20 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "ფუნქციები:" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "მáƒáƒ¡áƒ˜áƒ•ის ზáƒáƒ›áƒ˜áƒ¡ ცვლილებáƒ" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -13259,6 +13543,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -13267,6 +13555,61 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "მუდმივი" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "მუდმივი" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "მუდმივი" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "მუდმივი" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "წáƒáƒ¨áƒšáƒ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "შექმნáƒ" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ¡áƒáƒ¦áƒ”ბების áƒáƒ¡áƒšáƒ˜áƒ¡ შექმნáƒ" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -13276,12 +13619,68 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "მუდმივი" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "ყველრმáƒáƒœáƒ˜áƒ¨áƒœáƒ•áƒ" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "სიგნáƒáƒšáƒ”ბი" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "სიგნáƒáƒšáƒ”ბი" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13855,7 +14254,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14068,7 +14476,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/km.po b/editor/translations/km.po index 570aace246..db013eeb5d 100644 --- a/editor/translations/km.po +++ b/editor/translations/km.po @@ -357,6 +357,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -806,6 +807,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -855,8 +857,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1879,7 +1880,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -1996,7 +1996,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2164,7 +2165,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2194,6 +2195,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2887,7 +2890,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3022,10 +3025,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3243,6 +3242,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3319,7 +3319,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3544,6 +3543,11 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +msgid "%s Error" +msgstr "" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4399,6 +4403,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6047,6 +6052,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9331,7 +9337,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9339,7 +9345,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9347,7 +9358,35 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9359,39 +9398,55 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +msgid "Remote Login" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect new changes" +msgid "Username" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Password" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "SSH Public Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +msgid "Select SSH public key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" +msgid "SSH Private Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect new changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +msgid "Stage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Unstage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9399,15 +9454,107 @@ msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Commit List" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Create New Branch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Remove Branch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remotes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remove Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote URL" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -11916,6 +12063,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12744,6 +12892,38 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Condition" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12756,6 +12936,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12772,6 +13026,18 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Function" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12781,6 +13047,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12789,6 +13059,55 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Node" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "បញ្ចូល Key នៅទីនáŸáŸ‡" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "CustomNode" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12798,12 +13117,64 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Action %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13365,7 +13736,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13578,7 +13958,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/ko.po b/editor/translations/ko.po index 674d0ab18c..d35224bd42 100644 --- a/editor/translations/ko.po +++ b/editor/translations/ko.po @@ -385,6 +385,7 @@ msgstr "%dê°œì˜ ìƒˆ íŠ¸ëž™ì„ ë§Œë“¤ê³ í‚¤ë¥¼ ì‚½ìž…í• ê¹Œìš”?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -852,6 +853,7 @@ msgstr "추가" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -903,8 +905,7 @@ msgstr "시그ë„ì„ ì—°ê²°í• ìˆ˜ ì—†ìŒ" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1960,7 +1961,6 @@ msgid "New Folder..." msgstr "새 í´ë”..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "ìƒˆë¡œê³ ì¹¨" @@ -2077,7 +2077,8 @@ msgstr "ë””ë ‰í† ë¦¬ & 파ì¼:" msgid "Preview:" msgstr "미리보기:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "파ì¼:" @@ -2253,7 +2254,7 @@ msgstr "메서드" msgid "Signal" msgstr "시그ë„" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "ìƒìˆ˜" @@ -2284,6 +2285,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Set %s" @@ -3035,8 +3038,9 @@ msgid "Install Android Build Template..." msgstr "Android 빌드 템플릿 설치..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "프로ì 트 ë°ì´í„° í´ë” 열기" +#, fuzzy +msgid "Open User Data Folder" +msgstr "ì—디터 ë°ì´í„° í´ë” 열기" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3192,10 +3196,6 @@ msgid "Toggle Fullscreen" msgstr "ì „ì²´ 화면 í† ê¸€" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "시스템 콘솔 í† ê¸€" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "ì—디터 ë°ì´í„°/ì„¤ì • í´ë” 열기" @@ -3423,6 +3423,7 @@ msgid "Load Errors" msgstr "불러오기 오류" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "ì„ íƒ" @@ -3499,7 +3500,6 @@ msgid "Author" msgstr "ì €ìž" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "ìƒíƒœ" @@ -3739,6 +3739,12 @@ msgstr "씬 경로:" msgid "Import From Node:" msgstr "노드ì—서 ê°€ì ¸ì˜¤ê¸°:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "오류" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "ì´ í…œí”Œë¦¿ì„ í¬í•¨í•˜ëŠ” í´ë”를 엽니다." @@ -4622,6 +4628,7 @@ msgid "Subfolder:" msgstr "하위 í´ë”:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "ì €ìž:" @@ -6306,6 +6313,7 @@ msgid "Zoom to 1600%" msgstr "1600%로 줌" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "%s 추가" @@ -9670,7 +9678,8 @@ msgid "TileSet" msgstr "타ì¼ì…‹" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "ì´ìš©í• 수 있는 ë²„ì „ 관리 시스템(VCS)ì´ ì—†ìŠµë‹ˆë‹¤." #: editor/plugins/version_control_editor_plugin.cpp @@ -9678,16 +9687,56 @@ msgid "Error" msgstr "오류" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "스테ì´ì§€ì— ì¶”ê°€ëœ íŒŒì¼ì´ 없습니다" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "ì´ë¦„ì„ ì œê³µí•˜ì§€ 않았습니다." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "커밋" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "ë²„ì „ 관리 시스템(VCS)ì´ ì´ˆê¸°í™”ë˜ì§€ 않았습니다" +#, fuzzy +msgid "Staged Changes" +msgstr "ì…°ì´ë” 바꾸기:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "ì…°ì´ë” 바꾸기:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "커밋" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "하위 트리" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "ë‘ ê°œ ì´ìƒì˜ 프로ì 트를 ì—¬ì‹œê² ìŠµë‹ˆê¹Œ?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "ìž¬ì„¤ì • ì ìš©" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9698,16 +9747,148 @@ msgid "Initialize" msgstr "초기화" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "스테ì´ì§• ì˜ì—" +#, fuzzy +msgid "Remote Login" +msgstr "ì ì œê±°" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "ì´ë¦„ 바꾸기" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "새 ë³€ê²½ì‚¬í• ê°ì§€" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "변경사í•" +#, fuzzy +msgid "Discard all changes" +msgstr "변경사í•ì„ ì €ìž¥í•˜ê³ ë‹«ì„까요?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "로컬 변경사í•ì„ ì €ìž¥í•˜ëŠ” 중..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "머티리얼 바꾸기:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "커밋 변경사í•" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "커밋 변경사í•" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "커밋" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "ì¼ì¹˜í•¨:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "새 프로ì 트 만들기" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "ì• ë‹ˆë©”ì´ì…˜ 트랙 ì œê±°" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "ì›ê²©" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "새 프로ì 트 만들기" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "í•목 ì œê±°" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "ì›ê²© " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "ì›ê²© " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "ì›ë³¸ 메시:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9726,28 +9907,23 @@ msgid "Typechange" msgstr "타입체ì¸ì§€" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "ì„ íƒ í•목 스테ì´ì§€ë¡œ 보내기" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "ëª¨ë‘ ìŠ¤í…Œì´ì§€ë¡œ 보내기" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "커밋 변경사í•" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "ìµœì‹ ë²„ì „ìœ¼ë¡œ 커밋하기 ì „ì— íŒŒì¼ diff 보기" +#, fuzzy +msgid "View:" +msgstr "보기" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "íŒŒì¼ diffê°€ ì¼œì ¸ 있지 않습니다" +#, fuzzy +msgid "Split" +msgstr "경로 가르기" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "íŒŒì¼ ì°¨ì´ì—서 ê°ì§€í•œ 변경사í•" +#, fuzzy +msgid "Unified" +msgstr "ìˆ˜ì •ë¨" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12401,6 +12577,7 @@ msgid "Export list to a CSV file" msgstr "목ë¡ì„ CSV 파ì¼ë¡œ 내보내기" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "리소스 경로" @@ -13243,6 +13420,40 @@ msgstr "그래프 ìƒˆë¡œê³ ì¹¨" msgid "Edit Member" msgstr "멤버 편집" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "í‘œí˜„ì‹ ì„¤ì •" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "ì• ë‹ˆë©”ì´ì…˜" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "ë°˜ë³µí• ìˆ˜ 없는 ìž…ë ¥ 타입: " @@ -13255,6 +13466,88 @@ msgstr "Iteratorê°€ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" msgid "Iterator became invalid: " msgstr "Iteratorê°€ 잘못ë¨: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "í´ë” ì´ë¦„ 바꾸기:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Pitch:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "타입:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "ìžì²´" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "(ë¬¸ìž %s 위치)" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "%s 추가" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Set %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "%s 추가" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Get %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "ìž˜ëª»ëœ ì¸ë±ìФ ì†ì„± ì´ë¦„." @@ -13271,6 +13564,21 @@ msgstr "노드를 ì§€ì •í•˜ëŠ” 경로가 아닙니다!" msgid "Invalid index property name '%s' in node %s." msgstr "노드 %s ì•ˆì— ì¸ë±ìФ ì†ì„± ì´ë¦„ '%s'ì´(ê°€) 잘못ë˜ì—ˆìŠµë‹ˆë‹¤." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Set %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "함수(Function)" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "ë°°ì—´ í¬ê¸° 바꾸기" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": ìž˜ëª»ëœ ì¸ìˆ˜ 타입: " @@ -13280,6 +13588,10 @@ msgid ": Invalid arguments: " msgstr ": ìž˜ëª»ëœ ì¸ìˆ˜: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGetì„ ìŠ¤í¬ë¦½íЏì—서 ì°¾ì„ ìˆ˜ ì—†ìŒ: " @@ -13288,6 +13600,66 @@ msgid "VariableSet not found in script: " msgstr "VariableSetì„ ìŠ¤í¬ë¦½íЏì—서 ì°¾ì„ ìˆ˜ ì—†ìŒ: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "ìƒˆë¡œê³ ì¹¨" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Z ì¸ë±ìФ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Z ì¸ë±ìФ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "ìƒìˆ˜" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "ìƒìˆ˜" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "ìƒìˆ˜" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "ìƒìˆ˜" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "í™œì„±í™”ëœ GDNative 싱글톤" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "시간 íƒìƒ‰ 노드" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "씬 트리 편집" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "ìžì²´" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "노드 잘ë¼ë‚´ê¸°" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "커스텀 ë…¸ë“œì— _step() 메서드가 없습니다. 그래프를 ì²˜ë¦¬í• ìˆ˜ 없습니다." @@ -13299,13 +13671,75 @@ msgstr "" "_step()ì—서 ìž˜ëª»ëœ ë°˜í™˜ 값입니다. ì •ìˆ˜ (seq out), ë˜ëŠ” 문ìžì—´ (error)ì´ì–´ì•¼ " "합니다." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "호출" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "ìƒìˆ˜" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "로컬 공간 사용" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "로컬 공간 사용" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "ì•¡ì…˜" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "비주얼스í¬ë¦½íЏ 검색" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "í”„ë ˆìž„ ì´ë™" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "물리 í”„ë ˆìž„ %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "시그ë„" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "시그ë„" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "ì¸ìŠ¤í„´ìŠ¤í•˜ê¸°" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -13922,15 +14356,25 @@ msgstr "" "ParallaxLayer는 ParallaxBackground ë…¸ë“œì˜ ìžì‹ 노드로 ìžˆì„ ë•Œë§Œ ìž‘ë™í•©ë‹ˆë‹¤." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "GPU 기반 파티í´ì€ GLES2 비디오 드ë¼ì´ë²„ì—서 ì§€ì›í•˜ì§€ 않습니다.\n" "ëŒ€ì‹ CPUParticles2D 노드를 사용하세요. ì´ ê²½ìš° \"CPUParticles로 변환\" 옵션" "ì„ ì‚¬ìš©í• ìˆ˜ 있습니다." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14177,10 +14621,11 @@ msgid "Only uniform scales are supported." msgstr "Uniform 스케ì¼ë§Œ ì§€ì›ë©ë‹ˆë‹¤." #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "GPU 기반 파티í´ì€ GLES2 비디오 드ë¼ì´ë²„ì—서 ì§€ì›í•˜ì§€ 않습니다.\n" "ëŒ€ì‹ CPUParticles 노드를 사용하세요. ì´ ê²½ìš° \"CPUParticles로 변환\" ì„¤ì •ì„ " @@ -14188,6 +14633,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "메시가 패스를 그리ë„ë¡ ì§€ì •í•˜ì§€ 않아서, 아무 ê²ƒë„ ë³´ì´ì§€ 않습니다." diff --git a/editor/translations/lt.po b/editor/translations/lt.po index c9ef760bbf..53f33e0585 100644 --- a/editor/translations/lt.po +++ b/editor/translations/lt.po @@ -370,6 +370,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -842,6 +843,7 @@ msgstr "PridÄ—ti" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -892,8 +894,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1947,7 +1948,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2066,7 +2066,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2241,7 +2242,7 @@ msgstr "" msgid "Signal" msgstr "Signalai" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Konstanta" @@ -2272,6 +2273,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2980,8 +2983,9 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Atidaryti" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3117,10 +3121,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3340,6 +3340,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3421,7 +3422,6 @@ msgid "Author" msgstr "Autorius:" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3655,6 +3655,12 @@ msgstr "Kelias iki Scenos:" msgid "Import From Node:" msgstr "Importuoti iÅ¡ Nodo:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Ä®vyko klaida kraunant Å¡riftÄ…." + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4554,6 +4560,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Autorius:" @@ -6267,6 +6274,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9693,7 +9701,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9701,7 +9709,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9710,10 +9723,40 @@ msgid "Commit" msgstr "BendruomenÄ—" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "BendruomenÄ—" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Atstatyti PriartinimÄ…" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -9722,7 +9765,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Panaikinti pasirinkimÄ…" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Naujas pavadinimas:" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9731,50 +9804,139 @@ msgid "Detect new changes" msgstr "Sukurti NaujÄ…" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +#, fuzzy +msgid "Stage all changes" +msgstr "Sukurti NaujÄ…" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "Naujas pavadinimas:" +msgid "Commit Message" +msgstr "BendruomenÄ—" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "IÅ¡trinti EfektÄ…" +msgid "Commit List" +msgstr "BendruomenÄ—" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" +msgid "Create New Branch" +msgstr "Sukurti NaujÄ…" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Animacija: panaikinti įrašą" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Panaikinti" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Sukurti NaujÄ…" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" msgstr "Panaikinti pasirinkimÄ…" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +#, fuzzy +msgid "Remote Name" +msgstr "Panaikinti" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Panaikinti" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" +msgid "Pull" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Force Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "Naujas pavadinimas:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "IÅ¡trinti EfektÄ…" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12347,6 +12509,7 @@ msgid "Export list to a CSV file" msgstr "Importuoti iÅ¡ Nodo:" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13205,6 +13368,39 @@ msgstr "" msgid "Edit Member" msgstr "Redaguoti Filtrus" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Animacija" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -13217,6 +13413,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -13233,6 +13503,19 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "(Esama)" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -13242,6 +13525,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -13250,6 +13537,61 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Konstanta" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Konstanta" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Konstanta" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Konstanta" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "TimeSeek Nodas" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Sukurti" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Transition Nodas" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -13259,12 +13601,70 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Konstanta" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Animacija" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Mix Nodas" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Fizikos Kadro %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Signalai" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Signalai" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13840,7 +14240,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14053,7 +14462,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/lv.po b/editor/translations/lv.po index 4bd1bae67d..4d888fb41d 100644 --- a/editor/translations/lv.po +++ b/editor/translations/lv.po @@ -8,13 +8,13 @@ # Anonymous <noreply@weblate.org>, 2020. # StiLins <aigars.skilins@gmail.com>, 2020. # Rihards Kubilis <oldcar@inbox.lv>, 2020. -# M E <gruffy7932@gmail.com>, 2021. +# M E <gruffy7932@gmail.com>, 2021, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-11-29 20:38+0000\n" +"PO-Revision-Date: 2022-01-12 16:52+0000\n" "Last-Translator: M E <gruffy7932@gmail.com>\n" "Language-Team: Latvian <https://hosted.weblate.org/projects/godot-engine/" "godot/lv/>\n" @@ -24,7 +24,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n % 10 == 0 || n % 100 >= 11 && n % 100 <= " "19) ? 0 : ((n % 10 == 1 && n % 100 != 11) ? 1 : 2);\n" -"X-Generator: Weblate 4.10-dev\n" +"X-Generator: Weblate 4.10.1\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -365,6 +365,7 @@ msgstr "Izveidot %d JAUNU celiņu un ievietot atslÄ“gievietni?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -832,6 +833,7 @@ msgstr "Pievienot" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -881,8 +883,7 @@ msgstr "Nevar savienot signÄlu" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1947,7 +1948,6 @@ msgid "New Folder..." msgstr "Jauna mape..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "AtsvaidzinÄt" @@ -2064,7 +2064,8 @@ msgstr "Mapes & Faili:" msgid "Preview:" msgstr "PriekÅ¡katÄ«jums:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Fails:" @@ -2239,7 +2240,7 @@ msgstr "Metode" msgid "Signal" msgstr "SignÄls" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Konstante" @@ -2270,6 +2271,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Likt %s" @@ -2317,7 +2320,7 @@ msgstr "KopÄ“t IzvÄ“lÄ“to" #: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Clear" -msgstr "NotÄ«tÄ«t" +msgstr "NotÄ«rÄ«t" #: editor/editor_log.cpp msgid "Clear Output" @@ -2990,8 +2993,9 @@ msgid "Install Android Build Template..." msgstr "InstalÄ“t Android bÅ«ves Å¡ablonu..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "AtvÄ“rt Projekta Datu Mapi" +#, fuzzy +msgid "Open User Data Folder" +msgstr "AtvÄ“rt redaktora datu mapi" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3136,10 +3140,6 @@ msgid "Toggle Fullscreen" msgstr "PÄrslÄ“gt PilnekrÄnu" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "PÄrslÄ“gt sistÄ“mas konsoli" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "AtvÄ“rt redaktora datu / iestatÄ«jumu mapi" @@ -3364,6 +3364,7 @@ msgid "Load Errors" msgstr "IelÄdÄ“t kļūdas" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "IzvÄ“lÄ“ties" @@ -3440,7 +3441,6 @@ msgid "Author" msgstr "Autors" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Statuss" @@ -3665,6 +3665,12 @@ msgstr "Ainas ceļš:" msgid "Import From Node:" msgstr "ImportÄ“t no mezgla:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Kļūda!" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4376,7 +4382,7 @@ msgstr "" #: editor/import_dock.cpp msgid "Clear Default for '%s'" -msgstr "" +msgstr "NotÄ«rtÄ«t noklusÄ“jumu priekÅ¡ '%s'" #: editor/import_dock.cpp msgid "Reimport" @@ -4524,6 +4530,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Autors:" @@ -5800,7 +5807,7 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Clear Bones" -msgstr "" +msgstr "NotÄ«rÄ«t kaulus" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" @@ -6109,7 +6116,7 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Clear Pose" -msgstr "" +msgstr "NotÄ«rÄ«t pozu" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Add Node Here" @@ -6172,6 +6179,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -7457,7 +7465,7 @@ msgstr "Meklēšanas RezultÄti" #: editor/plugins/script_editor_plugin.cpp msgid "Clear Recent Scripts" -msgstr "" +msgstr "NotÄ«rÄ«t nesenos skriptus" #: editor/plugins/script_text_editor.cpp msgid "Connections to method:" @@ -8460,7 +8468,7 @@ msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Select/Clear All Frames" -msgstr "" +msgstr "IzvÄ“lÄ“ties/notÄ«rÄ«t visus kadrus" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Create Frames from Sprite Sheet" @@ -9462,7 +9470,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9470,7 +9478,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9478,8 +9491,42 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "Ä’notÄja izmaiņas:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Ä’notÄja izmaiņas:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "KomÅ«ns" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" msgstr "" +"Vai esat droÅ¡s(Å¡a), ka vÄ“laties noņemt visus savienojumus no šī signÄla?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Pielietot atiestatīšanu" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9490,7 +9537,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Noņemt Punktu" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "PÄrsaukt" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9498,8 +9575,109 @@ msgid "Detect new changes" msgstr "Atrast jaunas izmaiņas" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Maiņas" +#, fuzzy +msgid "Discard all changes" +msgstr "AizvÄ“rt un saglabÄt izmaiņas?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "SaglabÄ lokÄlÄs izmaiņas..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "SaglabÄ lokÄlÄs izmaiņas..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Pielietot izmaiņas" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "Pielietot izmaiņas" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Pielietot izmaiņas" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "SakritÄ«bas:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Izveidot Jaunu %s" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Noņemt Anim. Celiņu" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Noņemt" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Izveidot Jaunu %s" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Noņemt vienumu" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Mezgla VÄrds:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Noņemt" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9518,27 +9696,20 @@ msgid "Typechange" msgstr "Tipa maiņa" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "Posma izvÄ“le" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Unmerged" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "Pielietot izmaiņas" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "" +#, fuzzy +msgid "View:" +msgstr "SkatÄ«t" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Split" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12051,6 +12222,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12879,6 +13051,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animÄcija" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12891,6 +13096,83 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Sevi" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Pie rakstzÄ«mes %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Likt %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12907,6 +13189,21 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Likt %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funkcijas" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "MainÄ«t MasÄ«va Lielumu" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12916,6 +13213,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12924,6 +13225,63 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "PÄrlÄdÄ“t" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Konstante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Konstante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Konstante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Konstante" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "IzdzÄ“st Mezglu" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Ainas koka rediģēšana" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Sevi" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Izgriezt mezglu(s)" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12933,14 +13291,74 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Izsaukumi" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Konstantes" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "DarbÄ«ba" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" msgstr "" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "NÄkamÄ cilne" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Fizikas kadrs %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "SignÄls" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "SignÄls" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Å ablons" + #: platform/android/export/export_plugin.cpp msgid "Package name is missing." msgstr "" @@ -13500,7 +13918,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13713,7 +14140,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/mi.po b/editor/translations/mi.po index 535251ede2..52b6fecb05 100644 --- a/editor/translations/mi.po +++ b/editor/translations/mi.po @@ -349,6 +349,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -798,6 +799,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -847,8 +849,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1871,7 +1872,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -1988,7 +1988,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2156,7 +2157,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2186,6 +2187,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2879,7 +2882,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3014,10 +3017,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3234,6 +3233,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3310,7 +3310,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3535,6 +3534,11 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +msgid "%s Error" +msgstr "" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4390,6 +4394,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6033,6 +6038,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9315,7 +9321,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9323,7 +9329,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9331,7 +9342,35 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9343,39 +9382,55 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +msgid "Remote Login" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect new changes" +msgid "Username" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Password" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "SSH Public Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +msgid "Select SSH public key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" +msgid "SSH Private Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect new changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +msgid "Stage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Unstage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9383,15 +9438,107 @@ msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Commit List" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Create New Branch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Remove Branch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remotes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remove Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote URL" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -11900,6 +12047,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12728,6 +12876,38 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Condition" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12740,6 +12920,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12756,6 +13010,18 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Function" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12765,6 +13031,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12773,6 +13043,54 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Node" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Tree" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "CustomNode" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12782,12 +13100,64 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Action %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13349,7 +13719,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13562,7 +13941,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/mk.po b/editor/translations/mk.po index e1a6d054c8..8448673f6c 100644 --- a/editor/translations/mk.po +++ b/editor/translations/mk.po @@ -357,6 +357,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -806,6 +807,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -855,8 +857,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1880,7 +1881,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -1997,7 +1997,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2165,7 +2166,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2195,6 +2196,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2891,7 +2894,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3026,10 +3029,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3247,6 +3246,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3323,7 +3323,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3548,6 +3547,11 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +msgid "%s Error" +msgstr "" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4406,6 +4410,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6054,6 +6059,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9338,7 +9344,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9346,7 +9352,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9354,7 +9365,35 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9366,39 +9405,56 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Избриши невалидни клучеви" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Username" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect new changes" +msgid "Password" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "SSH Public Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "Select SSH public key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +msgid "SSH Private Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" +msgid "Select SSH private key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "SSH Passphrase" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect new changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Stage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9406,15 +9462,108 @@ msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Commit List" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Create New Branch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Remove Branch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remotes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Избриши невалидни клучеви" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote URL" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -11923,6 +12072,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12751,6 +12901,38 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Condition" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12763,6 +12945,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12779,6 +13035,18 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Function" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12788,6 +13056,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12796,6 +13068,55 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Node" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "ВнеÑи клуч тука" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "CustomNode" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12805,12 +13126,64 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Action %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13372,7 +13745,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13585,7 +13967,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/ml.po b/editor/translations/ml.po index 50770a8962..b6e14ce0cb 100644 --- a/editor/translations/ml.po +++ b/editor/translations/ml.po @@ -359,6 +359,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -810,6 +811,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -859,8 +861,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1884,7 +1885,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2001,7 +2001,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2170,7 +2171,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2202,6 +2203,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2898,7 +2901,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3033,10 +3036,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3254,6 +3253,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3330,7 +3330,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3555,6 +3554,11 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +msgid "%s Error" +msgstr "" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4411,6 +4415,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6063,6 +6068,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9348,7 +9354,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9356,7 +9362,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9364,7 +9375,35 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9376,39 +9415,55 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +msgid "Remote Login" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect new changes" +msgid "Username" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Password" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "SSH Public Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +msgid "Select SSH public key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" +msgid "SSH Private Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect new changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +msgid "Stage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Unstage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9416,15 +9471,107 @@ msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Commit List" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "10" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Branch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remove Branch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remotes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remove Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote URL" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -11933,6 +12080,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12763,6 +12911,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "ചലനം à´šàµà´±àµà´±àµ½" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12775,6 +12956,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12791,6 +13046,19 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "à´ªàµà´°à´µàµƒà´¤àµà´¤à´¿à´•ൾ:" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12800,6 +13068,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12808,6 +13080,55 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Node" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "സൂചിക ഇവിടെയിടàµà´•" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "CustomNode" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12817,12 +13138,65 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "à´ªàµà´°à´µàµƒà´¤àµà´¤à´¿à´•ൾ:" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13384,7 +13758,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13597,7 +13980,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/mr.po b/editor/translations/mr.po index 6a5005167a..4e1324414e 100644 --- a/editor/translations/mr.po +++ b/editor/translations/mr.po @@ -356,6 +356,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -806,6 +807,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -855,8 +857,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1879,7 +1880,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -1996,7 +1996,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2164,7 +2165,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2195,6 +2196,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2888,7 +2891,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3023,10 +3026,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3244,6 +3243,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3320,7 +3320,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3545,6 +3544,12 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "तà¥à¤°à¥à¤Ÿà¥€!" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4400,6 +4405,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6047,6 +6053,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9333,7 +9340,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9341,7 +9348,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9349,7 +9361,36 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "समà¥à¤¦à¤¾à¤¯" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9361,39 +9402,55 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +msgid "Remote Login" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect new changes" +msgid "Username" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Password" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "SSH Public Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +msgid "Select SSH public key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" +msgid "SSH Private Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect new changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Stage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9401,15 +9458,111 @@ msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +#, fuzzy +msgid "Commit List" +msgstr "समà¥à¤¦à¤¾à¤¯" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "10" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "नवीन अâ€à¥…निमेशन तयार करा" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remove Branch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remotes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "नवीन नोड तयार करा." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "नोड काढला" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote URL" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -11920,6 +12073,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12749,6 +12903,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "अâ€à¥…निमेशन टà¥à¤°à¥€" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12761,6 +12948,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12777,6 +13038,18 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Function" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12786,6 +13059,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12794,6 +13071,55 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "नोड हलवा" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Tree" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "CustomNode" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12803,12 +13129,64 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Action %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13370,7 +13748,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13583,7 +13970,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/ms.po b/editor/translations/ms.po index 4909f7f9b1..7fc1062ff2 100644 --- a/editor/translations/ms.po +++ b/editor/translations/ms.po @@ -8,16 +8,16 @@ # Nafis Ibrahim <thepreciousnafis@gmail.com>, 2018. # Muhammad Hazim bin Hafizalshah <muhammadhazimhafizalshah@gmail.com>, 2020. # keviinx <keviinx@yahoo.com>, 2020. -# Keviindran Ramachandran <keviinx@yahoo.com>, 2020, 2021. +# Keviindran Ramachandran <keviinx@yahoo.com>, 2020, 2021, 2022. # Jacque Fresco <aidter@use.startmail.com>, 2021. -# Lemoney <railkill@gmail.com>, 2021. +# Lemoney <railkill@gmail.com>, 2021, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-10-10 10:18+0000\n" -"Last-Translator: Lemoney <railkill@gmail.com>\n" +"PO-Revision-Date: 2022-01-12 16:52+0000\n" +"Last-Translator: Keviindran Ramachandran <keviinx@yahoo.com>\n" "Language-Team: Malay <https://hosted.weblate.org/projects/godot-engine/godot/" "ms/>\n" "Language: ms\n" @@ -25,7 +25,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.9-dev\n" +"X-Generator: Weblate 4.10.1\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -328,7 +328,7 @@ msgstr "Menduakan Kunci" #: editor/animation_track_editor.cpp msgid "Add RESET Value(s)" -msgstr "" +msgstr "Tambah Nilai-nilai RESET" #: editor/animation_track_editor.cpp msgid "Delete Key(s)" @@ -365,6 +365,7 @@ msgstr "Cipta %d BARU trek dan masukkan kunci?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -499,9 +500,8 @@ msgstr "" "trek." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Add RESET Keys" -msgstr "Kunci Skala Anim" +msgstr "Anim Tambah Kekunci RESET" #: editor/animation_track_editor.cpp msgid "" @@ -832,6 +832,7 @@ msgstr "Tambah" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -883,8 +884,7 @@ msgstr "Tidak dapat menyambungkan isyarat" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1489,7 +1489,7 @@ msgstr "Nama tidak sah." #: editor/editor_autoload_settings.cpp msgid "Cannot begin with a digit." -msgstr "" +msgstr "Tidak boleh bermula dengan digit." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" @@ -1857,9 +1857,8 @@ msgid "Error saving profile to path: '%s'." msgstr "Ralat menyimpan profil ke laluan: '%s'." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Reset to Default" -msgstr "Set Semula ke Lalai" +msgstr "Pulih ke Keadaan Asal" #: editor/editor_feature_profile.cpp msgid "Current Profile:" @@ -1954,7 +1953,6 @@ msgid "New Folder..." msgstr "Folder Baru..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Muat Semula" @@ -2071,7 +2069,8 @@ msgstr "Direktori & Fail:" msgid "Preview:" msgstr "Pratonton:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Fail:" @@ -2121,9 +2120,8 @@ msgid "Properties" msgstr "Sifat-sifat" #: editor/editor_help.cpp -#, fuzzy msgid "overrides %s:" -msgstr "ganti:" +msgstr "ganti %s:" #: editor/editor_help.cpp msgid "default:" @@ -2139,7 +2137,7 @@ msgstr "Sifat Tema" #: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp msgid "Colors" -msgstr "" +msgstr "Warna" #: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp msgid "Constants" @@ -2147,15 +2145,15 @@ msgstr "Pemalar" #: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp msgid "Fonts" -msgstr "" +msgstr "Fon" #: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp msgid "Icons" -msgstr "" +msgstr "Ikon" #: editor/editor_help.cpp msgid "Styles" -msgstr "" +msgstr "Gaya" #: editor/editor_help.cpp msgid "Enumerations" @@ -2246,7 +2244,7 @@ msgstr "Kaedah" msgid "Signal" msgstr "Isyarat" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Pemalar" @@ -2263,20 +2261,22 @@ msgid "Property:" msgstr "Sifat:" #: editor/editor_inspector.cpp -#, fuzzy msgid "Pin value" -msgstr "(nilai)" +msgstr "Nilai pin" #: editor/editor_inspector.cpp msgid "" "Pinning a value forces it to be saved even if it's equal to the default." msgstr "" +"Menyemat nilai memaksanya untuk disimpan walaupun ia sama dengan nilai asal." #: editor/editor_inspector.cpp msgid "Pin value [Disabled because '%s' is editor-only]" -msgstr "" +msgstr "Nilai pin [Dinyahdayakan kerana '%s' adalah editor sahaja]" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Tetapkan %s" @@ -2287,26 +2287,23 @@ msgstr "Tetapkan Pelbagai:" #: editor/editor_inspector.cpp msgid "Pinned %s" -msgstr "" +msgstr "Dipinkan %s" #: editor/editor_inspector.cpp msgid "Unpinned %s" -msgstr "" +msgstr "%s tidak dipinkan" #: editor/editor_inspector.cpp -#, fuzzy msgid "Copy Property" -msgstr "Sifat-sifat" +msgstr "Salin Sifat" #: editor/editor_inspector.cpp -#, fuzzy msgid "Paste Property" -msgstr "Sifat-sifat" +msgstr "Tampal Sifat" #: editor/editor_inspector.cpp -#, fuzzy msgid "Copy Property Path" -msgstr "Sifat-sifat" +msgstr "Salin Laluan Sifat" #: editor/editor_log.cpp msgid "Output:" @@ -2483,9 +2480,8 @@ msgstr "" "warisan) tidak dapat dipenuhi." #: editor/editor_node.cpp -#, fuzzy msgid "Could not save one or more scenes!" -msgstr "Tidak dapat memulakan subproses!" +msgstr "Tidak dapat menyimpan satu atau lebih adegan!" #: editor/editor_node.cpp msgid "Save All Scenes" @@ -2628,20 +2624,23 @@ msgstr "Simpan perubahan pada '%s' sebelum menutup?" #: editor/editor_node.cpp msgid "%s no longer exists! Please specify a new save location." -msgstr "" +msgstr "%s tidak lagi wujud! Sila nyatakan lokasi simpan baru." #: editor/editor_node.cpp msgid "" "The current scene has no root node, but %d modified external resource(s) " "were saved anyway." msgstr "" +"Adegan semasa tidak mempunyai nod akar, tetapi %d sumber luaran yang diubah " +"suai telah disimpan juga." #: editor/editor_node.cpp -#, fuzzy msgid "" "A root node is required to save the scene. You can add a root node using the " "Scene tree dock." -msgstr "Nod akar diperlukan untuk menyimpan adegan." +msgstr "" +"Nod akar diperlukan untuk menyimpan adegan. Anda boleh menambah nod akar " +"menggunakan dok pokok Adegan." #: editor/editor_node.cpp msgid "Save Scene As..." @@ -2673,29 +2672,27 @@ msgstr "Adegan semasa tidak disimpan. Masih buka?" #: editor/editor_node.cpp msgid "Can't undo while mouse buttons are pressed." -msgstr "" +msgstr "Tidak boleh buat asal semasa butang tetikus ditekan." #: editor/editor_node.cpp msgid "Nothing to undo." -msgstr "" +msgstr "Tiada apa yang perlu dibuat asal." #: editor/editor_node.cpp -#, fuzzy msgid "Undo: %s" -msgstr "Buat Asal" +msgstr "Buat asal: %s" #: editor/editor_node.cpp msgid "Can't redo while mouse buttons are pressed." -msgstr "" +msgstr "Tidak boleh buat semula semasa butang tetikus ditekan." #: editor/editor_node.cpp msgid "Nothing to redo." -msgstr "" +msgstr "Tiada apa yang perlu dibuat semula." #: editor/editor_node.cpp -#, fuzzy msgid "Redo: %s" -msgstr "Buat Semula" +msgstr "Buat semula: %s" #: editor/editor_node.cpp msgid "Can't reload a scene that was never saved." @@ -3035,8 +3032,9 @@ msgid "Install Android Build Template..." msgstr "Pasang Templat Binaan Android..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Buka Folder Data Projek" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Buka Folder Data Editor" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3126,7 +3124,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Force Shader Fallbacks" -msgstr "" +msgstr "Paksa Shader Fallbacks" #: editor/editor_node.cpp msgid "" @@ -3137,6 +3135,13 @@ msgid "" "Asynchronous shader compilation must be enabled in the project settings for " "this option to make a difference." msgstr "" +"Apabila pilihan ini didayakan, shader akan digunakan dalam bentuk fallback " +"mereka (sama ada boleh dilihat melalui ubershader atau tersembunyi) " +"sepanjang masa berjalan.\n" +"Ini berguna untuk mengesahkan rup dan prestasi fallback, yang biasanya " +"diaparkan secara ringkas.\n" +"Kompilasi shader tak segerak mesti didayakan dalam tetapan projek untuk " +"pilihan ini membuat perubahan." #: editor/editor_node.cpp msgid "Synchronize Scene Changes" @@ -3195,10 +3200,6 @@ msgid "Toggle Fullscreen" msgstr "Togol Skrin Penuh" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Togol Konsol Sistem" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Buka Folder Data/Tetapan Editor" @@ -3223,13 +3224,12 @@ msgid "Help" msgstr "Bantuan" #: editor/editor_node.cpp -#, fuzzy msgid "Online Documentation" -msgstr "Dokumen Dalam Talian" +msgstr "Dokumentasi Dalam Talian" #: editor/editor_node.cpp msgid "Questions & Answers" -msgstr "" +msgstr "Soalan & Jawapan" #: editor/editor_node.cpp msgid "Report a Bug" @@ -3237,7 +3237,7 @@ msgstr "Laporkan Pepijat" #: editor/editor_node.cpp msgid "Suggest a Feature" -msgstr "" +msgstr "Cadangkan Ciri" #: editor/editor_node.cpp msgid "Send Docs Feedback" @@ -3248,9 +3248,8 @@ msgid "Community" msgstr "Komuniti" #: editor/editor_node.cpp -#, fuzzy msgid "About Godot" -msgstr "Tentang" +msgstr "Tentang Godot" #: editor/editor_node.cpp msgid "Support Godot Development" @@ -3342,13 +3341,12 @@ msgid "Manage Templates" msgstr "Urus Templat-templat" #: editor/editor_node.cpp -#, fuzzy msgid "Install from file" -msgstr "Pasang Dari Fail" +msgstr "Pasang dari fail" #: editor/editor_node.cpp msgid "Select android sources file" -msgstr "" +msgstr "Pilih fail sumber android" #: editor/editor_node.cpp msgid "" @@ -3398,9 +3396,8 @@ msgid "Merge With Existing" msgstr "Gabung Dengan Sedia Ada" #: editor/editor_node.cpp -#, fuzzy msgid "Apply MeshInstance Transforms" -msgstr "Anim Ubah Perubahan" +msgstr "Gunakan MeshInstance Transforms" #: editor/editor_node.cpp msgid "Open & Run a Script" @@ -3433,13 +3430,13 @@ msgid "Load Errors" msgstr "Muatkan Ralat-ralat" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Pilih" #: editor/editor_node.cpp -#, fuzzy msgid "Select Current" -msgstr "Pilih Folder Semasa" +msgstr "Pilih Semasa" #: editor/editor_node.cpp msgid "Open 2D Editor" @@ -3474,9 +3471,8 @@ msgid "No sub-resources found." msgstr "Tiada sub-sumber dijumpai." #: editor/editor_path.cpp -#, fuzzy msgid "Open a list of sub-resources." -msgstr "Tiada sub-sumber dijumpai." +msgstr "Buka senarai sub-sumber." #: editor/editor_plugin.cpp msgid "Creating Mesh Previews" @@ -3507,29 +3503,25 @@ msgid "Version" msgstr "Versi" #: editor/editor_plugin_settings.cpp -#, fuzzy msgid "Author" msgstr "Pengarang" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" -msgstr "" +msgstr "Status" #: editor/editor_profiler.cpp msgid "Measure:" msgstr "Ukur:" #: editor/editor_profiler.cpp -#, fuzzy msgid "Frame Time (ms)" -msgstr "Masa Bingkai (saat)" +msgstr "Masa Bingkai (ms)" #: editor/editor_profiler.cpp -#, fuzzy msgid "Average Time (ms)" -msgstr "Masa Purata (saat)" +msgstr "Masa Purata (ms)" #: editor/editor_profiler.cpp msgid "Frame %" @@ -3556,6 +3548,13 @@ msgid "" "functions called by that function.\n" "Use this to find individual functions to optimize." msgstr "" +"Inklusif: Termasuk masa daripada fungsi lain yang dipanggil oleh fungsi " +"ini.\n" +"Gunakan ini untuk mengesan kesesakan.\n" +"\n" +"Diri: Hanya kira masa yang dihabiskan dalam fungsi itu sendiri, bukan dalam " +"fungsi lain yang dipanggil oleh fungsi itu.\n" +"Gunakan ini untuk mencari fungsi individu untuk dioptimumkan." #: editor/editor_profiler.cpp msgid "Frame #:" @@ -3661,7 +3660,7 @@ msgstr "" #: editor/editor_resource_picker.cpp msgid "Quick Load" -msgstr "" +msgstr "Muatan Cepat" #: editor/editor_resource_picker.cpp editor/property_editor.cpp msgid "Make Unique" @@ -3682,9 +3681,8 @@ msgid "Paste" msgstr "Tampal" #: editor/editor_resource_picker.cpp editor/property_editor.cpp -#, fuzzy msgid "Convert to %s" -msgstr "Tukar Kepada %s" +msgstr "Tukar ke %s" #: editor/editor_resource_picker.cpp editor/property_editor.cpp msgid "New %s" @@ -3733,10 +3731,9 @@ msgid "Did you forget the '_run' method?" msgstr "Adakah anda lupa kaedah '_run'?" #: editor/editor_spin_slider.cpp -#, fuzzy msgid "Hold %s to round to integers. Hold Shift for more precise changes." msgstr "" -"Tahan Ctrl untuk bundarkan ke integer. Tahan Shift untuk perubahan yang " +"Tahan %s untuk membundarkan ke integer. Tahan Shift untuk perubahan yang " "lebih tepat." #: editor/editor_sub_scene.cpp @@ -3755,67 +3752,68 @@ msgstr "Laluan Adegan:" msgid "Import From Node:" msgstr "Import Dari Nod:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Ralat!" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." -msgstr "" +msgstr "Buka folder yang mengandungi templat ini." #: editor/export_template_manager.cpp msgid "Uninstall these templates." -msgstr "" +msgstr "Nyahpasang templat ini." #: editor/export_template_manager.cpp -#, fuzzy msgid "There are no mirrors available." -msgstr "Tiada fail '%s'." +msgstr "Tiada mirror tersedia." #: editor/export_template_manager.cpp -#, fuzzy msgid "Retrieving the mirror list..." -msgstr "Mengambil maklumat cermin, sila tunggu..." +msgstr "Mendapatkan semula senarai mirror..." #: editor/export_template_manager.cpp msgid "Starting the download..." -msgstr "" +msgstr "Memulakan muat turun..." #: editor/export_template_manager.cpp msgid "Error requesting URL:" msgstr "Ralat semasa meminta URL:" #: editor/export_template_manager.cpp -#, fuzzy msgid "Connecting to the mirror..." -msgstr "Menyambung ke Cermin..." +msgstr "Menyambung ke mirror..." #: editor/export_template_manager.cpp msgid "Can't resolve the requested address." -msgstr "" +msgstr "Tidak dapat menyelesaikan alamat yang diminta." #: editor/export_template_manager.cpp msgid "Can't connect to the mirror." msgstr "Tidak dapat menyambung ke tapak web." #: editor/export_template_manager.cpp -#, fuzzy msgid "No response from the mirror." -msgstr "Tiada jawapan." +msgstr "Tiada jawapan dari mirror." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request failed." -msgstr "" +msgstr "Permintaan gagal." #: editor/export_template_manager.cpp msgid "Request ended up in a redirect loop." -msgstr "" +msgstr "Permintaan berakhir dalam loop pengalihan." #: editor/export_template_manager.cpp -#, fuzzy msgid "Request failed:" -msgstr "Permintaan Gagal." +msgstr "Permintaan gagal:" #: editor/export_template_manager.cpp msgid "Download complete; extracting templates..." -msgstr "" +msgstr "Muat turun selesai; mengekstrak templat..." #: editor/export_template_manager.cpp msgid "Cannot remove temporary file:" @@ -3834,13 +3832,12 @@ msgid "Error getting the list of mirrors." msgstr "Ralat mendapatkan senarai cermin-cermin." #: editor/export_template_manager.cpp -#, fuzzy msgid "Error parsing JSON with the list of mirrors. Please report this issue!" -msgstr "Ralat menghuraikan JSON senarai cermin. Sila laporkan isu ini!" +msgstr "Ralat menghuraikan JSON dengan senarai mirror. Sila laporkan isu ini!" #: editor/export_template_manager.cpp msgid "Best available mirror" -msgstr "" +msgstr "Mirror terbaik yang tersedia" #: editor/export_template_manager.cpp msgid "" @@ -3893,24 +3890,20 @@ msgid "SSL Handshake Error" msgstr "Ralat Jabat Tangan SSL" #: editor/export_template_manager.cpp -#, fuzzy msgid "Can't open the export templates file." -msgstr "Tidak dapat membuka zip templat eksport." +msgstr "Tidak dapat membuka fail templat eksport." #: editor/export_template_manager.cpp -#, fuzzy msgid "Invalid version.txt format inside the export templates file: %s." -msgstr "Format version.txt tidak sah di dalam templat: %s." +msgstr "Format version.txt tidak sah di dalam fail templat eksport: %s." #: editor/export_template_manager.cpp -#, fuzzy msgid "No version.txt found inside the export templates file." -msgstr "Tiada version.txt dijumpai di dalam templat." +msgstr "Tiada version.txt dijumpai di dalam fail templat eksport." #: editor/export_template_manager.cpp -#, fuzzy msgid "Error creating path for extracting templates:" -msgstr "Ralat mencipta laluan untuk templat-templat:" +msgstr "Ralat mencipta laluan untuk mengekstrak templat:" #: editor/export_template_manager.cpp msgid "Extracting Export Templates" @@ -3921,9 +3914,8 @@ msgid "Importing:" msgstr "Mengimport:" #: editor/export_template_manager.cpp -#, fuzzy msgid "Remove templates for the version '%s'?" -msgstr "Alih keluar versi templat '%s'?" +msgstr "Alih keluar templat versi '%s'?" #: editor/export_template_manager.cpp msgid "Uncompressing Android Build Sources" @@ -3939,20 +3931,19 @@ msgstr "Versi Terkini:" #: editor/export_template_manager.cpp msgid "Export templates are missing. Download them or install from a file." -msgstr "" +msgstr "Templat eksport tiada. Muat turun atau pasang dari fail." #: editor/export_template_manager.cpp msgid "Export templates are installed and ready to be used." -msgstr "" +msgstr "Templat eksport dipasang dan sedia untuk digunakan." #: editor/export_template_manager.cpp -#, fuzzy msgid "Open Folder" -msgstr "Buka Fail" +msgstr "Buka Folder" #: editor/export_template_manager.cpp msgid "Open the folder containing installed templates for the current version." -msgstr "" +msgstr "Buka folder yang mengandungi templat yang dipasang untuk versi semasa." #: editor/export_template_manager.cpp msgid "Uninstall" @@ -3960,45 +3951,41 @@ msgstr "Nyahpasang" #: editor/export_template_manager.cpp msgid "Uninstall templates for the current version." -msgstr "" +msgstr "Nyahpasang templat untuk versi semasa." #: editor/export_template_manager.cpp -#, fuzzy msgid "Download from:" -msgstr "Muat turun" +msgstr "Muat turun dari:" #: editor/export_template_manager.cpp -#, fuzzy msgid "Open in Web Browser" -msgstr "Buka dalam Pengurus Fail" +msgstr "Buka dalam Pelayar Web" #: editor/export_template_manager.cpp msgid "Copy Mirror URL" -msgstr "" +msgstr "Salin URL Mirror" #: editor/export_template_manager.cpp msgid "Download and Install" -msgstr "" +msgstr "Muat Turun dan Pasang" #: editor/export_template_manager.cpp msgid "" "Download and install templates for the current version from the best " "possible mirror." -msgstr "" +msgstr "Muat turun dan pasang templat untuk versi semasa dari mirror terbaik." #: editor/export_template_manager.cpp msgid "Official export templates aren't available for development builds." msgstr "Templat eksport rasmi tidak tersedia untuk binaan pembangunan." #: editor/export_template_manager.cpp -#, fuzzy msgid "Install from File" -msgstr "Pasang Dari Fail" +msgstr "Pasang dari Fail" #: editor/export_template_manager.cpp -#, fuzzy msgid "Install templates from a local file." -msgstr "Import Templat Dari Fail ZIP" +msgstr "Pasang templat dari fail tempatan." #: editor/export_template_manager.cpp editor/find_in_files.cpp #: editor/progress_dialog.cpp scene/gui/dialogs.cpp @@ -4006,19 +3993,16 @@ msgid "Cancel" msgstr "Batal" #: editor/export_template_manager.cpp -#, fuzzy msgid "Cancel the download of the templates." -msgstr "Tidak dapat membuka zip templat eksport." +msgstr "Batalkan muat turun templat." #: editor/export_template_manager.cpp -#, fuzzy msgid "Other Installed Versions:" -msgstr "Versi-versi Yang Dipasang:" +msgstr "Versi Terpasang Lain:" #: editor/export_template_manager.cpp -#, fuzzy msgid "Uninstall Template" -msgstr "Nyahpasang" +msgstr "Nyahpasang Templat" #: editor/export_template_manager.cpp msgid "Select Template File" @@ -4033,6 +4017,8 @@ msgid "" "The templates will continue to download.\n" "You may experience a short editor freeze when they finish." msgstr "" +"Templat akan terus dimuat turun.\n" +"Anda mungkin mengalami pembekuan editor pendek apabila ia selesai." #: editor/filesystem_dock.cpp msgid "Favorites" @@ -4180,33 +4166,32 @@ msgid "Collapse All" msgstr "Runtuhkan Semua" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Sort files" -msgstr "Cari fail" +msgstr "Susun fail-fail" #: editor/filesystem_dock.cpp msgid "Sort by Name (Ascending)" -msgstr "" +msgstr "Susun mengikut Nama (Menaik)" #: editor/filesystem_dock.cpp msgid "Sort by Name (Descending)" -msgstr "" +msgstr "Susun mengikut Nama (Menurun)" #: editor/filesystem_dock.cpp msgid "Sort by Type (Ascending)" -msgstr "" +msgstr "Susun mengikut Jenis (Menaik)" #: editor/filesystem_dock.cpp msgid "Sort by Type (Descending)" -msgstr "" +msgstr "Susun mengikut Jenis (Menurun)" #: editor/filesystem_dock.cpp msgid "Sort by Last Modified" -msgstr "" +msgstr "Susun mengikut Terakhir Diubah Suai" #: editor/filesystem_dock.cpp msgid "Sort by First Modified" -msgstr "" +msgstr "Susun mengikut Pertama Diubah Suai" #: editor/filesystem_dock.cpp msgid "Duplicate..." @@ -4218,7 +4203,7 @@ msgstr "Namakan semula..." #: editor/filesystem_dock.cpp msgid "Focus the search box" -msgstr "" +msgstr "Fokuskan kotak carian" #: editor/filesystem_dock.cpp msgid "Previous Folder/File" @@ -4309,9 +4294,8 @@ msgid "Replace..." msgstr "Ganti..." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Replace in Files" -msgstr "Ganti Semua" +msgstr "Gantikan dalam Fail-fail" #: editor/find_in_files.cpp msgid "Find: " @@ -4322,9 +4306,8 @@ msgid "Replace: " msgstr "Ganti: " #: editor/find_in_files.cpp -#, fuzzy msgid "Replace All (NO UNDO)" -msgstr "Ganti Semua" +msgstr "Gantikan Semua (TIADA BUAT ASAL)" #: editor/find_in_files.cpp msgid "Searching..." @@ -4517,6 +4500,10 @@ msgid "" "Selecting another resource in the FileSystem dock without clicking Reimport " "first will discard changes made in the Import dock." msgstr "" +"Anda mempunyai perubahan belum selesai yang belum digunakan lagi.Klik Import " +"Semula untuk menggunakan perubahan yang dibuat pada pilihan import.\n" +"Memilih sumber lain dalam dok FileSystem tampa mengklik Import Semula " +"terlebih dahulu akan membuang perubahan yang dibuat dalam dok Import." #: editor/import_dock.cpp msgid "Import As:" @@ -4546,20 +4533,20 @@ msgid "" "Select a resource file in the filesystem or in the inspector to adjust " "import settings." msgstr "" +"Pilih fail sumber dalam sistem fail atau dalam pemeriksa untuk melaraskan " +"tetapan import." #: editor/inspector_dock.cpp msgid "Failed to load resource." msgstr "Gagal untuk memuatkan sumber." #: editor/inspector_dock.cpp -#, fuzzy msgid "Copy Properties" -msgstr "Sifat-sifat" +msgstr "Salin Sifat-sifat" #: editor/inspector_dock.cpp -#, fuzzy msgid "Paste Properties" -msgstr "Sifat-sifat" +msgstr "Tampal Sifat-sifat" #: editor/inspector_dock.cpp msgid "Make Sub-Resources Unique" @@ -4585,21 +4572,19 @@ msgstr "Simpan Sebagai..." #: editor/inspector_dock.cpp msgid "Extra resource options." -msgstr "" +msgstr "Pilihan sumber tambahan." #: editor/inspector_dock.cpp -#, fuzzy msgid "Edit Resource from Clipboard" -msgstr "Sunting Papan Klip Sumber" +msgstr "Edit Sumber dari Papan Klip" #: editor/inspector_dock.cpp msgid "Copy Resource" msgstr "Salin Sumber" #: editor/inspector_dock.cpp -#, fuzzy msgid "Make Resource Built-In" -msgstr "Buat Terbina Dalaman" +msgstr "Buat Sumber Terbina Dalam" #: editor/inspector_dock.cpp msgid "Go to the previous edited object in history." @@ -4615,20 +4600,19 @@ msgstr "Sejarah objek-objek yang baru disunting." #: editor/inspector_dock.cpp msgid "Open documentation for this object." -msgstr "" +msgstr "Buka dokumentasi untuk objek ini." #: editor/inspector_dock.cpp editor/scene_tree_dock.cpp msgid "Open Documentation" -msgstr "" +msgstr "Buka Dokumentasi" #: editor/inspector_dock.cpp msgid "Filter properties" msgstr "Tapis sifat-sifat" #: editor/inspector_dock.cpp -#, fuzzy msgid "Manage object properties." -msgstr "Sifat-sifat objek." +msgstr "Urus sifat objek." #: editor/inspector_dock.cpp msgid "Changes may be lost!" @@ -4659,6 +4643,7 @@ msgid "Subfolder:" msgstr "Subfolder:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Pengarang:" @@ -4843,7 +4828,6 @@ msgid "Remove BlendSpace2D Triangle" msgstr "Keluarkan Segi tiga BlendSpace2D" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "BlendSpace2D does not belong to an AnimationTree node." msgstr "BlendSpace2D bukan milik nod AnimationTree." @@ -4874,9 +4858,8 @@ msgid "Blend:" msgstr "Adun:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Parameter Changed:" -msgstr "Parameter Berubah" +msgstr "Parameter Berubah:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp @@ -4885,29 +4868,31 @@ msgstr "Sunting Filters" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Output node can't be added to the blend tree." -msgstr "" +msgstr "Nod keluaran tidak boleh ditambah ke pokok adunan." #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Add Node to BlendTree" -msgstr "" +msgstr "Tambah Nod ke BlendTree" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Node Moved" -msgstr "" +msgstr "Nod Dialihkan" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Unable to connect, port may be in use or connection may be invalid." msgstr "" +"Tidak dapat menyambung, port mungkin sedang digunakan atau sambungan mungkin " +"tidak sah." #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Nodes Connected" -msgstr "" +msgstr "Nod Bersambung" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Nodes Disconnected" -msgstr "" +msgstr "Nod Diputuskan" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Set Animation" @@ -4915,30 +4900,32 @@ msgstr "Tetapkan Animasi" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Delete Node" -msgstr "Semua Pilihan" +msgstr "Padam Nod" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" -msgstr "" +msgstr "Padam Nod(-nod)" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Toggle Filter On/Off" -msgstr "" +msgstr "Togol Filter Hidup/Mati" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Change Filter" -msgstr "" +msgstr "Tukar Filter" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "No animation player set, so unable to retrieve track names." msgstr "" +"Tiada pemain animasi ditetapkan, jadi tidak dapat memperolehi semula nama " +"trek." #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Player path set is invalid, so unable to retrieve track names." msgstr "" +"Set laluan pemain tidak sah, jadi tidak dapat mendapatkan semula nama trek." #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/root_motion_editor_plugin.cpp @@ -4946,15 +4933,16 @@ msgid "" "Animation player has no valid root node path, so unable to retrieve track " "names." msgstr "" +"Pemain animasi tidak mempunyai laluan nod akar yang sah, jadi tidak dapat " +"mendapatkan semula nama trek." #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Anim Clips" -msgstr "" +msgstr "Klip Anim" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Audio Clips" -msgstr "Anim Tambah Trek" +msgstr "Klip Audio" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Functions" @@ -4963,132 +4951,132 @@ msgstr "Fungsi" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_state_machine_editor.cpp msgid "Node Renamed" -msgstr "" +msgstr "Nod Diubah Nama" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add Node..." -msgstr "" +msgstr "Tambah Nod..." #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/root_motion_editor_plugin.cpp msgid "Edit Filtered Tracks:" -msgstr "" +msgstr "Edit Trek Difilter:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Enable Filtering" -msgstr "" +msgstr "Dayakan Penapisan" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Toggle Autoplay" -msgstr "" +msgstr "Togol Automain" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Animation Name:" -msgstr "" +msgstr "Nama Animasi Baru:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Anim" -msgstr "" +msgstr "Anim Baru" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Change Animation Name:" -msgstr "" +msgstr "Tukar Nama Animasi:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Delete Animation?" -msgstr "" +msgstr "Padam Animasi?" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Remove Animation" -msgstr "" +msgstr "Alih Keluar Animasi" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Invalid animation name!" -msgstr "" +msgstr "Nama animasi tidak sah!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation name already exists!" -msgstr "" +msgstr "Nama animasi sudah wujud!" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Rename Animation" -msgstr "" +msgstr "Namakan Semula Animasi" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Next Changed" -msgstr "" +msgstr "Adun Berubah Seterusnya" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Change Blend Time" -msgstr "" +msgstr "Tukar Masa Blend" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Load Animation" -msgstr "" +msgstr "Muatkan Animasi" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Duplicate Animation" -msgstr "" +msgstr "Gandakan Animasi" #: editor/plugins/animation_player_editor_plugin.cpp msgid "No animation to copy!" -msgstr "" +msgstr "Tiada animasi untuk disalin!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "No animation resource on clipboard!" -msgstr "" +msgstr "Tiada sumber animasi pada papan klip!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Pasted Animation" -msgstr "" +msgstr "Animasi Ditampal" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Paste Animation" -msgstr "" +msgstr "Tampal Animasi" #: editor/plugins/animation_player_editor_plugin.cpp msgid "No animation to edit!" -msgstr "" +msgstr "Tiada animasi untuk disunting!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from current pos. (A)" -msgstr "" +msgstr "Mainkan animasi terpilih ke belakang dari pos semasa. (A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from end. (Shift+A)" -msgstr "" +msgstr "Mainkan animasi terpillih ke belakang dari hujung. (Shift+A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Stop animation playback. (S)" -msgstr "" +msgstr "Hentikan playback animasi. (S)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from start. (Shift+D)" -msgstr "" +msgstr "Mainkan animasi terpilih dari awal. (Shift+D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from current pos. (D)" -msgstr "" +msgstr "Mainkan animasi terpilih dar pos semasa. (D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation position (in seconds)." -msgstr "" +msgstr "Kedudukan animasi (dalam saat)." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Scale animation playback globally for the node." -msgstr "" +msgstr "Skala main balik animasi secara global untuk nod." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Tools" -msgstr "" +msgstr "Alat Animasi" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation" -msgstr "" +msgstr "Animasi" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/version_control_editor_plugin.cpp @@ -5101,39 +5089,39 @@ msgstr "Sunting Peralihan..." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Open in Inspector" -msgstr "" +msgstr "Buka dalam Inspektor" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Display list of animations in player." -msgstr "" +msgstr "Paparkan senarai animasi dalam pemain." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Autoplay on Load" -msgstr "" +msgstr "Automain semasa Muatkan" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Enable Onion Skinning" -msgstr "" +msgstr "Aktifkan Kulit Bawang" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Onion Skinning Options" -msgstr "" +msgstr "Pilihan Kulit Bawang" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" -msgstr "" +msgstr "Arah" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Past" -msgstr "" +msgstr "Sebelum" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Future" -msgstr "" +msgstr "Masa depan" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Depth" -msgstr "" +msgstr "Kedalaman" #: editor/plugins/animation_player_editor_plugin.cpp msgid "1 step" @@ -5149,50 +5137,50 @@ msgstr "3 langkah" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Differences Only" -msgstr "" +msgstr "Perbezaan Sahaja" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Force White Modulate" -msgstr "" +msgstr "Paksa Modulasi Putih" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Include Gizmos (3D)" -msgstr "" +msgstr "Sertakan Gizmos (3D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Pin AnimationPlayer" -msgstr "" +msgstr "Pin AnimationPlayer" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create New Animation" -msgstr "" +msgstr "Cipta Animasi Baru" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Name:" -msgstr "" +msgstr "Nama Animasi:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp msgid "Error!" -msgstr "" +msgstr "Ralat!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Times:" -msgstr "" +msgstr "Masa Adunan:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Next (Auto Queue):" -msgstr "" +msgstr "Seterusnya (Baris Gilir Automatik):" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Cross-Animation Blend Times" -msgstr "" +msgstr "Masa Adunan Animasi Silang" #: editor/plugins/animation_state_machine_editor.cpp msgid "Move Node" -msgstr "" +msgstr "Pindahkan Nod" #: editor/plugins/animation_state_machine_editor.cpp msgid "Transition exists!" @@ -5205,39 +5193,39 @@ msgstr "Tambah Peralihan" #: editor/plugins/animation_state_machine_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Add Node" -msgstr "" +msgstr "Tambah Nod" #: editor/plugins/animation_state_machine_editor.cpp msgid "End" -msgstr "" +msgstr "Akhir" #: editor/plugins/animation_state_machine_editor.cpp msgid "Immediate" -msgstr "" +msgstr "Segera" #: editor/plugins/animation_state_machine_editor.cpp msgid "Sync" -msgstr "" +msgstr "Segerak" #: editor/plugins/animation_state_machine_editor.cpp msgid "At End" -msgstr "" +msgstr "Pada Akhir" #: editor/plugins/animation_state_machine_editor.cpp msgid "Travel" -msgstr "" +msgstr "Perjalanan" #: editor/plugins/animation_state_machine_editor.cpp msgid "Start and end nodes are needed for a sub-transition." -msgstr "" +msgstr "Nod mula dan tamat diperlukan untuk sub-peralihan." #: editor/plugins/animation_state_machine_editor.cpp msgid "No playback resource set at path: %s." -msgstr "" +msgstr "Tiada sumber main balik ditetapkan pada laluan: %s." #: editor/plugins/animation_state_machine_editor.cpp msgid "Node Removed" -msgstr "" +msgstr "Nod Dikeluarkan" #: editor/plugins/animation_state_machine_editor.cpp msgid "Transition Removed" @@ -5245,7 +5233,7 @@ msgstr "Peralihan Dikeluarkan" #: editor/plugins/animation_state_machine_editor.cpp msgid "Set Start Node (Autoplay)" -msgstr "" +msgstr "Tetapkan Nod Mula (Automain)" #: editor/plugins/animation_state_machine_editor.cpp msgid "" @@ -5253,26 +5241,30 @@ msgid "" "RMB to add new nodes.\n" "Shift+LMB to create connections." msgstr "" +"Pilih dan pindah nod.\n" +"RMB untuk menambah nod baru.\n" +"Shift+LMB untuk membuat sambungan." #: editor/plugins/animation_state_machine_editor.cpp msgid "Create new nodes." -msgstr "" +msgstr "Cipta nod baru." #: editor/plugins/animation_state_machine_editor.cpp msgid "Connect nodes." -msgstr "" +msgstr "Hubungkan nod-nod." #: editor/plugins/animation_state_machine_editor.cpp msgid "Remove selected node or transition." -msgstr "" +msgstr "Alih keluar nod atau peralihan yang dipilih." #: editor/plugins/animation_state_machine_editor.cpp msgid "Toggle autoplay this animation on start, restart or seek to zero." msgstr "" +"Togol automain animasi ini semasa mula, mulakan semula atau cari ke sifar." #: editor/plugins/animation_state_machine_editor.cpp msgid "Set the end animation. This is useful for sub-transitions." -msgstr "" +msgstr "Tetapkan hujung animasi. Ini adalah berguna untuk sub-peralihan." #: editor/plugins/animation_state_machine_editor.cpp msgid "Transition: " @@ -5280,7 +5272,7 @@ msgstr "Peralihan: " #: editor/plugins/animation_state_machine_editor.cpp msgid "Play Mode:" -msgstr "" +msgstr "Mod Main:" #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp @@ -5289,115 +5281,115 @@ msgstr "AnimationTree" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "New name:" -msgstr "" +msgstr "Nama baru:" #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/multimesh_editor_plugin.cpp msgid "Scale:" -msgstr "" +msgstr "Skala:" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Fade In (s):" -msgstr "" +msgstr "Pudar Masuk (s):" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Fade Out (s):" -msgstr "" +msgstr "Pudar Keluar (s):" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Blend" -msgstr "" +msgstr "Adun" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Mix" -msgstr "" +msgstr "Campur" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Auto Restart:" -msgstr "" +msgstr "Mula Semula Auto:" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Restart (s):" -msgstr "" +msgstr "Mula Semula (s):" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Random Restart (s):" -msgstr "" +msgstr "Mula Semula Rawak (s):" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Start!" -msgstr "" +msgstr "Mula!" #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/multimesh_editor_plugin.cpp msgid "Amount:" -msgstr "" +msgstr "Jumlah:" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Blend 0:" -msgstr "" +msgstr "Adun 0:" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Blend 1:" -msgstr "" +msgstr "Adun 1:" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "X-Fade Time (s):" -msgstr "" +msgstr "Masa X-Fade (s):" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Current:" -msgstr "" +msgstr "Semasa:" #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Add Input" -msgstr "" +msgstr "Tambah Input" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Clear Auto-Advance" -msgstr "" +msgstr "Kosongkan Auto-Advance" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Set Auto-Advance" -msgstr "" +msgstr "Tetapkan Auto-Advance" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Delete Input" -msgstr "" +msgstr "Padam Input" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Animation tree is valid." -msgstr "" +msgstr "Pokok animasi sah." #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Animation tree is invalid." -msgstr "" +msgstr "Pokok animasi tidak sah." #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Animation Node" -msgstr "" +msgstr "Nod Animasi" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "OneShot Node" -msgstr "" +msgstr "Nod OneShot" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Mix Node" -msgstr "" +msgstr "Campur Nod" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Blend2 Node" -msgstr "" +msgstr "Nod Blend2" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Blend3 Node" -msgstr "" +msgstr "Nod Blend3" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Blend4 Node" -msgstr "" +msgstr "Nod Blend4" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "TimeScale Node" @@ -6336,6 +6328,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9700,7 +9693,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9708,19 +9701,59 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy +msgid "No commit message was provided." +msgstr "Tidak ada nama yang diberikan." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy msgid "Commit" msgstr "Komuniti" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "Parameter Berubah" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Parameter Berubah" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Komuniti" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "" +"Adakah anda pasti anda mahu mengeluarkan semua sambungan dari isyarat ini?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Guna Set Semula" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -9729,7 +9762,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Buang Trek Anim" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Namakan Semula" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9737,50 +9800,143 @@ msgid "Detect new changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +#, fuzzy +msgid "Discard all changes" +msgstr "Parameter Berubah" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Menyimpan perubahan tempatan..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Parameter Berubah" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Komuniti" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +#, fuzzy +msgid "Commit List" +msgstr "Komuniti" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "Ubah Nama Trek Anim" +msgid "Branches" +msgstr "Padanan:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "Semua Pilihan" +msgid "Create New Branch" +msgstr "Cipta %s Baru" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +#, fuzzy +msgid "Remove Branch" +msgstr "Keluarkan Trek Anim" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "Semua Pilihan" +msgid "Remotes" +msgstr "Keluarkan" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Cipta %s Baru" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Keluarkan Item" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +#, fuzzy +msgid "Remote Name" +msgstr "Nama Nod:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Keluarkan" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" +msgid "Pull" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Force Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "Ubah Nama Trek Anim" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "Semua Pilihan" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "View:" +msgstr "Pratonton:" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12308,6 +12464,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13151,6 +13308,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animasi" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -13163,6 +13353,84 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Menamakan semula folder:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Diri" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Tetapkan %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Dipinkan %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -13179,6 +13447,21 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Tetapkan %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Fungsi" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Ubah saiz Array" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -13188,6 +13471,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -13196,6 +13483,63 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Muatkan Semula" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Pemalar" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Pemalar" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Pemalar" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Pemalar" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Padam Nod" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Penyuntingan Pokok Adegan" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Diri" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Potong Nod" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -13205,14 +13549,74 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Panggilan" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Pemalar" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Aksi" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" msgstr "" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Tab seterusnya" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Bingkai Fizik %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Isyarat" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Isyarat" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Contoh" + #: platform/android/export/export_plugin.cpp msgid "Package name is missing." msgstr "" @@ -13789,7 +14193,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14002,7 +14415,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/nb.po b/editor/translations/nb.po index 2aab12820b..0849aa8c03 100644 --- a/editor/translations/nb.po +++ b/editor/translations/nb.po @@ -20,13 +20,14 @@ # Lili Zoey <sayaks1@gmail.com>, 2021. # slasken06 <ask.skivdal@gmail.com>, 2021. # Daniel Skogly <daniel@klungo.no>, 2021. +# Imre Kristoffer Eilertsen <imreeil42@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-12-26 17:18+0000\n" -"Last-Translator: Petter Reinholdtsen <pere-weblate@hungry.com>\n" +"PO-Revision-Date: 2022-01-12 16:52+0000\n" +"Last-Translator: Imre Kristoffer Eilertsen <imreeil42@gmail.com>\n" "Language-Team: Norwegian BokmÃ¥l <https://hosted.weblate.org/projects/godot-" "engine/godot/nb_NO/>\n" "Language: nb\n" @@ -109,7 +110,7 @@ msgstr "EiB" #: editor/animation_bezier_editor.cpp msgid "Free" -msgstr "Frigjør" +msgstr "Fri" #: editor/animation_bezier_editor.cpp msgid "Balanced" @@ -300,7 +301,7 @@ msgstr "Diskret" #: editor/animation_track_editor.cpp msgid "Trigger" -msgstr "Avtrekker" +msgstr "Utløser" #: editor/animation_track_editor.cpp msgid "Capture" @@ -375,11 +376,12 @@ msgstr "Lag %d NYE spor og sett inn nøkler?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Create" -msgstr "Lag" +msgstr "Opprett" #: editor/animation_track_editor.cpp msgid "Anim Insert" @@ -768,7 +770,7 @@ msgstr "Erstatt" #: editor/code_editor.cpp msgid "Replace All" -msgstr "Erstatt Alle" +msgstr "Erstatt alle" #: editor/code_editor.cpp msgid "Selection Only" @@ -788,14 +790,14 @@ msgstr "Veksle skriptpanel" #: editor/plugins/texture_region_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp msgid "Zoom In" -msgstr "Zoom Inn" +msgstr "Forstørr" #: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp msgid "Zoom Out" -msgstr "Zoom Ut" +msgstr "Zoom ut" #: editor/code_editor.cpp msgid "Reset Zoom" @@ -849,12 +851,13 @@ msgstr "Scenen inneholder ikke noen skript." #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp msgid "Add" -msgstr "Legg Til" +msgstr "Legg til" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -905,8 +908,7 @@ msgstr "Kobler Til Signal:" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -915,12 +917,11 @@ msgstr "Lukk" #: editor/connections_dialog.cpp msgid "Connect" -msgstr "Koble Til" +msgstr "Koble til" #: editor/connections_dialog.cpp -#, fuzzy msgid "Signal:" -msgstr "Signaler:" +msgstr "Signal:" #: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" @@ -942,7 +943,7 @@ msgstr "Koble Til..." #: editor/connections_dialog.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Disconnect" -msgstr "Koble Fra" +msgstr "Koble fra" #: editor/connections_dialog.cpp #, fuzzy @@ -992,7 +993,7 @@ msgstr "Endre %s type" #: editor/create_dialog.cpp editor/project_settings_editor.cpp msgid "Change" -msgstr "Forandre" +msgstr "Endre" #: editor/create_dialog.cpp msgid "Create New %s" @@ -1214,7 +1215,7 @@ msgstr "Prosjektgrunnleggere" #: editor/editor_about.cpp msgid "Lead Developer" -msgstr "Utviklingsleder" +msgstr "Ledende utvikler" #. TRANSLATORS: This refers to a job title. #. The trailing space is used to distinguish with the project list application, @@ -1229,7 +1230,7 @@ msgstr "Utviklere" #: editor/editor_about.cpp msgid "Authors" -msgstr "Forfattere" +msgstr "Skapere" #: editor/editor_about.cpp msgid "Platinum Sponsors" @@ -1343,7 +1344,7 @@ msgstr "Vellykket Installering av Pakke!" #: editor/editor_asset_installer.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Success!" -msgstr "Vellykket!" +msgstr "Suksess!" #: editor/editor_asset_installer.cpp editor/editor_node.cpp msgid "Install" @@ -1413,7 +1414,7 @@ msgstr "Demp" #: editor/editor_audio_buses.cpp msgid "Bypass" -msgstr "OmgÃ¥" +msgstr "Forbipasser" #: editor/editor_audio_buses.cpp #, fuzzy @@ -1423,7 +1424,7 @@ msgstr "Bus valg" #: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp #: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "Duplicate" -msgstr "Duplisér" +msgstr "Dupliser" #: editor/editor_audio_buses.cpp msgid "Reset Volume" @@ -1479,7 +1480,7 @@ msgstr "Det finnes ingen «%s»-fil" #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" -msgstr "Layout" +msgstr "Utforming" #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." @@ -1612,7 +1613,7 @@ msgstr "Legg til AutoLoad" #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/script_create_dialog.cpp scene/gui/file_dialog.cpp msgid "Path:" -msgstr "Bane:" +msgstr "Filbane:" #: editor/editor_autoload_settings.cpp msgid "Node Name:" @@ -1668,7 +1669,7 @@ msgstr "Velg en Mappe" #: editor/filesystem_dock.cpp editor/project_manager.cpp #: scene/gui/file_dialog.cpp msgid "Create Folder" -msgstr "Lag Mappe" +msgstr "Opprett mappe" #: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp #: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp @@ -1878,9 +1879,8 @@ msgid "(Editor Disabled)" msgstr "AvslÃ¥tt" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "Beskrivelse:" +msgstr "Alternativer for klasse:" #: editor/editor_feature_profile.cpp msgid "Enable Contextual Editor" @@ -1916,9 +1916,8 @@ msgid "Error saving profile to path: '%s'." msgstr "Feil ved lagring av profilen til stien: '%s'." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Reset to Default" -msgstr "Last Standard" +msgstr "Tilbakestill til standarder" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1948,7 +1947,7 @@ msgstr "Gjeldende:" #: editor/editor_feature_profile.cpp editor/editor_node.cpp #: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp msgid "Import" -msgstr "importer" +msgstr "Importer" #: editor/editor_feature_profile.cpp editor/project_export.cpp msgid "Export" @@ -1984,9 +1983,8 @@ msgid "Import Profile(s)" msgstr "%d flere filer" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "Eksporter Prosjekt" +msgstr "Eksporter Profil" #: editor/editor_feature_profile.cpp #, fuzzy @@ -2027,7 +2025,6 @@ msgid "New Folder..." msgstr "Ny Mappe..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Oppdater" @@ -2069,11 +2066,11 @@ msgstr "Lagre ei fil" #: editor/editor_file_dialog.cpp msgid "Go Back" -msgstr "GÃ¥ Tilbake" +msgstr "GÃ¥ tilbake" #: editor/editor_file_dialog.cpp msgid "Go Forward" -msgstr "GÃ¥ Fremover" +msgstr "GÃ¥ fremover" #: editor/editor_file_dialog.cpp msgid "Go Up" @@ -2150,7 +2147,8 @@ msgstr "Mapper og Filer:" msgid "Preview:" msgstr "ForhÃ¥ndsvisning:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Fil:" @@ -2218,27 +2216,24 @@ msgid "Theme Properties" msgstr "Egenskaper" #: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Colors" -msgstr "Farge" +msgstr "Farger" #: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp msgid "Constants" msgstr "Konstanter" #: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Fonts" -msgstr "Font" +msgstr "Skrifttyper" #: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Icons" -msgstr "Ikon" +msgstr "Ikoner" #: editor/editor_help.cpp msgid "Styles" -msgstr "" +msgstr "Stiler" #: editor/editor_help.cpp msgid "Enumerations" @@ -2282,17 +2277,15 @@ msgstr "Søk Hjelp" #: editor/editor_help_search.cpp msgid "Case Sensitive" -msgstr "Forskjell pÃ¥ smÃ¥ og store bokstaver" +msgstr "Skilling mellom store/smÃ¥ bokstaver" #: editor/editor_help_search.cpp -#, fuzzy msgid "Show Hierarchy" -msgstr "Vis hjelpere" +msgstr "Vis hierarki" #: editor/editor_help_search.cpp -#, fuzzy msgid "Display All" -msgstr "Erstatt Alle" +msgstr "Vis alle" #: editor/editor_help_search.cpp #, fuzzy @@ -2334,23 +2327,20 @@ msgid "Class" msgstr "Klasse" #: editor/editor_help_search.cpp -#, fuzzy msgid "Method" -msgstr "Metoder" +msgstr "Metode" #: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" -msgstr "Signaler" +msgstr "Signal" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Konstant" #: editor/editor_help_search.cpp -#, fuzzy msgid "Property" -msgstr "Egenskap:" +msgstr "Egenskap" #: editor/editor_help_search.cpp #, fuzzy @@ -2376,6 +2366,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2409,7 +2401,7 @@ msgstr "Kopier Skript-Sti" #: editor/editor_log.cpp msgid "Output:" -msgstr "Output:" +msgstr "Utgang:" #: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp #, fuzzy @@ -2433,7 +2425,7 @@ msgstr "Nullstill Resultat" #: editor/editor_network_profiler.cpp editor/editor_node.cpp #: editor/editor_profiler.cpp msgid "Stop" -msgstr "Stopp" +msgstr "Stopp avspilling" #: editor/editor_network_profiler.cpp editor/editor_profiler.cpp #: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp @@ -2445,13 +2437,12 @@ msgid "%s/s" msgstr "%s/s" #: editor/editor_network_profiler.cpp -#, fuzzy msgid "Down" -msgstr "Last ned" +msgstr "Ned" #: editor/editor_network_profiler.cpp msgid "Up" -msgstr "Oppover" +msgstr "Opp" #: editor/editor_network_profiler.cpp editor/editor_node.cpp msgid "Node" @@ -2977,9 +2968,8 @@ msgid "Play This Scene" msgstr "Spill Scene" #: editor/editor_node.cpp -#, fuzzy msgid "Close Tab" -msgstr "Lukk Andre Faner" +msgstr "Lukk fanen" #: editor/editor_node.cpp #, fuzzy @@ -2995,9 +2985,8 @@ msgid "Close Tabs to the Right" msgstr "Lukk faner til høyre" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "Lukk Alle" +msgstr "Lukk alle faner" #: editor/editor_node.cpp msgid "Switch Scene Tab" @@ -3074,7 +3063,7 @@ msgstr "Ã…pne Scene..." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Open Recent" -msgstr "Ã…pne Nylig" +msgstr "Ã…pne nylig brukte" #: editor/editor_node.cpp msgid "Save Scene" @@ -3100,7 +3089,7 @@ msgstr "Angre" #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Redo" -msgstr "Gjenta" +msgstr "Gjør om" #: editor/editor_node.cpp #, fuzzy @@ -3131,17 +3120,17 @@ msgid "Shut Down Version Control" msgstr "Steng ned versjonskontroll" #: editor/editor_node.cpp -#, fuzzy msgid "Export..." -msgstr "Eksporter" +msgstr "Eksporter..." #: editor/editor_node.cpp msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Ã…pne prosjektdatamappe" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Ã…pne Redigererdatamappen" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3164,7 +3153,7 @@ msgstr "Avslutt til Prosjektliste" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/project_export.cpp msgid "Debug" -msgstr "Feilsøk" +msgstr "Avlus" #: editor/editor_node.cpp msgid "Deploy with Remote Debug" @@ -3278,7 +3267,7 @@ msgstr "" #: editor/editor_node.cpp editor/script_create_dialog.cpp msgid "Editor" -msgstr "Redigeringsverktøy" +msgstr "Redaktør" #: editor/editor_node.cpp msgid "Editor Settings..." @@ -3290,7 +3279,7 @@ msgstr "Redigeringsverktøy Layout" #: editor/editor_node.cpp msgid "Take Screenshot" -msgstr "Ta Skjermbilde" +msgstr "Ta skjermbilde" #: editor/editor_node.cpp msgid "Screenshots are stored in the Editor Data/Settings Folder." @@ -3301,11 +3290,6 @@ msgid "Toggle Fullscreen" msgstr "Veksle Fullskjerm" #: editor/editor_node.cpp -#, fuzzy -msgid "Toggle System Console" -msgstr "Veksle modus" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Ã…pne data for redigeringsverktøy/innstillingsmappe" @@ -3355,7 +3339,7 @@ msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" -msgstr "Fellesskap" +msgstr "Samfunn" #: editor/editor_node.cpp #, fuzzy @@ -3442,7 +3426,7 @@ msgstr "Utvid Nederste Panel" #: editor/editor_node.cpp msgid "Output" -msgstr "Output" +msgstr "Utgang" #: editor/editor_node.cpp msgid "Don't Save" @@ -3497,7 +3481,7 @@ msgstr "Eksporter Mal-Manager" #: editor/editor_node.cpp modules/gltf/editor_scene_exporter_gltf_plugin.cpp msgid "Export Library" -msgstr "Eksporter Bibliotek" +msgstr "Eksporter bibliotek" #: editor/editor_node.cpp msgid "Merge With Existing" @@ -3523,7 +3507,7 @@ msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Reload" -msgstr "Gjeninnlat" +msgstr "Oppdater" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp @@ -3540,6 +3524,7 @@ msgid "Load Errors" msgstr "Last feil" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Velg" @@ -3613,20 +3598,17 @@ msgid "Update" msgstr "Oppdater" #: editor/editor_plugin_settings.cpp -#, fuzzy msgid "Version" -msgstr "Versjon:" +msgstr "Versjon" #: editor/editor_plugin_settings.cpp -#, fuzzy msgid "Author" -msgstr "Forfattere" +msgstr "Forfatter" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" -msgstr "" +msgstr "Status" #: editor/editor_profiler.cpp msgid "Measure:" @@ -3673,14 +3655,12 @@ msgid "Frame #:" msgstr "Bilde #:" #: editor/editor_profiler.cpp -#, fuzzy msgid "Time" -msgstr "Tid:" +msgstr "Tid" #: editor/editor_profiler.cpp -#, fuzzy msgid "Calls" -msgstr "Ring" +msgstr "Samtaler" #: editor/editor_properties.cpp #, fuzzy @@ -3858,9 +3838,8 @@ msgid "Select Node(s) to Import" msgstr "Velg node(r) som skal importeres" #: editor/editor_sub_scene.cpp editor/project_manager.cpp -#, fuzzy msgid "Browse" -msgstr "Bla gjennom" +msgstr "See gjennom" #: editor/editor_sub_scene.cpp msgid "Scene Path:" @@ -3870,6 +3849,12 @@ msgstr "Scene-Sti:" msgid "Import From Node:" msgstr "Importer Fra Node:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Feil!" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -3969,7 +3954,7 @@ msgstr "" #: editor/export_template_manager.cpp msgid "Disconnected" -msgstr "Frakoblet" +msgstr "Koblet fra" #: editor/export_template_manager.cpp msgid "Resolving" @@ -3982,7 +3967,7 @@ msgstr "Kan ikke Løses" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Connecting..." -msgstr "Kobler til..." +msgstr "Kobler til…" #: editor/export_template_manager.cpp #, fuzzy @@ -4057,7 +4042,7 @@ msgstr "Eksporter Mal-Manager" #: editor/export_template_manager.cpp msgid "Current Version:" -msgstr "Gjeldende Versjon:" +msgstr "NÃ¥værende versjon:" #: editor/export_template_manager.cpp msgid "Export templates are missing. Download them or install from a file." @@ -4068,9 +4053,8 @@ msgid "Export templates are installed and ready to be used." msgstr "" #: editor/export_template_manager.cpp -#, fuzzy msgid "Open Folder" -msgstr "Ã…pne en fil" +msgstr "Ã…pne mappe…" #: editor/export_template_manager.cpp msgid "Open the folder containing installed templates for the current version." @@ -4160,9 +4144,8 @@ msgid "" msgstr "" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Favorites" -msgstr "Favoritter:" +msgstr "Favoritter" #: editor/filesystem_dock.cpp msgid "Status: Import of file failed. Please fix file and reimport manually." @@ -4266,14 +4249,12 @@ msgid "Instance" msgstr "Instans" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" -msgstr "Favoritter:" +msgstr "Legg til i favoritter" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" -msgstr "Fjern fra Gruppe" +msgstr "Fjern fra favoritter" #: editor/filesystem_dock.cpp msgid "Edit Dependencies..." @@ -4305,16 +4286,14 @@ msgstr "Lagre Ressurs Som..." #: editor/filesystem_dock.cpp editor/inspector_dock.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Expand All" msgstr "Utvid alle" #: editor/filesystem_dock.cpp editor/inspector_dock.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Collapse All" -msgstr "Kollaps alle" +msgstr "Fold sammen alle" #: editor/filesystem_dock.cpp #, fuzzy @@ -4352,7 +4331,7 @@ msgstr "Duplisér" #: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Rename..." -msgstr "Endre Navn..." +msgstr "Gi nytt navn..." #: editor/filesystem_dock.cpp msgid "Focus the search box" @@ -4378,9 +4357,8 @@ msgid "Toggle Split Mode" msgstr "Veksle modus" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Search files" -msgstr "Søk i klasser" +msgstr "Søk i filer" #: editor/filesystem_dock.cpp msgid "" @@ -4399,7 +4377,7 @@ msgstr "Flytt" #: editor/project_manager.cpp editor/rename_dialog.cpp #: editor/scene_tree_dock.cpp msgid "Rename" -msgstr "Endre navn" +msgstr "Gi nytt navn" #: editor/filesystem_dock.cpp msgid "Overwrite" @@ -4416,21 +4394,19 @@ msgstr "Opprett skript" #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp msgid "Find in Files" -msgstr "Finn i Filer" +msgstr "Finn i filer" #: editor/find_in_files.cpp -#, fuzzy msgid "Find:" -msgstr "Finn" +msgstr "Finn:" #: editor/find_in_files.cpp editor/rename_dialog.cpp msgid "Replace:" msgstr "Erstatt:" #: editor/find_in_files.cpp -#, fuzzy msgid "Folder:" -msgstr "Lag mappe" +msgstr "Mappe:" #: editor/find_in_files.cpp #, fuzzy @@ -4471,9 +4447,8 @@ msgid "Replace All (NO UNDO)" msgstr "Erstatt Alle" #: editor/find_in_files.cpp -#, fuzzy msgid "Searching..." -msgstr "Lagrer..." +msgstr "Søker …" #: editor/find_in_files.cpp #, fuzzy @@ -4546,9 +4521,8 @@ msgid "Group Editor" msgstr "Redigeringsverktøy for grupper" #: editor/groups_editor.cpp -#, fuzzy msgid "Manage Groups" -msgstr "Grupper" +msgstr "HÃ¥ndter grupper" #: editor/import/resource_importer_scene.cpp msgid "Import as Single Scene" @@ -4680,9 +4654,8 @@ msgid "Import As:" msgstr "Importer Som:" #: editor/import_dock.cpp -#, fuzzy msgid "Preset" -msgstr "Preset..." +msgstr "ForhÃ¥ndsinnstilling" #: editor/import_dock.cpp #, fuzzy @@ -4819,15 +4792,15 @@ msgid "Create a Plugin" msgstr "Lag Omriss" #: editor/plugin_config_dialog.cpp -#, fuzzy msgid "Plugin Name:" -msgstr "Plugins" +msgstr "Navn pÃ¥ tillegg:" #: editor/plugin_config_dialog.cpp msgid "Subfolder:" msgstr "Undermappe:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Forfatter:" @@ -4909,9 +4882,8 @@ msgstr "Legg til Animasjon" #: editor/plugins/animation_blend_space_2d_editor.cpp #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Load..." -msgstr "Last" +msgstr "Last..." #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp @@ -4982,9 +4954,8 @@ msgstr "" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Point" -msgstr "Flytt Punkt" +msgstr "Punkt" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp @@ -5068,7 +5039,7 @@ msgstr "Forandre" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Edit Filters" -msgstr "Rediger Filtre" +msgstr "Rediger filtere" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Output node can't be added to the blend tree." @@ -5293,7 +5264,7 @@ msgstr "Animasjon" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/version_control_editor_plugin.cpp msgid "New" -msgstr "Ny" +msgstr "Nye" #: editor/plugins/animation_player_editor_plugin.cpp #, fuzzy @@ -5333,7 +5304,7 @@ msgstr "Fortid" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Future" -msgstr "Framtid" +msgstr "Fremtid" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Depth" @@ -5418,7 +5389,7 @@ msgstr "Legg til node" #: editor/plugins/animation_state_machine_editor.cpp msgid "End" -msgstr "Slutt" +msgstr "End" #: editor/plugins/animation_state_machine_editor.cpp msgid "Immediate" @@ -5426,7 +5397,7 @@ msgstr "Umiddelbart" #: editor/plugins/animation_state_machine_editor.cpp msgid "Sync" -msgstr "" +msgstr "Synkroniser" #: editor/plugins/animation_state_machine_editor.cpp msgid "At End" @@ -5434,7 +5405,7 @@ msgstr "" #: editor/plugins/animation_state_machine_editor.cpp msgid "Travel" -msgstr "" +msgstr "Reise" #: editor/plugins/animation_state_machine_editor.cpp msgid "Start and end nodes are needed for a sub-transition." @@ -5521,13 +5492,12 @@ msgid "Fade Out (s):" msgstr "Fade Ut (s):" #: editor/plugins/animation_tree_player_editor_plugin.cpp -#, fuzzy msgid "Blend" -msgstr "Blend" +msgstr "Bland" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Mix" -msgstr "Bland" +msgstr "Miks" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Auto Restart:" @@ -5564,13 +5534,13 @@ msgstr "X-Fade Tid (s):" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Current:" -msgstr "Gjeldende:" +msgstr "Aktiv:" #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Add Input" -msgstr "Legg til Input" +msgstr "Legg til inndata" #: editor/plugins/animation_tree_player_editor_plugin.cpp #, fuzzy @@ -5751,9 +5721,8 @@ msgid "Downloading (%s / %s)..." msgstr "Laster ned" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Downloading..." -msgstr "Laster ned" +msgstr "Laster ned..." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Resolving..." @@ -5779,7 +5748,7 @@ msgstr "Prøv pÃ¥ nytt" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Download Error" -msgstr "Nedlastningsfeil" +msgstr "Feil ved nedlasting" #: editor/plugins/asset_library_editor_plugin.cpp #, fuzzy @@ -5788,7 +5757,7 @@ msgstr "Nedlastning for denne asset'en er allerede i gang!" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Recently Updated" -msgstr "" +msgstr "Nylig oppdatert" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Least Recently Updated" @@ -5813,14 +5782,12 @@ msgid "License (Z-A)" msgstr "Lisens" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "First" -msgstr "første" +msgstr "Første" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Previous" -msgstr "Forrige fane" +msgstr "Forrige" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Next" @@ -5843,9 +5810,8 @@ msgid "Search assets (excluding templates, projects, and demos)" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Import..." -msgstr "Importer" +msgstr "Importer..." #: editor/plugins/asset_library_editor_plugin.cpp #, fuzzy @@ -5865,9 +5831,8 @@ msgid "Site:" msgstr "Side:" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Support" -msgstr "Support..." +msgstr "Støtte" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Official" @@ -5878,9 +5843,8 @@ msgid "Testing" msgstr "Tester" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Loading..." -msgstr "Last" +msgstr "Laster..." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Assets ZIP File" @@ -5933,7 +5897,7 @@ msgstr "Velg malfil" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" -msgstr "ForhÃ¥ndsvis" +msgstr "ForhÃ¥ndvisning" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Configure Snap" @@ -6053,9 +6017,8 @@ msgstr "Endre CanvasItem" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Locked" -msgstr "Slett Valgte" +msgstr "LÃ¥st" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6080,29 +6043,24 @@ msgid "" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Top Left" -msgstr "Venstre" +msgstr "Øverst til venstre" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Top Right" -msgstr "Høyre" +msgstr "Øverst til høyre" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Bottom Right" -msgstr "Roter Polygon" +msgstr "Nederst til høyre" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Bottom Left" -msgstr "Bunnvisning" +msgstr "Nederst til venstre" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Center Left" -msgstr "Innrykk Venstre" +msgstr "I midten til venstre" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -6110,9 +6068,8 @@ msgid "Center Top" msgstr "Plasser Utvalg I Midten" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Center Right" -msgstr "Innrykk Høyre" +msgstr "I midten til høyre" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -6121,7 +6078,7 @@ msgstr "Plasser Utvalg I Midten" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center" -msgstr "" +msgstr "I midten" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -6249,7 +6206,7 @@ msgstr "" #: editor/plugins/texture_region_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp msgid "Zoom Reset" -msgstr "Zoom Resett" +msgstr "Tilbakestill forstørring" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6475,7 +6432,7 @@ msgstr "Fjern Ben" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "View" -msgstr "Visning" +msgstr "Vis" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Always Show Grid" @@ -6636,6 +6593,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Legg til %s" @@ -6697,9 +6655,8 @@ msgstr "" #: editor/plugins/cpu_particles_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Restart" -msgstr "Omstart NÃ¥" +msgstr "Omstart" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp @@ -6818,9 +6775,8 @@ msgid "Right Linear" msgstr "Høyrelineær" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Load Preset" -msgstr "Last Ressurs" +msgstr "Ã…pne forhÃ¥ndsinnstilling" #: editor/plugins/curve_editor_plugin.cpp msgid "Remove Curve Point" @@ -7073,7 +7029,7 @@ msgstr "MeshBibliotek..." #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Add Item" -msgstr "Legg til Element" +msgstr "Legg til en gjenstand" #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Remove Selected Item" @@ -7345,7 +7301,7 @@ msgstr "Legg til Punkt (i tomt rom)" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Delete Point" -msgstr "Fjern Punkt" +msgstr "Slett punkt" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp @@ -7495,9 +7451,8 @@ msgid "UV" msgstr "" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Points" -msgstr "Flytt Punkt" +msgstr "Poeng" #: editor/plugins/polygon_2d_editor_plugin.cpp #, fuzzy @@ -7586,7 +7541,7 @@ msgstr "Fjern UV" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid Settings" -msgstr "Rutenettsinnstillinger" +msgstr "Instillinger for rutenett" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Snap" @@ -7765,9 +7720,8 @@ msgid "New Text File..." msgstr "Ny Mappe..." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open File" -msgstr "Ã…pne en fil" +msgstr "Ã…pne fil" #: editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -7805,7 +7759,7 @@ msgstr "Feil ved lagring" #: editor/plugins/script_editor_plugin.cpp msgid "Save Theme As..." -msgstr "Lagre Tema Som..." +msgstr "Lagre drakt som …" #: editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -7815,12 +7769,12 @@ msgstr "%s-klassereferanse" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp msgid "Find Next" -msgstr "Finn Neste" +msgstr "Finn neste" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp msgid "Find Previous" -msgstr "Finn Forrige" +msgstr "Finn forrige" #: editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -7838,19 +7792,19 @@ msgstr "Lim inn Noder" #: editor/plugins/script_editor_plugin.cpp msgid "Sort" -msgstr "Sorter" +msgstr "Sortering" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Move Up" -msgstr "Flytt Opp" +msgstr "Flytt opp" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Move Down" -msgstr "Flytt Ned" +msgstr "Flytt ned" #: editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -7877,7 +7831,7 @@ msgstr "GjenÃ¥pne Lukket Skript" #: editor/plugins/script_editor_plugin.cpp msgid "Save All" -msgstr "Lagre Alt" +msgstr "Lagre alle" #: editor/plugins/script_editor_plugin.cpp msgid "Soft Reload Script" @@ -7915,7 +7869,7 @@ msgstr "Lagre drakt" #: editor/plugins/script_editor_plugin.cpp msgid "Close All" -msgstr "Lukk Alle" +msgstr "Lukk alle" #: editor/plugins/script_editor_plugin.cpp msgid "Close Docs" @@ -7935,15 +7889,15 @@ msgstr "Søk" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" -msgstr "Tre Inn I" +msgstr "Stepp Inn i" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Over" -msgstr "Hopp Over" +msgstr "Stepp over" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Break" -msgstr "Brekk" +msgstr "Stopp" #: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp #: editor/script_editor_debugger.cpp @@ -7993,12 +7947,11 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" -msgstr "Feilsøking" +msgstr "Feilsøkingsprogram" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Search Results" -msgstr "Søk hjelp" +msgstr "Søkeresultater" #: editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -8011,13 +7964,12 @@ msgid "Connections to method:" msgstr "Koble Til Node:" #: editor/plugins/script_text_editor.cpp editor/script_editor_debugger.cpp -#, fuzzy msgid "Source" -msgstr "Ressurs" +msgstr "Kilde" #: editor/plugins/script_text_editor.cpp msgid "Target" -msgstr "" +msgstr "MÃ¥l" #: editor/plugins/script_text_editor.cpp #, fuzzy @@ -8030,9 +7982,8 @@ msgid "[Ignore]" msgstr "" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Line" -msgstr "Linje:" +msgstr "Linje" #: editor/plugins/script_text_editor.cpp msgid "Go to Function" @@ -8069,7 +8020,7 @@ msgstr "SmÃ¥ bokstaver" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Capitalize" -msgstr "Store bokstaver" +msgstr "Stor forbokstav" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Syntax Highlighter" @@ -8078,27 +8029,26 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "Bokmerker" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Breakpoints" -msgstr "Slett punkter" +msgstr "Stoppunkter" #: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Go To" -msgstr "" +msgstr "GÃ¥ til" #: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" -msgstr "Klipp ut" +msgstr "Kutt" #: editor/plugins/script_text_editor.cpp editor/plugins/theme_editor_plugin.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Select All" -msgstr "Velg Alle" +msgstr "Velg alle" #: editor/plugins/script_text_editor.cpp msgid "Delete Line" @@ -8196,7 +8146,7 @@ msgstr "GÃ¥ til Linje" #: editor/plugins/script_text_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Toggle Breakpoint" -msgstr "" +msgstr "SlÃ¥ av/pÃ¥ stoppunkt" #: editor/plugins/script_text_editor.cpp msgid "Remove All Breakpoints" @@ -8368,20 +8318,17 @@ msgid "None" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Rotate" -msgstr "Roter Modus" +msgstr "Roter" #. TRANSLATORS: This refers to the movement that changes the position of an object. #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Translate" -msgstr "Oversettelser" +msgstr "Oversett" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Scale" -msgstr "Skala:" +msgstr "Skala" #: editor/plugins/spatial_editor_plugin.cpp msgid "Scaling: " @@ -8727,7 +8674,7 @@ msgstr "Last Standard" #: editor/plugins/spatial_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Transform" -msgstr "" +msgstr "Transformer" #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Object to Floor" @@ -8785,7 +8732,7 @@ msgstr "Rediger Poly" #: editor/plugins/spatial_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Settings..." -msgstr "Innstillinger …" +msgstr "Innstillinger…" #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Settings" @@ -8841,11 +8788,11 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Pre" -msgstr "" +msgstr "Pre" #: editor/plugins/spatial_editor_plugin.cpp msgid "Post" -msgstr "" +msgstr "Send" #: editor/plugins/spatial_editor_plugin.cpp msgid "Unnamed Gizmo" @@ -9022,7 +8969,7 @@ msgstr "Hastighet (FPS):" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Loop" -msgstr "" +msgstr "Repeter" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy @@ -9108,7 +9055,7 @@ msgstr "" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Offset:" -msgstr "" +msgstr "Avstand:" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Step:" @@ -9200,9 +9147,8 @@ msgid "Finalizing" msgstr "Analyserer" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Filter:" -msgstr "Lim inn Noder" +msgstr "Filter:" #: editor/plugins/theme_editor_plugin.cpp msgid "With Data" @@ -9304,9 +9250,8 @@ msgid "Select all Theme items with item data." msgstr "" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Deselect All" -msgstr "Velg Alle" +msgstr "Velg ingen" #: editor/plugins/theme_editor_plugin.cpp msgid "Deselect all Theme items." @@ -9435,9 +9380,8 @@ msgid "Edit Items" msgstr "Rediger Variabel:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Types:" -msgstr "Type:" +msgstr "Typer:" #: editor/plugins/theme_editor_plugin.cpp #, fuzzy @@ -9483,9 +9427,8 @@ msgid "Old Name:" msgstr "Nodenavn:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Import Items" -msgstr "Importer Tema" +msgstr "Importer gjenstander" #: editor/plugins/theme_editor_plugin.cpp #, fuzzy @@ -9626,7 +9569,7 @@ msgstr "Deaktivert" #: editor/plugins/theme_editor_preview.cpp msgid "Item" -msgstr "" +msgstr "Oppføring" #: editor/plugins/theme_editor_preview.cpp #, fuzzy @@ -9656,7 +9599,7 @@ msgstr "" #: editor/plugins/theme_editor_preview.cpp msgid "Submenu" -msgstr "" +msgstr "Undermeny" #: editor/plugins/theme_editor_preview.cpp #, fuzzy @@ -9700,7 +9643,7 @@ msgstr "Rediger Variabel:" #: editor/plugins/theme_editor_preview.cpp msgid "Subtree" -msgstr "" +msgstr "Undertre" #: editor/plugins/theme_editor_preview.cpp #, fuzzy @@ -9752,7 +9695,7 @@ msgstr "" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Bucket Fill" -msgstr "" +msgstr "Bøttefylling" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Erase TileMap" @@ -9764,7 +9707,7 @@ msgstr "Finn Flis" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Transpose" -msgstr "" +msgstr "Transposer" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Disable Autotile" @@ -9806,19 +9749,19 @@ msgstr "" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Rotate Left" -msgstr "Roter til Venstre" +msgstr "Roter til venstre" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Rotate Right" -msgstr "Roter til Høyre" +msgstr "Roter til høyre" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Flip Horizontally" -msgstr "" +msgstr "Vend horisontalt" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Flip Vertically" -msgstr "" +msgstr "Vend loddrett" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Clear Transform" @@ -9873,9 +9816,8 @@ msgid "Select the previous shape, subtile, or Tile." msgstr "" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Region" -msgstr "Roter Modus" +msgstr "Region" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -9897,9 +9839,8 @@ msgid "Bitmask" msgstr "Roter Modus" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Priority" -msgstr "Eksporter Prosjekt" +msgstr "Prioritet" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Icon" @@ -10192,7 +10133,7 @@ msgid "TileSet" msgstr "TileSet..." #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -10200,19 +10141,58 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy +msgid "No commit message was provided." +msgstr "Ingen navn gitt." + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" -msgstr "Fellesskap" +msgstr "Sjekk inn" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "Forandre" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Forandre" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Sjekk inn" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Undertre" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Er du sikker pÃ¥ at du vil Ã¥pne mer enn ett prosjekt?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Nullstill Zoom" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -10222,7 +10202,37 @@ msgid "Initialize" msgstr "Store bokstaver" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Fjern punkt" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Gi nytt navn" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -10231,55 +10241,147 @@ msgid "Detect new changes" msgstr "Lag ny %s" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Endringer" +#, fuzzy +msgid "Discard all changes" +msgstr "Lukke og lagre endringer?" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +#, fuzzy +msgid "Stage all changes" +msgstr "Lagrer lokale endringer..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Forandre" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Sjekk inn endringer" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "Sjekk inn endringer" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Sjekk inn" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "Endre navn" +msgid "Branches" +msgstr "Treff:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "Slett" +msgid "Create New Branch" +msgstr "Opprett Nytt Prosjekt" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Typechange" -msgstr "Forandre" +msgid "Remove Branch" +msgstr "Fjern Anim-Spor" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "Slett Valgte" +msgid "Remotes" +msgstr "Ekstern" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "Lagre Alle" +msgid "Create New Remote" +msgstr "Opprett Nytt Prosjekt" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" -msgstr "Synkroniser Skriptforandringer" +msgid "Remove Remote" +msgstr "Fjern Gjenstand" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +#, fuzzy +msgid "Remote Name" +msgstr "Fjern-funksjon " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Fjern-funksjon " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Pull" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Push" msgstr "" +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "Endret" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "Endre navn" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "Slettet" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Typechange" +msgstr "Forandre" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "View:" +msgstr "Vis" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Split" +msgstr "Splitt Sti" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unified" +msgstr "Endret" + #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" msgstr "" @@ -10300,7 +10402,7 @@ msgstr "Vektor" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" -msgstr "" +msgstr "Boolsk verdi" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Sampler" @@ -10406,9 +10508,8 @@ msgid "Fragment" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Light" -msgstr "Høyre" +msgstr "Lys" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -11135,7 +11236,7 @@ msgstr "Kjørbar" #: editor/project_export.cpp msgid "Delete preset '%s'?" -msgstr "" +msgstr "Slett forhÃ¥ndsinnstillingen «%s»?" #: editor/project_export.cpp msgid "" @@ -11152,7 +11253,7 @@ msgstr "" #: editor/project_export.cpp msgid "Release" -msgstr "" +msgstr "Slipp" #: editor/project_export.cpp #, fuzzy @@ -11169,11 +11270,11 @@ msgstr "" #: editor/project_export.cpp msgid "Presets" -msgstr "" +msgstr "ForhÃ¥ndsinnstillinger" #: editor/project_export.cpp editor/project_settings_editor.cpp msgid "Add..." -msgstr "" +msgstr "Legg til…" #: editor/project_export.cpp msgid "" @@ -11224,7 +11325,7 @@ msgstr "" #: editor/project_export.cpp msgid "Features" -msgstr "Egenskaper" +msgstr "Funksjoner" #: editor/project_export.cpp msgid "Custom (comma-separated):" @@ -11235,9 +11336,8 @@ msgid "Feature List:" msgstr "" #: editor/project_export.cpp -#, fuzzy msgid "Script" -msgstr "Kjør Skript" +msgstr "Skript" #: editor/project_export.cpp #, fuzzy @@ -11246,7 +11346,7 @@ msgstr "Eksporter Prosjekt" #: editor/project_export.cpp msgid "Text" -msgstr "" +msgstr "Tekst" #: editor/project_export.cpp msgid "Compiled Bytecode (Faster Loading)" @@ -11583,7 +11683,7 @@ msgstr "" #. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" -msgstr "Prosjektstyring" +msgstr "ProsjekthÃ¥ndterer" #: editor/project_manager.cpp #, fuzzy @@ -11597,7 +11697,7 @@ msgstr "Henter fillager, vennligst vent..." #: editor/project_manager.cpp msgid "Last Modified" -msgstr "" +msgstr "Sist endret" #: editor/project_manager.cpp #, fuzzy @@ -11611,7 +11711,7 @@ msgstr "Endre Navn pÃ¥ Prosjekt" #: editor/project_manager.cpp msgid "Scan" -msgstr "Gjennomsøk" +msgstr "Skann" #: editor/project_manager.cpp #, fuzzy @@ -11624,7 +11724,7 @@ msgstr "Velg en mappe Ã¥ søke gjennom" #: editor/project_manager.cpp msgid "New Project" -msgstr "Nytt Prosjekt" +msgstr "Nytt prosjekt" #: editor/project_manager.cpp #, fuzzy @@ -11652,12 +11752,11 @@ msgstr "Ressursbibliotek" #: editor/project_manager.cpp msgid "Restart Now" -msgstr "Omstart NÃ¥" +msgstr "Start pÃ¥ nytt nÃ¥" #: editor/project_manager.cpp -#, fuzzy msgid "Remove All" -msgstr "Fjern Funksjon" +msgstr "Fjern alle" #: editor/project_manager.cpp msgid "Also delete project contents (no undo!)" @@ -11777,14 +11876,12 @@ msgid "Wheel Right Button" msgstr "" #: editor/project_settings_editor.cpp -#, fuzzy msgid "X Button 1" -msgstr "Museknapp" +msgstr "X knapp 1" #: editor/project_settings_editor.cpp -#, fuzzy msgid "X Button 2" -msgstr "Museknapp" +msgstr "X knapp 2" #: editor/project_settings_editor.cpp msgid "Joypad Axis Index:" @@ -11852,9 +11949,8 @@ msgid "Setting '%s' is internal, and it can't be deleted." msgstr "" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Delete Item" -msgstr "Slett Valgte" +msgstr "Slett objektet" #: editor/project_settings_editor.cpp msgid "" @@ -11962,7 +12058,7 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "Localization" -msgstr "" +msgstr "Lokalisering" #: editor/project_settings_editor.cpp msgid "Translations" @@ -11986,7 +12082,7 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "Locale" -msgstr "" +msgstr "SprÃ¥k" #: editor/project_settings_editor.cpp msgid "Locales Filter" @@ -12017,7 +12113,7 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "Plugins" -msgstr "Innstikkmoduler" +msgstr "Plugins" #: editor/project_settings_editor.cpp #, fuzzy @@ -12050,7 +12146,7 @@ msgstr "" #: editor/property_editor.cpp msgid "Assign" -msgstr "Tildel" +msgstr "Knytt" #: editor/property_editor.cpp msgid "Select Node" @@ -12099,9 +12195,8 @@ msgid "Use Regular Expressions" msgstr "Gjeldende Versjon:" #: editor/rename_dialog.cpp -#, fuzzy msgid "Advanced Options" -msgstr "Snapping innstillinger" +msgstr "Avanserte alternativer" #: editor/rename_dialog.cpp msgid "Substitute" @@ -12149,9 +12244,8 @@ msgid "Initial value for the counter" msgstr "" #: editor/rename_dialog.cpp -#, fuzzy msgid "Step" -msgstr "Steg:" +msgstr "Steg" #: editor/rename_dialog.cpp msgid "Amount by which counter is incremented for each node" @@ -12159,7 +12253,7 @@ msgstr "" #: editor/rename_dialog.cpp msgid "Padding" -msgstr "" +msgstr "Fyll" #: editor/rename_dialog.cpp msgid "" @@ -12173,11 +12267,11 @@ msgstr "" #: editor/rename_dialog.cpp msgid "Style" -msgstr "" +msgstr "Stil" #: editor/rename_dialog.cpp msgid "Keep" -msgstr "" +msgstr "Behold" #: editor/rename_dialog.cpp msgid "PascalCase to snake_case" @@ -12202,9 +12296,8 @@ msgid "To Uppercase" msgstr "Store versaler" #: editor/rename_dialog.cpp -#, fuzzy msgid "Reset" -msgstr "Nullstill Zoom" +msgstr "Tilbakestill" #: editor/rename_dialog.cpp #, fuzzy @@ -12563,9 +12656,8 @@ msgid "Detach the script from the selected node." msgstr "Instanser den valgte scene(r) som barn av den valgte noden." #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Remote" -msgstr "Fjern Funksjon" +msgstr "Ekstern" #: editor/scene_tree_dock.cpp msgid "" @@ -12576,7 +12668,7 @@ msgstr "" #: editor/scene_tree_dock.cpp msgid "Local" -msgstr "" +msgstr "Lokal" #: editor/scene_tree_dock.cpp msgid "Clear Inheritance? (No Undo!)" @@ -12643,7 +12735,7 @@ msgstr "" #: editor/scene_tree_editor.cpp msgid "Toggle Visibility" -msgstr "" +msgstr "Juster synlighet" #: editor/scene_tree_editor.cpp msgid "" @@ -12725,7 +12817,7 @@ msgstr "Overskriv" #: editor/script_create_dialog.cpp msgid "N/A" -msgstr "" +msgstr "Ikke aktuelt" #: editor/script_create_dialog.cpp msgid "Open Script / Choose Location" @@ -12802,9 +12894,8 @@ msgid "Class Name:" msgstr "Klasse:" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Template:" -msgstr "Fjern Mal" +msgstr "Mal:" #: editor/script_create_dialog.cpp #, fuzzy @@ -12825,9 +12916,8 @@ msgid "Bytes:" msgstr "" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Warning:" -msgstr "Advarsler:" +msgstr "Advarsel:" #: editor/script_editor_debugger.cpp msgid "Error:" @@ -12847,9 +12937,8 @@ msgid "C++ Source" msgstr "Ressurs" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Source:" -msgstr "Ressurs" +msgstr "Kildekode:" #: editor/script_editor_debugger.cpp #, fuzzy @@ -12862,7 +12951,7 @@ msgstr "" #: editor/script_editor_debugger.cpp msgid "Errors" -msgstr "" +msgstr "Feil" #: editor/script_editor_debugger.cpp #, fuzzy @@ -12871,7 +12960,7 @@ msgstr "Frakoblet" #: editor/script_editor_debugger.cpp msgid "Copy Error" -msgstr "Kopier feil" +msgstr "Feil ved kopiering" #: editor/script_editor_debugger.cpp msgid "Open C++ Source on GitHub" @@ -12908,7 +12997,7 @@ msgstr "" #: editor/script_editor_debugger.cpp msgid "Monitor" -msgstr "" +msgstr "Skjerm" #: editor/script_editor_debugger.cpp msgid "Value" @@ -12916,7 +13005,7 @@ msgstr "" #: editor/script_editor_debugger.cpp msgid "Monitors" -msgstr "" +msgstr "Skjermer" #: editor/script_editor_debugger.cpp msgid "Pick one or more items from the list to display the graph." @@ -12936,24 +13025,25 @@ msgid "Export list to a CSV file" msgstr "Eksporter Prosjekt" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" #: editor/script_editor_debugger.cpp msgid "Type" -msgstr "" +msgstr "Skriv" #: editor/script_editor_debugger.cpp msgid "Format" -msgstr "" +msgstr "Format" #: editor/script_editor_debugger.cpp msgid "Usage" -msgstr "" +msgstr "Bruk" #: editor/script_editor_debugger.cpp msgid "Misc" -msgstr "" +msgstr "Diverse" #: editor/script_editor_debugger.cpp msgid "Clicked Control:" @@ -12995,7 +13085,7 @@ msgstr "Innstillinger for redigeringsverktøy" #: editor/settings_config_dialog.cpp msgid "Shortcuts" -msgstr "" +msgstr "Snarveier" #: editor/settings_config_dialog.cpp msgid "Binding" @@ -13118,7 +13208,7 @@ msgstr "" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Platform" -msgstr "" +msgstr "Plattform" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Dynamic Library" @@ -13143,7 +13233,7 @@ msgstr "Deaktiver Oppdateringsspinner" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Library" -msgstr "" +msgstr "Bibliotek" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Libraries: " @@ -13365,9 +13455,8 @@ msgid "Indirect lighting" msgstr "Innrykk Høyre" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Post processing" -msgstr "Gjeldende Versjon:" +msgstr "Etterbehandling" #: modules/lightmapper_cpu/lightmapper_cpu.cpp #, fuzzy @@ -13450,7 +13539,7 @@ msgstr "" #: modules/navigation/navigation_mesh_generator.cpp msgid "Done!" -msgstr "Ferdig!" +msgstr "Ferdig" #: modules/visual_script/visual_script.cpp msgid "" @@ -13805,7 +13894,7 @@ msgstr "Velg eller lag en funksjon for Ã¥ redigere graf" #: modules/visual_script/visual_script_editor.cpp msgid "Delete Selected" -msgstr "Slett Valgte" +msgstr "Slett valgt" #: modules/visual_script/visual_script_editor.cpp msgid "Find Node Type" @@ -13831,6 +13920,40 @@ msgstr "Oppdater Graf" msgid "Edit Member" msgstr "Rediger Medlem" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Gjeldende Versjon:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Animasjon" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Tilførseltype ikke itererbar: " @@ -13843,6 +13966,87 @@ msgstr "Iterator ble ugyldig" msgid "Iterator became invalid: " msgstr "Iterator ble ugyldig: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Ender mappenavn:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Bryter" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Typer:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Selv" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Gyldige karakterer:" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Legg til %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Legg til %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -13859,6 +14063,20 @@ msgstr "Sti leder ikke Node!" msgid "Invalid index property name '%s' in node %s." msgstr "Ugyldig navn for indeksegenskap '%s' i noden %s." +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funksjoner" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Endre størrelsen pÃ¥ Array" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Ugyldig argument av type: " @@ -13868,6 +14086,10 @@ msgid ": Invalid arguments: " msgstr ": Ugyldige argumenter: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -13876,6 +14098,65 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Oppdater" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Panorerings-Modus" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Panorerings-Modus" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "TidSøk Node" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Lagre Scene" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Selv" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Klipp ut Noder" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -13885,15 +14166,77 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Samtaler" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Konstanter" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Lag Ben" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Lag Ben" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Handling" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp #, fuzzy msgid "Search VisualScript" msgstr "Lim inn Noder" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Flytt Modus" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Fysikk-Frame %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" msgstr "" +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Signal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Signal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instans" + #: platform/android/export/export_plugin.cpp msgid "Package name is missing." msgstr "" @@ -13932,9 +14275,8 @@ msgid "Exporting APK..." msgstr "Eksporter" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Uninstalling..." -msgstr "Avinstaller" +msgstr "Avinstallerer …" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -14488,7 +14830,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14596,7 +14947,7 @@ msgstr "Genererer Lyskart" #: scene/3d/baked_lightmap.cpp msgid "Done" -msgstr "Ferdig" +msgstr "Fullført" #: scene/3d/collision_object.cpp msgid "" @@ -14705,7 +15056,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp @@ -14951,11 +15310,11 @@ msgstr "" #: scene/gui/color_picker.cpp msgid "HSV" -msgstr "" +msgstr "HSV" #: scene/gui/color_picker.cpp msgid "Raw" -msgstr "" +msgstr "RÃ¥" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -15023,7 +15382,7 @@ msgstr "" #: scene/gui/tree.cpp msgid "(Other)" -msgstr "" +msgstr "(Annet)" #: scene/main/scene_tree.cpp msgid "" diff --git a/editor/translations/nl.po b/editor/translations/nl.po index 9574536fb7..f7f68d55f8 100644 --- a/editor/translations/nl.po +++ b/editor/translations/nl.po @@ -410,6 +410,7 @@ msgstr "Maak %d NIEUWE sporen aan en voer sleutels in?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -879,6 +880,7 @@ msgstr "Toevoegen" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -930,8 +932,7 @@ msgstr "Kan signaal niet verbinden" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1998,7 +1999,6 @@ msgid "New Folder..." msgstr "Nieuwe map..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Verversen" @@ -2115,7 +2115,8 @@ msgstr "Mappen & Bestanden:" msgid "Preview:" msgstr "Voorbeeld:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Bestand:" @@ -2294,7 +2295,7 @@ msgstr "Methode" msgid "Signal" msgstr "Signaal" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Constante" @@ -2325,6 +2326,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Zet %s" @@ -3084,8 +3087,9 @@ msgid "Install Android Build Template..." msgstr "Android Build-sjabloon Installeren ..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Projectdatamap openen" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Editordatamap openen" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3243,10 +3247,6 @@ msgid "Toggle Fullscreen" msgstr "Volledig scherm" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Systeemconsole aan-/uitschakelen" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Editordata-/instellingenmap openen" @@ -3483,6 +3483,7 @@ msgid "Load Errors" msgstr "Laadfouten" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Selecteer" @@ -3563,7 +3564,6 @@ msgid "Author" msgstr "Auteurs" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Status" @@ -3805,6 +3805,12 @@ msgstr "Scènepad:" msgid "Import From Node:" msgstr "Vanuit knoop importeren:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Fout" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4722,6 +4728,7 @@ msgid "Subfolder:" msgstr "Submap:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Auteur:" @@ -6435,6 +6442,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Voeg %s Toe" @@ -9908,7 +9916,8 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "Geen VCS addons beschikbaar." #: editor/plugins/version_control_editor_plugin.cpp @@ -9916,16 +9925,56 @@ msgid "Error" msgstr "Fout" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "Geen bestanden toegevoegd aan stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Geen naam opgegeven." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "Commit" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "VCS Addon is niet geïnitialiseerd" +#, fuzzy +msgid "Staged Changes" +msgstr "Shader Wijzigingen" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Shader Wijzigingen" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Commit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Subtree" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Weet je zeker dat je meer dan één project wilt openen?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Reset" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9936,16 +9985,148 @@ msgid "Initialize" msgstr "Initialiseren" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "staging gebied" +#, fuzzy +msgid "Remote Login" +msgstr "Punt verwijderen" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Naam wijzigen" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Detecteer nieuwe veranderingen" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Wijzigingen" +#, fuzzy +msgid "Discard all changes" +msgstr "Wijzigingen oplaan en sluiten?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Lokale wijziging aan het opslaan..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Materiaal Wijzigingen" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Commit veranderingen" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "Commit veranderingen" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Commit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Overeenkomsten:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Creëer Nieuw Project" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Verwijder Anim Track" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Remote" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Creëer Nieuw Project" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Verwijder Item" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Remote " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Remote " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Bron Mesh:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9964,30 +10145,23 @@ msgid "Typechange" msgstr "Typewijziging" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "Stage Geselecteerd" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "Stage Alles" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "Commit veranderingen" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "" -"Bekijk de veranderde bestanden voordat ze gebruikt worden in de nieuwste " -"versie" +#, fuzzy +msgid "View:" +msgstr "Weergeven" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "Geen bestands veranderingen actief" +#, fuzzy +msgid "Split" +msgstr "Splits Pad" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "Detecteer verandering in bestanden" +#, fuzzy +msgid "Unified" +msgstr "Bewerkt" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12694,6 +12868,7 @@ msgid "Export list to a CSV file" msgstr "Exporteer lijst naar een csv-bestand" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Bronpad" @@ -13551,6 +13726,40 @@ msgstr "Diagram vernieuwen" msgid "Edit Member" msgstr "Lid bewerken" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Stel expressie in" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animatie" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Invoer type is niet iterabel: " @@ -13563,6 +13772,88 @@ msgstr "Iterator werd ongeldig" msgid "Iterator became invalid: " msgstr "Iterator werd ongeldig: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Mapnaam wijzigen:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Pitch" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Type:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Zelf" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Bij teken %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Voeg %s Toe" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Zet %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Voeg %s Toe" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Krijg %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Ongeldige index eigenschap naam." @@ -13579,6 +13870,21 @@ msgstr "Pad leidt niet naar een knoop!" msgid "Invalid index property name '%s' in node %s." msgstr "Ongeldige eigenschapnaam '%s' in knoop %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Zet %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Functies" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Array Grootte Wijzigen" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Ongeldig argument van type: " @@ -13588,6 +13894,10 @@ msgid ": Invalid arguments: " msgstr ": Ongeldige argumenten: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet niet gevonden in script: " @@ -13596,6 +13906,66 @@ msgid "VariableSet not found in script: " msgstr "VariableSet niet gevonden in script: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Herladen" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Z Index" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Z Index" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "Schakel GDNative Singleton in" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "TimeSeek-knoop" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Scèneboombewerking" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Zelf" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Knopen knippen" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" "Zelfgemaakte knoop heeft geen _step() methode, kan diagram niet verwerken." @@ -13608,13 +13978,75 @@ msgstr "" "Ongeldige terugkeerwaarde van _step(), moet een geheel getal (sequentie " "uitvoer) of string (fout) zijn." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Aanroepen" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Constanten" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Gebruik Lokale Ruimtemodus" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Gebruik Lokale Ruimtemodus" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Actie" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Zoek VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Krijg %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Verplaats Frame" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Physics Frame %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Signaal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Signaal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instantie" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14264,16 +14696,26 @@ msgstr "" "ParallaxLayer-knoop werkt alleen als kind van een ParallaxBackground-knoop." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "GPU-gebaseerde particles worden niet ondersteund door de GLES2-" "stuurprogramma.\n" "Gebruik in plaats daarvan een CPUParticles2D knoop. De \"Zet om in " "CPUParticles\" optie kan hiervoor gebruikt worden." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14520,10 +14962,11 @@ msgid "Only uniform scales are supported." msgstr "" #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "Op GPU-gebaseerde particles worden niet ondersteund door het GLES2 grafische " "stuurprogramma.\n" @@ -14532,6 +14975,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" "Niets is zichtbaar want meshes zijn niet toegewezen aan de tekendoorlopen " diff --git a/editor/translations/or.po b/editor/translations/or.po index 59c61de288..fb6c7ff0c2 100644 --- a/editor/translations/or.po +++ b/editor/translations/or.po @@ -355,6 +355,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -804,6 +805,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -853,8 +855,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1877,7 +1878,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -1994,7 +1994,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2162,7 +2163,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2192,6 +2193,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2885,7 +2888,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3020,10 +3023,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3240,6 +3239,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3316,7 +3316,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3541,6 +3540,11 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +msgid "%s Error" +msgstr "" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4396,6 +4400,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6039,6 +6044,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9321,7 +9327,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9329,7 +9335,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9337,7 +9348,35 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9349,39 +9388,55 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +msgid "Remote Login" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect new changes" +msgid "Username" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Password" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "SSH Public Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +msgid "Select SSH public key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" +msgid "SSH Private Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect new changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +msgid "Stage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Unstage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9389,15 +9444,107 @@ msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Commit List" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Create New Branch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Remove Branch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remotes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remove Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote URL" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -11906,6 +12053,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12734,6 +12882,38 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Condition" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12746,6 +12926,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12762,6 +13016,18 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Function" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12771,6 +13037,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12779,6 +13049,54 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Node" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Tree" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "CustomNode" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12788,12 +13106,64 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Action %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13355,7 +13725,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13568,7 +13947,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/pl.po b/editor/translations/pl.po index fd2468a30e..1f10b9f3a5 100644 --- a/editor/translations/pl.po +++ b/editor/translations/pl.po @@ -52,13 +52,14 @@ # Marek Malaria <to.tylko.dla.kont@gmail.com>, 2021. # Mateusz Å»ak <matisgramy@gmail.com>, 2021. # voltinus <voltinusmail@gmail.com>, 2021. +# Lech Migdal <lech.migdal@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-12-23 15:30+0000\n" -"Last-Translator: Tomek <kobewi4e@gmail.com>\n" +"PO-Revision-Date: 2022-01-12 16:52+0000\n" +"Last-Translator: Lech Migdal <lech.migdal@gmail.com>\n" "Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/" "godot/pl/>\n" "Language: pl\n" @@ -409,6 +410,7 @@ msgstr "Utworzyć %d NOWYCH Å›cieżek i dodać klatki kluczowe?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -876,6 +878,7 @@ msgstr "Dodaj" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -926,8 +929,7 @@ msgstr "Nie można połączyć sygnaÅ‚u" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1529,7 +1531,7 @@ msgstr "NiewÅ‚aÅ›ciwa nazwa." #: editor/editor_autoload_settings.cpp msgid "Cannot begin with a digit." -msgstr "" +msgstr "Nie może zaczynać siÄ™ od cyfry." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" @@ -1987,7 +1989,6 @@ msgid "New Folder..." msgstr "Utwórz katalog..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "OdÅ›wież" @@ -2104,7 +2105,8 @@ msgstr "Katalogi i pliki:" msgid "Preview:" msgstr "PodglÄ…d:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Plik:" @@ -2152,9 +2154,8 @@ msgid "Properties" msgstr "WÅ‚aÅ›ciwoÅ›ci" #: editor/editor_help.cpp -#, fuzzy msgid "overrides %s:" -msgstr "nadpisanie:" +msgstr "nadpisuje %s:" #: editor/editor_help.cpp msgid "default:" @@ -2277,7 +2278,7 @@ msgstr "Metoda" msgid "Signal" msgstr "SygnaÅ‚" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "StaÅ‚a" @@ -2308,6 +2309,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Ustaw %s" @@ -3063,8 +3066,9 @@ msgid "Install Android Build Template..." msgstr "Zainstaluj szablon eksportu dla Androida..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Otwórz folder danych projektu" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Otwórz folder danych edytora" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3221,10 +3225,6 @@ msgid "Toggle Fullscreen" msgstr "Przełącz peÅ‚ny ekran" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Przełącz systemowÄ… konsolÄ™" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Otwórz folder ustawieÅ„/danych edytora" @@ -3453,6 +3453,7 @@ msgid "Load Errors" msgstr "Błędy wczytywania" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Zaznacz" @@ -3529,7 +3530,6 @@ msgid "Author" msgstr "Autor" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Status" @@ -3773,6 +3773,12 @@ msgstr "Åšcieżka sceny:" msgid "Import From Node:" msgstr "Zaimportuj z wÄ™zÅ‚a:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Błąd" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "Otwórz folder zawierajÄ…cy te szablony." @@ -4662,6 +4668,7 @@ msgid "Subfolder:" msgstr "Podfolder:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Autor:" @@ -6362,6 +6369,7 @@ msgid "Zoom to 1600%" msgstr "Przybliż do 1600%" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Dodaj %s" @@ -9739,7 +9747,8 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "Brak dostÄ™pnych dodatków VCS." #: editor/plugins/version_control_editor_plugin.cpp @@ -9747,16 +9756,56 @@ msgid "Error" msgstr "Błąd" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "Brak plików dodanych do stage'a" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Nie podano nazwy." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "Commit" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "Dodatek VCS nie jest zainicjowany" +#, fuzzy +msgid "Staged Changes" +msgstr "Zmiany shadera:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Zmiany shadera:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Commit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Poddrzewo" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Czy jesteÅ› pewny że chcesz otworzyć wiÄ™cej niż jeden projekt?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Zastosuj reset" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9767,16 +9816,148 @@ msgid "Initialize" msgstr "Inicjuj" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "Obszar stage'a" +#, fuzzy +msgid "Remote Login" +msgstr "UsuÅ„ punkt" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "ZmieÅ„ nazwÄ™" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Wykryj nowe zmiany" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Zmiany" +#, fuzzy +msgid "Discard all changes" +msgstr "Zamknąć i zapisać zmiany?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Zachowywanie lokalnych zmian..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Zmiany materiaÅ‚u:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Commituj zmiany" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "Commituj zmiany" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Commit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "PasujÄ…ce:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Utwórz nowy projekt" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "UsuÅ„ Å›cieżkÄ™ animacji" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Zdalny" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Utwórz nowy projekt" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "UsuÅ„ element" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Zdalny " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Zdalny " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "ŹródÅ‚owa siatka:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9795,28 +9976,23 @@ msgid "Typechange" msgstr "Zmiana typu" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "Stage'uj zaznaczone" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "Stage'uj wszystko" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "Commituj zmiany" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "Zobacz różnice przed commitowaniem do najnowszej wersji" +#, fuzzy +msgid "View:" +msgstr "Widok" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "Brak aktywnego różnicowania plików (diff)" +#, fuzzy +msgid "Split" +msgstr "Podziel ÅšcieżkÄ™" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "Wykryj zmiany w różnicach plików" +#, fuzzy +msgid "Unified" +msgstr "Zmodyfikowany" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12507,6 +12683,7 @@ msgid "Export list to a CSV file" msgstr "Eksportuj listÄ™ do pliku CSV" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Åšcieżka zasobu" @@ -13352,6 +13529,40 @@ msgstr "OdÅ›wież graf" msgid "Edit Member" msgstr "Edytuj czÅ‚onka" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Ustaw wyrażenie" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animacja" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Typ danych wejÅ›ciowych nie jest iterowalny: " @@ -13364,6 +13575,88 @@ msgstr "Iterator staÅ‚ siÄ™ nieprawidÅ‚owy" msgid "Iterator became invalid: " msgstr "Iterator staÅ‚ siÄ™ nieprawidÅ‚owy: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Zmiana nazwy folderu:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "PuÅ‚ap:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Typy:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Pojedynczo" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Przy znaku %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Dodaj %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Ustaw %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Dodaj %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Przyjmij %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "NieprawidÅ‚owa nazwa wÅ‚aÅ›ciwoÅ›ci indeksowej." @@ -13380,6 +13673,21 @@ msgstr "Åšcieżka nie prowadzi do wÄ™zÅ‚a!" msgid "Invalid index property name '%s' in node %s." msgstr "NieprawidÅ‚owy indeks we wÅ‚aÅ›ciwoÅ›ci \"%s\" wÄ™zÅ‚a %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Ustaw %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funkcje" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "ZmieÅ„ rozmiar Tablicy" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ":nieprawidÅ‚owy argument typu: " @@ -13389,6 +13697,10 @@ msgid ": Invalid arguments: " msgstr ":nieprawidÅ‚owe argumenty: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "Nie znaleziono VariableGet w skrypcie: " @@ -13397,6 +13709,66 @@ msgid "VariableSet not found in script: " msgstr "Nie znaleziono VariableSet w skrypcie: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "PrzeÅ‚aduj" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Indeks Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Indeks Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "StaÅ‚a" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "StaÅ‚a" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "StaÅ‚a" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "StaÅ‚a" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "Włączony singleton GDNative" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "WÄ™zeÅ‚ Przewijania w Czasie" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Edycja drzewa sceny" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Pojedynczo" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Wytnij wÄ™zÅ‚y" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" "Niestandardowy wÄ™zeÅ‚ nie posiada metody _step(), nie można przetworzyć grafu." @@ -13409,13 +13781,75 @@ msgstr "" "NieprawidÅ‚owa wartość zwracana przez funkcjÄ™ _step(), musi ona być liczbÄ… " "caÅ‚kowitÄ… (seq out), lub tekstowÄ… (error)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "WywoÅ‚ania" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "StaÅ‚e" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Użyj przestrzeni lokalnej" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Użyj przestrzeni lokalnej" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Akcja" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Przeszukaj VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Przyjmij %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "PrzesuÅ„ klatkÄ™" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Klatka fizyki %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "SygnaÅ‚" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "SygnaÅ‚" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instancja" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14061,15 +14495,25 @@ msgstr "" "ParallaxBackground." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "CzÄ…steczki oparte o GPU sÄ… nieobsÅ‚ugiwane przez sterownik wideo GLES2.\n" "Użyj zamiast tego wÄ™zÅ‚a CPUParticles2D. Możesz użyć do tego celu opcji " "\"Konwertuj na CPUParticles\"." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14323,10 +14767,11 @@ msgid "Only uniform scales are supported." msgstr "ObsÅ‚ugiwane sÄ… tylko jednolite skale." #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "CzÄ…steczki oparte o GPU sÄ… nieobsÅ‚ugiwane przez sterownik wideo GLES2.\n" "Użyj zamiast tego wÄ™zÅ‚a CPUParticles. Możesz użyć do tego celu opcji " @@ -14334,6 +14779,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" "Nic nie jest widoczne, bo siatki nie zostaÅ‚y przypisane do kolejki rysowania." diff --git a/editor/translations/pr.po b/editor/translations/pr.po index 799813904a..daa3074190 100644 --- a/editor/translations/pr.po +++ b/editor/translations/pr.po @@ -380,6 +380,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -841,6 +842,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -892,8 +894,7 @@ msgstr "Slit th' Node" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1951,7 +1952,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2070,7 +2070,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2244,7 +2245,7 @@ msgstr "" msgid "Signal" msgstr "Yer signals:" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2275,6 +2276,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2982,7 +2985,7 @@ msgstr "" #: editor/editor_node.cpp #, fuzzy -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "Slit th' Node" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3120,11 +3123,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -#, fuzzy -msgid "Toggle System Console" -msgstr "Toggle ye Breakpoint" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3348,6 +3346,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3427,7 +3426,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3659,6 +3657,12 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Error loading yer Calligraphy Pen." + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4556,6 +4560,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6263,6 +6268,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9708,7 +9714,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9716,7 +9722,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9724,7 +9735,37 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "Change" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Change" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9736,7 +9777,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Discharge ye' Signal" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Rename Function" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9746,52 +9817,142 @@ msgstr "Yar, Blow th' Selected Down!" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Changes" +msgid "Discard all changes" msgstr "Change" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" -msgstr "" +#, fuzzy +msgid "Stage all changes" +msgstr "Change" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "Rename Function" +msgid "Unstage all changes" +msgstr "Change" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "Slit th' Node" +msgid "Commit Message" +msgstr "Change" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Typechange" +msgid "Commit Changes" +msgstr "Change" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" msgstr "Change" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" +msgid "Create New Branch" msgstr "Yar, Blow th' Selected Down!" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +#, fuzzy +msgid "Remove Branch" +msgstr "Rename Function" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" +msgid "Remotes" +msgstr "Discharge ye' Signal" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Yar, Blow th' Selected Down!" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Discharge ye' Variable" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Discharge ye' Signal" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Discharge ye' Signal" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "Rename Function" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "Slit th' Node" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Typechange" msgstr "Change" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Split" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12374,6 +12535,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13268,6 +13430,40 @@ msgstr "" msgid "Edit Member" msgstr "th' Members:" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Swap yer Expression" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Yer functions:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Yar! Yer input aint iterable: " @@ -13280,6 +13476,82 @@ msgstr "Yer Iterator be no good" msgid "Iterator became invalid: " msgstr "Yer Iterator be no good: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Switch" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "th' Base Type:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Yer index property name be thrown overboard!" @@ -13296,6 +13568,19 @@ msgstr "There be no Node at ye path's end!" msgid "Invalid index property name '%s' in node %s." msgstr "Yer index property name '%s' in node %s be walkin' th' plank!" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Yer functions:" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Evil argument of th' type: " @@ -13305,6 +13590,10 @@ msgid ": Invalid arguments: " msgstr ": Evil arguments: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet be in davy jones locker! Not in th' script: " @@ -13313,6 +13602,60 @@ msgid "VariableSet not found in script: " msgstr "VariableSet be in davy jones locker! Not in th' script: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Add yer Preload Node" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Yar, Blow th' Selected Down!" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Slit th' Node" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Slit th' Node" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Yar, Blow th' Selected Down!" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Slit th' Node" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "Yer fancy node got no _step() method, we can't get th' graph." @@ -13324,13 +13667,70 @@ msgstr "" "Yer return value from _step() be no good! She must be th' integer (seq out) " "or th' string (error)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Call" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Add Function" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp #, fuzzy msgid "Search VisualScript" msgstr "Discharge ye' Variable" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Forge yer Node!" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Yer signals:" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Yer signals:" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13903,7 +14303,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14116,7 +14525,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/pt.po b/editor/translations/pt.po index fcaec3fee6..443974d90c 100644 --- a/editor/translations/pt.po +++ b/editor/translations/pt.po @@ -6,7 +6,7 @@ # Carlos Vieira <carlos.vieira@gmail.com>, 2017. # João <joao@nogordio.com>, 2018. # João Graça <jgraca95@gmail.com>, 2017. -# João Lopes <linux-man@hotmail.com>, 2017-2018, 2019, 2020, 2021. +# João Lopes <linux-man@hotmail.com>, 2017-2018, 2019, 2020, 2021, 2022. # Miguel Gomes <miggas09@gmail.com>, 2017. # Paulo Caldeira <paucal@gmail.com>, 2018. # Pedro Gomes <pedrogomes1698@gmail.com>, 2017. @@ -24,7 +24,7 @@ msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-12-31 08:52+0000\n" +"PO-Revision-Date: 2022-01-12 16:52+0000\n" "Last-Translator: João Lopes <linux-man@hotmail.com>\n" "Language-Team: Portuguese <https://hosted.weblate.org/projects/godot-engine/" "godot/pt/>\n" @@ -336,9 +336,8 @@ msgid "Duplicate Key(s)" msgstr "Duplicar Chave(s)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add RESET Value(s)" -msgstr "Adicionar %d Frame(s)" +msgstr "Adicionar Valor(es) RESET" #: editor/animation_track_editor.cpp msgid "Delete Key(s)" @@ -375,6 +374,7 @@ msgstr "Criar %d NOVAS pistas e inserir chaves?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -510,9 +510,8 @@ msgstr "" "Esta opção não funciona para edição de Bezier, dado que é uma única faixa." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Add RESET Keys" -msgstr "Anim Escalar Chaves" +msgstr "Anim Adicionar Chaves RESET" #: editor/animation_track_editor.cpp msgid "" @@ -843,6 +842,7 @@ msgstr "Adicionar" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -894,8 +894,7 @@ msgstr "Incapaz de conectar sinal" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1500,7 +1499,7 @@ msgstr "Nome inválido." #: editor/editor_autoload_settings.cpp msgid "Cannot begin with a digit." -msgstr "" +msgstr "Não pode começar com um dÃgito." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" @@ -1960,7 +1959,6 @@ msgid "New Folder..." msgstr "Nova Diretoria..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Atualizar" @@ -2077,7 +2075,8 @@ msgstr "Diretorias e Ficheiros:" msgid "Preview:" msgstr "Pré-visualização:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Ficheiro:" @@ -2127,9 +2126,8 @@ msgid "Properties" msgstr "Propriedades" #: editor/editor_help.cpp -#, fuzzy msgid "overrides %s:" -msgstr "sobrepor:" +msgstr "sobrepor %s:" #: editor/editor_help.cpp msgid "default:" @@ -2252,7 +2250,7 @@ msgstr "Método" msgid "Signal" msgstr "Sinal" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Constante" @@ -2269,20 +2267,22 @@ msgid "Property:" msgstr "Propriedade:" #: editor/editor_inspector.cpp -#, fuzzy msgid "Pin value" -msgstr "(valor)" +msgstr "Valor pin" #: editor/editor_inspector.cpp msgid "" "Pinning a value forces it to be saved even if it's equal to the default." msgstr "" +"Fixar um valor força-o a ser guardado mesmo que seja igual à predefinição." #: editor/editor_inspector.cpp msgid "Pin value [Disabled because '%s' is editor-only]" -msgstr "" +msgstr "Fixar valor [Desativado porque '%s' é só-para-editor]" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Definir %s" @@ -2293,26 +2293,23 @@ msgstr "Definir Múltiplo:" #: editor/editor_inspector.cpp msgid "Pinned %s" -msgstr "" +msgstr "Fixado %s" #: editor/editor_inspector.cpp msgid "Unpinned %s" -msgstr "" +msgstr "Desafixado %s" #: editor/editor_inspector.cpp -#, fuzzy msgid "Copy Property" -msgstr "Copiar Propriedades" +msgstr "Copiar Propriedade" #: editor/editor_inspector.cpp -#, fuzzy msgid "Paste Property" -msgstr "Colar Propriedades" +msgstr "Colar Propriedade" #: editor/editor_inspector.cpp -#, fuzzy msgid "Copy Property Path" -msgstr "Copiar Caminho do Script" +msgstr "Copiar Caminho da Propriedade" #: editor/editor_log.cpp msgid "Output:" @@ -3040,8 +3037,9 @@ msgid "Install Android Build Template..." msgstr "Instalar Modelo Android de Compilação..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Abrir Pasta de Dados do Projeto" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Abrir Pasta de Dados do Editor" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3129,7 +3127,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Force Shader Fallbacks" -msgstr "" +msgstr "Forçar Shader de Recurso" #: editor/editor_node.cpp msgid "" @@ -3199,10 +3197,6 @@ msgid "Toggle Fullscreen" msgstr "Alternar Ecrã completo" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Alternar Consola do Sistema" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Abrir Pasta do Editor de Dados/Configurações" @@ -3432,6 +3426,7 @@ msgid "Load Errors" msgstr "Carregar Erros" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Selecionar" @@ -3508,7 +3503,6 @@ msgid "Author" msgstr "Autor" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Status" @@ -3753,6 +3747,12 @@ msgstr "Caminho da Cena:" msgid "Import From Node:" msgstr "Importar do Nó:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Erro" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "Abrir a pasta que contem estes modelos." @@ -4298,9 +4298,8 @@ msgid "Replace..." msgstr "Substituir..." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Replace in Files" -msgstr "Substituir todos" +msgstr "Substituir em Ficheiros" #: editor/find_in_files.cpp msgid "Find: " @@ -4311,9 +4310,8 @@ msgid "Replace: " msgstr "Substituir: " #: editor/find_in_files.cpp -#, fuzzy msgid "Replace All (NO UNDO)" -msgstr "Substituir todos" +msgstr "Substituir Tudo (DEFINITIVO)" #: editor/find_in_files.cpp msgid "Searching..." @@ -4537,6 +4535,8 @@ msgid "" "Select a resource file in the filesystem or in the inspector to adjust " "import settings." msgstr "" +"Selecione um ficheiro de recurso no sistema de ficheiros ou no inspetor para " +"ajustar configuração de importação." #: editor/inspector_dock.cpp msgid "Failed to load resource." @@ -4645,6 +4645,7 @@ msgid "Subfolder:" msgstr "Sub-pasta:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Autor:" @@ -5997,9 +5998,8 @@ msgid "Alt+Drag: Move selected node." msgstr "Alt+Arrastar: Mover nó selecionado." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Alt+Drag: Scale selected node." -msgstr "Alt+Arrastar: Mover nó selecionado." +msgstr "Alt+Arrastar: Escalar nó selecionado." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "V: Set selected node's pivot position." @@ -6033,7 +6033,7 @@ msgstr "Modo Escalar" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Shift: Scale proportionally." -msgstr "" +msgstr "Shift: Escalar proporcionalmente." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6132,9 +6132,8 @@ msgstr "Bloquear a posição do objeto selecionado (não pode ser movido)." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected Node(s)" -msgstr "Bloquear Seleção" +msgstr "Bloquear Nó(s) Selecionado(s)" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6143,9 +6142,8 @@ msgstr "Desbloquear o Objeto selecionado (pode ser movido)." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected Node(s)" -msgstr "Desbloquear Seleção" +msgstr "Desbloquear Nó(s) Selecionado(s)" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6154,9 +6152,8 @@ msgstr "Assegura que os Objetos-filho não são selecionáveis." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected Node(s)" -msgstr "Agrupar Seleção" +msgstr "Agrupar Nó(s) Selecionado(s)" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6165,9 +6162,8 @@ msgstr "Restaura a capacidade de selecionar os Objetos-filho." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected Node(s)" -msgstr "Desagrupar Seleção" +msgstr "Desagrupar Nó(s) Selecionado(s)" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Skeleton Options" @@ -6340,6 +6336,7 @@ msgid "Zoom to 1600%" msgstr "Zoom a 1600%" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Adicionar %s" @@ -7806,9 +7803,8 @@ msgid "Find in Files..." msgstr "Localizar em Ficheiros..." #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Replace in Files..." -msgstr "Substituir..." +msgstr "Substituir em Ficheiros..." #: editor/plugins/script_text_editor.cpp msgid "Contextual Help" @@ -8336,16 +8332,15 @@ msgstr "Alternar Freelook" #: editor/plugins/spatial_editor_plugin.cpp msgid "Decrease Field of View" -msgstr "" +msgstr "Reduzir Campo de Visão" #: editor/plugins/spatial_editor_plugin.cpp msgid "Increase Field of View" -msgstr "" +msgstr "Aumentar Campo de Visão" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Reset Field of View to Default" -msgstr "Restaurar Predefinição" +msgstr "Restaurar Campo de Visão para Predefinição" #: editor/plugins/spatial_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9074,22 +9069,19 @@ msgstr "Adicionar Tipo" #: editor/plugins/theme_editor_plugin.cpp msgid "Filter the list of types or create a new custom type:" -msgstr "" +msgstr "Filtra a lista de tipos ou cria um novo tipo personalizado:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Available Node-based types:" -msgstr "Perfis disponÃveis:" +msgstr "Tipos de Nós disponÃveis:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Type name is empty!" -msgstr "Nome do Ficheiro vazio." +msgstr "Nome do tipo vazio!" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Are you sure you want to create an empty type?" -msgstr "Está seguro que quer abrir mais do que um Projeto?" +msgstr "Está seguro que quer criar um tipo vazio?" #: editor/plugins/theme_editor_plugin.cpp msgid "Confirm Item Rename" @@ -9709,7 +9701,8 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "Não existem addons VCS disponÃveis." #: editor/plugins/version_control_editor_plugin.cpp @@ -9717,16 +9710,56 @@ msgid "Error" msgstr "Erro" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "Nenhum ficheiro adicionado ao palco" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Nome não fornecido." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "Gravar" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "Addon VCS não foi inicializado" +#, fuzzy +msgid "Staged Changes" +msgstr "Mudanças do Shader:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Mudanças do Shader:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Gravar" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Sub-árvore" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Está seguro que quer criar um tipo vazio?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Aplicar Reinicialização" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9737,16 +9770,148 @@ msgid "Initialize" msgstr "Inicializar" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "Ãrea de Palco" +#, fuzzy +msgid "Remote Login" +msgstr "Remover Ponto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Renomear" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Detetar novas alterações" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Alterações" +#, fuzzy +msgid "Discard all changes" +msgstr "Fechar e guardar alterações?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "A armazenar alterações locais..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Mudanças de Material:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Gravar Alterações" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "Gravar Alterações" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Gravar" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Correspondências:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Criar novo Projeto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Remover Pista de Animação" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Remoto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Criar novo Projeto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Remover item" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Remoto " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Remoto " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Fonte Malha:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9765,28 +9930,23 @@ msgid "Typechange" msgstr "Mudança de tipo" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "Palco Selecionado" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "Tudo no Palco" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "Gravar Alterações" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "Ver diffs dos ficheiros antes de atualizá-los para a última versão" +#, fuzzy +msgid "View:" +msgstr "Vista" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "Nenhum ficheiro diff está ativo" +#, fuzzy +msgid "Split" +msgstr "Separar Caminho" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "Detetar alterações em ficheiro diff" +#, fuzzy +msgid "Unified" +msgstr "Modificado" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12474,6 +12634,7 @@ msgid "Export list to a CSV file" msgstr "Exportar lista para ficheiro CSV" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Caminho do Recurso" @@ -13319,6 +13480,40 @@ msgstr "Atualizar Gráfico" msgid "Edit Member" msgstr "Editar Membro" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Definir expressão" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animação" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Tipo de Input não iterável: " @@ -13331,6 +13526,88 @@ msgstr "O iterador tornou-se inválido" msgid "Iterator became invalid: " msgstr "O iterador tornou-se inválido: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Renomear diretoria:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Inclinação:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Tipos:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Auto" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "No carácter %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Adicionar %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Definir %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Fixado %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Obter %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Nome de Ãndice Propriedade inválido." @@ -13347,6 +13624,21 @@ msgstr "Caminho não conduz Nó!" msgid "Invalid index property name '%s' in node %s." msgstr "Nome de propriedade Ãndice '%s' inválido no nó %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Definir %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funções" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Redimensionar Array" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Argumento inválido de tipo: " @@ -13356,6 +13648,10 @@ msgid ": Invalid arguments: " msgstr ": Argumentos inválidos: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet não encontrado no script: " @@ -13364,6 +13660,66 @@ msgid "VariableSet not found in script: " msgstr "VariableSet não encontrado no script: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Recarregar" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Ãndice Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Ãndice Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "Ativa Singleton GDNative" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Nó TimeSeek" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Edição da Ãrvore de Cena" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Auto" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Cortar Nós" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" "Nó personalizado não tem método _step(), sem poder processar um gráfico." @@ -13376,13 +13732,75 @@ msgstr "" "Retorno de valor inválido a partir do _step(), tem de ser inteiro (seq out), " "ou cadeia (error)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Chamadas" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Constantes" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Usar Espaço Local" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Usar Espaço Local" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Ação" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Procurar VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Obter %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Mover Frame" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Frame de FÃsica %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Sinal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Sinal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instância" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -13994,7 +14412,7 @@ msgstr "O polÃgono oclusor deste oclusor está vazio. Desenhe um polÃgono." #: scene/2d/navigation_agent_2d.cpp msgid "The NavigationAgent2D can be used only under a Node2D node." -msgstr "" +msgstr "O NavigationAgent2D pode ser apenas usado dentro de um nó Node2D." #: scene/2d/navigation_obstacle_2d.cpp msgid "" @@ -14026,15 +14444,25 @@ msgstr "" "ParallaxBackground." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "PartÃculas baseadas em GPU não são suportadas pelo driver de vÃdeo GLES2.\n" "Use o nó CPUParticles2D. Pode usar a opção \"Converter em CPUParticles\" " "para este efeito." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14283,10 +14711,11 @@ msgid "Only uniform scales are supported." msgstr "Apenas são suportadas escalas uniformes." #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "PartÃculas baseadas em GPU não são suportadas pelo driver de vÃdeo GLES2.\n" "Use o nó CPUParticles. Pode usar a opção \"Converter em CPUParticles\" para " @@ -14294,6 +14723,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" "Nada é visÃvel porque não foram atribuÃdas malhas aos passos de desenho." diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po index f4872c4483..b60b09c80e 100644 --- a/editor/translations/pt_BR.po +++ b/editor/translations/pt_BR.po @@ -488,6 +488,7 @@ msgstr "Criar %d NOVAS faixas e inserir chaves?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -957,6 +958,7 @@ msgstr "Adicionar" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -1007,8 +1009,7 @@ msgstr "Não foi possÃvel conectar o sinal" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -2073,7 +2074,6 @@ msgid "New Folder..." msgstr "Nova Pasta..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Atualizar" @@ -2190,7 +2190,8 @@ msgstr "Diretórios & Arquivos:" msgid "Preview:" msgstr "Previsualização:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Arquivo:" @@ -2365,7 +2366,7 @@ msgstr "Método" msgid "Signal" msgstr "Sinal" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Constante" @@ -2396,6 +2397,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Conjunto %s" @@ -3158,8 +3161,9 @@ msgid "Install Android Build Template..." msgstr "Instalar Modelo de Compilação Android..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Abrir Pasta do Projeto" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Abrir a Pasta de dados do Editor" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3317,10 +3321,6 @@ msgid "Toggle Fullscreen" msgstr "Alternar Tela Cheia" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Alternar Console do Sistema" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Abrir Editor/Configurações de Pasta" @@ -3551,6 +3551,7 @@ msgid "Load Errors" msgstr "Erros de Carregamento" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Selecionar" @@ -3627,7 +3628,6 @@ msgid "Author" msgstr "Autor" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Estado" @@ -3873,6 +3873,12 @@ msgstr "Caminho da Cena:" msgid "Import From Node:" msgstr "Importar a Partir do Nó:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Erro" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "Abrir a pasta contendo esses modelos." @@ -4771,6 +4777,7 @@ msgid "Subfolder:" msgstr "Subpasta:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Autor:" @@ -6475,6 +6482,7 @@ msgid "Zoom to 1600%" msgstr "Zoom para 1600%" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Adicionar %s" @@ -9849,7 +9857,8 @@ msgid "TileSet" msgstr "Conjunto de Telha" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "Nenhum complemento VCS está disponÃvel." #: editor/plugins/version_control_editor_plugin.cpp @@ -9857,16 +9866,56 @@ msgid "Error" msgstr "Erro" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "Nenhum arquivo em espera" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Nenhum nome fornecido." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "Confirmação" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "VCS Addon não inicializado" +#, fuzzy +msgid "Staged Changes" +msgstr "Alterações de Shader:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Alterações de Shader:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Confirmação" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Subárvore" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Tem certeza de que quer abrir mais de um projeto?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Redefinir" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9877,16 +9926,148 @@ msgid "Initialize" msgstr "Inicializar" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "Ãrea de espera" +#, fuzzy +msgid "Remote Login" +msgstr "Remover Ponto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Renomear" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Detectar novas mudanças" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Mudanças" +#, fuzzy +msgid "Discard all changes" +msgstr "Fechar e salvar alterações?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Armazenando alterações locais..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Alterações de Material:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Confirmar Mudanças" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "Confirmar Mudanças" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Confirmação" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Correspondências:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Criar Novo Projeto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Remover Trilha da Anim" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Remoto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Criar Novo Projeto" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Remover Item" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Remoto " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Remoto " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Malha de Origem:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9905,28 +10086,23 @@ msgid "Typechange" msgstr "Alteração de tipo" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "Estágio selecionado" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "Salvar Tudo" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "Confirmar Mudanças" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "Ver aquivos diff antes do commit para a última versão" +#, fuzzy +msgid "View:" +msgstr "Visualizar" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "Nenhuma mudança no arquivo" +#, fuzzy +msgid "Split" +msgstr "Dividir Caminho" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "Detectar mudanças no arquivo diff" +#, fuzzy +msgid "Unified" +msgstr "Modificado" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12619,6 +12795,7 @@ msgid "Export list to a CSV file" msgstr "Exportar lista para arquivo CSV" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Caminho do Recurso" @@ -13465,6 +13642,40 @@ msgstr "Atualizar Grafo" msgid "Edit Member" msgstr "Editar Membro" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Definir expressão" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animação" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Tipo de entrada não iterável: " @@ -13477,6 +13688,88 @@ msgstr "Iterador tornou-se inválido" msgid "Iterator became invalid: " msgstr "Iterador tornou-se inválido: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Renomear pasta:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Tom:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Modelos:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Self" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Para caractere %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Adicionar %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Conjunto %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Adicionar %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Receba %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Nome da propriedade de Ãndice inválido." @@ -13493,6 +13786,21 @@ msgstr "Caminho não leva a um Nó!" msgid "Invalid index property name '%s' in node %s." msgstr "Nome de propriedade '%s' inválido no nó %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Conjunto %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funções" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Redimensionar Vetor" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Argumento inválido do tipo: " @@ -13502,6 +13810,10 @@ msgid ": Invalid arguments: " msgstr ": Argumentos inválidos: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet não encontrada no script: " @@ -13510,6 +13822,66 @@ msgid "VariableSet not found in script: " msgstr "VariableSet não encontrada no script: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Recarregar" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Ãndice Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Ãndice Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "Singleton GDNative ativado" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Nó TimeSeek" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Edição da Ãrvore de Cena" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Self" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Recortar Nós" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" "Nó customizado não tem um método _step(), não foi possÃvel processar o " @@ -13523,13 +13895,75 @@ msgstr "" "Valor de retorno da _step() inválido, deve ser um inteiro (seq out), ou " "string (erro)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Chamadas" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Constantes" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Usar Espaço Local" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Usar Espaço Local" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Ação" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Buscar VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Receba %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Mover Quadro" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Frame de FÃsica %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Sinal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Sinal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instância" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14180,15 +14614,25 @@ msgstr "" "ParallaxBackground." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "PartÃculas baseadas em GPU não são suportadas pelo driver de vÃdeo GLES2.\n" "Use o nó CPUParticles2D como substituto. Você pode usar a opção \"Converter " "para CPUParticles\" para este propósito." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14441,10 +14885,11 @@ msgid "Only uniform scales are supported." msgstr "Apenas escalas uniformes são suportadas." #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "PartÃculas baseadas em GPU não são suportadas pelo driver de vÃdeo GLES2.\n" "Use o nó CPUParticles como substituto. Você pode usar a opção \"Converter " @@ -14452,6 +14897,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" "Nada está visÃvel porque as meshes não foram atribuÃdas a passes de desenho." diff --git a/editor/translations/ro.po b/editor/translations/ro.po index d763d64a8c..216de7fab1 100644 --- a/editor/translations/ro.po +++ b/editor/translations/ro.po @@ -374,6 +374,7 @@ msgstr "CreaÈ›i %d piste NOI È™i inseraÈ›i cheie?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -842,6 +843,7 @@ msgstr "AdăugaÈ›i" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -892,8 +894,7 @@ msgstr "Nu se poate conecta semnalul" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1967,7 +1968,6 @@ msgid "New Folder..." msgstr "Director Nou..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Reîmprospătare" @@ -2084,7 +2084,8 @@ msgstr "Directoare È™i FiÅŸiere:" msgid "Preview:" msgstr "PrevizualizaÈ›i:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "FiÈ™ier:" @@ -2260,7 +2261,7 @@ msgstr "Metodă" msgid "Signal" msgstr "Semnal" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Permanent" @@ -2291,6 +2292,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp #, fuzzy msgid "Set %s" @@ -3046,8 +3049,9 @@ msgid "Install Android Build Template..." msgstr "Instalare È™ablon compilare Android..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "DeschideÈ›i folderul datelor proiectului" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Deschidere dosarul de date editor" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3207,10 +3211,6 @@ msgid "Toggle Fullscreen" msgstr "Comutare ecran complet" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Cumutează Consola de Sistem" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Deschide Dosarul De Date/Setări" @@ -3436,6 +3436,7 @@ msgid "Load Errors" msgstr "ÃŽncarcă Erorile" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Selectează" @@ -3516,7 +3517,6 @@ msgid "Author" msgstr "Autori" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3748,6 +3748,12 @@ msgstr "Calea Scenei:" msgid "Import From Node:" msgstr "Importă Din Nod:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Eroare!" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4649,6 +4655,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Autor:" @@ -6419,6 +6426,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Adaugă %s" @@ -9950,7 +9958,7 @@ msgid "TileSet" msgstr "Set de dale" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9958,19 +9966,58 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy +msgid "No commit message was provided." +msgstr "Niciun nume furnizat." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy msgid "Commit" msgstr "Comunitate" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "SchimbaÈ›i" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "SchimbaÈ›i" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Comunitate" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "EÈ™ti sigur că vrei să È™tergi toate conexiunile de la acest semnal?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "ResetaÈ›i" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -9979,7 +10026,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Elimină punct" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "RedenumeÈ™te" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9989,53 +10066,146 @@ msgstr "CreaÈ›i %s Nou" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Changes" -msgstr "SchimbaÈ›i" +msgid "Discard all changes" +msgstr "Modificări ale Actualizării" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +#, fuzzy +msgid "Stage all changes" +msgstr "Modificările locale se stochează..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Modificări ale Actualizării" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Sincronizează Modificările Scriptului" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Changes" +msgstr "Sincronizează Modificările Scriptului" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Comunitate" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "RedenumeÈ™te" +msgid "Branches" +msgstr "Potriviri:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" +msgid "Create New Branch" +msgstr "CreaÈ›i %s Nou" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Elimină Pista Anim" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" msgstr "ȘtergeÈ›i" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Typechange" -msgstr "SchimbaÈ›i" +msgid "Create New Remote" +msgstr "CreaÈ›i %s Nou" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "ScalaÈ›i SelecÈ›ia" +msgid "Remove Remote" +msgstr "Elimină Șablon" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "ÃŽnlocuiÈ›i Tot" +msgid "Remote Name" +msgstr "Nume Nod:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" -msgstr "Sincronizează Modificările Scriptului" +msgid "Remote URL" +msgstr "ȘtergeÈ›i" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Fetch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Pull" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Mesh Sursă:" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "RedenumeÈ™te" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "ȘtergeÈ›i" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Typechange" +msgstr "SchimbaÈ›i" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "View:" +msgstr "Perspectivă" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Split" +msgstr "Divizare cale" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12632,6 +12802,7 @@ msgid "Export list to a CSV file" msgstr "Exportă Profil" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13500,6 +13671,40 @@ msgstr "ReîmprospătaÈ›i" msgid "Edit Member" msgstr "Membri" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Setare expresie" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animaÈ›ie" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -13512,6 +13717,86 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Redenumind directorul:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Propriu" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "La caracterul %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Adaugă %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "SetaÈ›i %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Adaugă %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -13528,6 +13813,21 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "SetaÈ›i %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "FuncÈ›ii" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "RedimensionaÈ›i Array-ul" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -13537,6 +13837,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -13545,6 +13849,64 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Mod ÃŽn Jur" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Mod ÃŽn Jur" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Permanent" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Permanent" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Permanent" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Permanent" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Nod CăutareTimp" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Editează Arborele Scenei" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Propriu" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Creează Nod" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -13554,15 +13916,77 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Apeluri" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Constante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Creează Oase" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Creează Oase" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "AcÈ›iune" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp #, fuzzy msgid "Search VisualScript" msgstr "Curăță Scriptul" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Mod Mutare" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Cadru Fizic %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" msgstr "" +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Semnal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Semnal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instanță" + #: platform/android/export/export_plugin.cpp msgid "Package name is missing." msgstr "" @@ -14148,7 +14572,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14363,7 +14796,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/ru.po b/editor/translations/ru.po index dfecd99550..d8ca320413 100644 --- a/editor/translations/ru.po +++ b/editor/translations/ru.po @@ -56,7 +56,7 @@ # КонÑтантин Рин <email.to.rean@gmail.com>, 2019, 2020. # Maxim Samburskiy <alpacones@outlook.com>, 2019. # Dima Koshel <form.eater@gmail.com>, 2019. -# Danil Alexeev <danil@alexeev.xyz>, 2019, 2020, 2021. +# Danil Alexeev <danil@alexeev.xyz>, 2019, 2020, 2021, 2022. # Ravager <al.porkhunov@gmail.com>, 2019. # ÐлекÑандр <akonn7@mail.ru>, 2019. # Rei <clxgamer12@gmail.com>, 2019. @@ -106,7 +106,7 @@ msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-12-14 15:28+0000\n" +"PO-Revision-Date: 2022-01-12 16:52+0000\n" "Last-Translator: Danil Alexeev <danil@alexeev.xyz>\n" "Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/" "godot/ru/>\n" @@ -116,7 +116,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.10-dev\n" +"X-Generator: Weblate 4.10.1\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -421,9 +421,8 @@ msgid "Duplicate Key(s)" msgstr "Дублировать ключ(и)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add RESET Value(s)" -msgstr "Добавить кадров: %d" +msgstr "Добавить значение(Ñ) СБРОСа" #: editor/animation_track_editor.cpp msgid "Delete Key(s)" @@ -460,6 +459,7 @@ msgstr "Создать %d новые дорожки и вÑтавить ключ #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -595,9 +595,8 @@ msgstr "" "одна дорожка." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Add RESET Keys" -msgstr "МаÑштабировать ключи" +msgstr "Добавить ключи СБРОСа" #: editor/animation_track_editor.cpp msgid "" @@ -928,6 +927,7 @@ msgstr "Добавить" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -979,8 +979,7 @@ msgstr "Ðе удаетÑÑ Ð¿Ñ€Ð¸Ñоединить Ñигнал" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1581,7 +1580,7 @@ msgstr "ÐедопуÑтимое имÑ." #: editor/editor_autoload_settings.cpp msgid "Cannot begin with a digit." -msgstr "" +msgstr "Ðе может начинатьÑÑ Ñ Ñ†Ð¸Ñ„Ñ€Ñ‹." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" @@ -2044,7 +2043,6 @@ msgid "New Folder..." msgstr "ÐÐ¾Ð²Ð°Ñ Ð¿Ð°Ð¿ÐºÐ°..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Обновить" @@ -2161,7 +2159,8 @@ msgstr "Каталоги и файлы:" msgid "Preview:" msgstr "ПредпроÑмотр:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Файл:" @@ -2211,9 +2210,8 @@ msgid "Properties" msgstr "СвойÑтва" #: editor/editor_help.cpp -#, fuzzy msgid "overrides %s:" -msgstr "переопределено:" +msgstr "переопределÑет %s:" #: editor/editor_help.cpp msgid "default:" @@ -2336,7 +2334,7 @@ msgstr "Метод" msgid "Signal" msgstr "Сигнал" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "КонÑтанта" @@ -2353,20 +2351,24 @@ msgid "Property:" msgstr "Параметр:" #: editor/editor_inspector.cpp -#, fuzzy msgid "Pin value" -msgstr "(значение)" +msgstr "Закрепить значение" #: editor/editor_inspector.cpp msgid "" "Pinning a value forces it to be saved even if it's equal to the default." msgstr "" +"Закрепление Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð·Ð°ÑтавлÑет его ÑохранÑтьÑÑ, даже еÑли оно равно " +"значению по умолчанию." #: editor/editor_inspector.cpp msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" +"Закрепить значение [Отключено, так как «%s» доÑтупно только Ð´Ð»Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¾Ñ€Ð°]" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Задать %s" @@ -2377,26 +2379,23 @@ msgstr "Задать неÑколько:" #: editor/editor_inspector.cpp msgid "Pinned %s" -msgstr "" +msgstr "Закреплено %s" #: editor/editor_inspector.cpp msgid "Unpinned %s" -msgstr "" +msgstr "Откреплено %s" #: editor/editor_inspector.cpp -#, fuzzy msgid "Copy Property" -msgstr "Копировать ÑвойÑтва" +msgstr "Копировать ÑвойÑтво" #: editor/editor_inspector.cpp -#, fuzzy msgid "Paste Property" -msgstr "Ð’Ñтавить ÑвойÑтва" +msgstr "Ð’Ñтавить ÑвойÑтво" #: editor/editor_inspector.cpp -#, fuzzy msgid "Copy Property Path" -msgstr "Копировать путь к Ñкрипту" +msgstr "Копировать путь к ÑвойÑтву" #: editor/editor_log.cpp msgid "Output:" @@ -3125,8 +3124,9 @@ msgid "Install Android Build Template..." msgstr "УÑтановить шаблон Ñборки Android..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Открыть папку Ñ Ð´Ð°Ð½Ð½Ñ‹Ð¼Ð¸ проекта" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Открыть папку данных редактора" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3214,7 +3214,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Force Shader Fallbacks" -msgstr "" +msgstr "Принудительно уÑтановить резервные шейдеры" #: editor/editor_node.cpp msgid "" @@ -3225,6 +3225,13 @@ msgid "" "Asynchronous shader compilation must be enabled in the project settings for " "this option to make a difference." msgstr "" +"ЕÑли Ñта Ð¾Ð¿Ñ†Ð¸Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°, шейдеры будут иÑпользоватьÑÑ Ð² их резервной форме " +"(либо видимой через убершейдер, либо Ñкрытой) в течение вÑего времени " +"выполнениÑ.\n" +"Ðто полезно Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ внешнего вида и производительноÑти резервных " +"шейдеров, которые обычно отображаютÑÑ Ð½Ð° короткое времÑ.\n" +"ÐÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð½Ð°Ñ ÐºÐ¾Ð¼Ð¿Ð¸Ð»ÑÑ†Ð¸Ñ ÑˆÐµÐ¹Ð´ÐµÑ€Ð¾Ð² должна быть включена в наÑтройках проекта, " +"чтобы Ñтот параметр имел значение." #: editor/editor_node.cpp msgid "Synchronize Scene Changes" @@ -3283,10 +3290,6 @@ msgid "Toggle Fullscreen" msgstr "Включить полноÑкранный режим" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Переключить ÑиÑтемную конÑоль" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Открыть папку данных/наÑтроек редактора" @@ -3518,6 +3521,7 @@ msgid "Load Errors" msgstr "Ошибки загрузки" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Выделение" @@ -3594,7 +3598,6 @@ msgid "Author" msgstr "Ðвтор" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "СтатуÑ" @@ -3838,6 +3841,12 @@ msgstr "Путь к Ñцене:" msgid "Import From Node:" msgstr "Импортировать из узла:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Ошибка" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "Открыть папку, Ñодержащую Ñти шаблоны." @@ -4379,9 +4388,8 @@ msgid "Replace..." msgstr "Заменить..." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Replace in Files" -msgstr "Заменить вÑÑ‘" +msgstr "Заменить в файлах" #: editor/find_in_files.cpp msgid "Find: " @@ -4392,9 +4400,8 @@ msgid "Replace: " msgstr "Заменить: " #: editor/find_in_files.cpp -#, fuzzy msgid "Replace All (NO UNDO)" -msgstr "Заменить вÑÑ‘" +msgstr "Заменить вÑÑ‘ (ÐЕЛЬЗЯ ОТМЕÐИТЬ)" #: editor/find_in_files.cpp msgid "Searching..." @@ -4619,6 +4626,8 @@ msgid "" "Select a resource file in the filesystem or in the inspector to adjust " "import settings." msgstr "" +"Выберите файл реÑурÑа в файловой ÑиÑтеме или в инÑпекторе, чтобы наÑтроить " +"параметры импорта." #: editor/inspector_dock.cpp msgid "Failed to load resource." @@ -4727,6 +4736,7 @@ msgid "Subfolder:" msgstr "Подпапка:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Ðвтор:" @@ -6076,12 +6086,11 @@ msgstr "Тащить: Вращать выделенный узел вокруг #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Alt+Drag: Move selected node." -msgstr "Alt+Тащить: перемещение выбранного узла." +msgstr "Alt+Тащить: Перемещение выбранного узла." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Alt+Drag: Scale selected node." -msgstr "Alt+Тащить: перемещение выбранного узла." +msgstr "Alt+Тащить: МаÑштабирование выбранного узла." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "V: Set selected node's pivot position." @@ -6115,7 +6124,7 @@ msgstr "Режим маÑштабированиÑ" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Shift: Scale proportionally." -msgstr "" +msgstr "Shift: МаÑштабировать пропорционально." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6210,13 +6219,12 @@ msgstr "ПривÑзка к направлÑющим" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock the selected object in place (can't be moved)." -msgstr "ЗафикÑировать выбранный объект." +msgstr "Заблокировать выбранный объект." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected Node(s)" -msgstr "Заблокировать выбранное" +msgstr "Заблокировать выбранный узел(узлы)" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6225,9 +6233,8 @@ msgstr "Разблокировать выбранный объект." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected Node(s)" -msgstr "Разблокировать выделенное" +msgstr "Разблокировать выбранный узел(узлы)" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6236,9 +6243,8 @@ msgstr "Делает потомков объекта невыбираемыми. #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected Node(s)" -msgstr "Сгруппировать выделенное" +msgstr "Сгруппировать выбранный узел(узлы)" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6247,9 +6253,8 @@ msgstr "ВоÑÑтанавливает возможноÑть выбора Ð¿Ð¾Ñ #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected Node(s)" -msgstr "Разгруппировать выделенное" +msgstr "Разгруппировать выбранный узел(узлы)" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Skeleton Options" @@ -6422,6 +6427,7 @@ msgid "Zoom to 1600%" msgstr "МаÑштаб 1600%" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Добавить %s" @@ -7893,9 +7899,8 @@ msgid "Find in Files..." msgstr "Ðайти в файлах..." #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Replace in Files..." -msgstr "Заменить..." +msgstr "Заменить в файлах..." #: editor/plugins/script_text_editor.cpp msgid "Contextual Help" @@ -8424,16 +8429,15 @@ msgstr "Включить Ñвободный вид" #: editor/plugins/spatial_editor_plugin.cpp msgid "Decrease Field of View" -msgstr "" +msgstr "Уменьшить поле зрениÑ" #: editor/plugins/spatial_editor_plugin.cpp msgid "Increase Field of View" -msgstr "" +msgstr "Увеличить поле зрениÑ" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Reset Field of View to Default" -msgstr "СброÑить наÑтройки" +msgstr "СброÑить поле Ð·Ñ€ÐµÐ½Ð¸Ñ Ðº значению по умолчанию" #: editor/plugins/spatial_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9164,22 +9168,19 @@ msgstr "Добавить тип" #: editor/plugins/theme_editor_plugin.cpp msgid "Filter the list of types or create a new custom type:" -msgstr "" +msgstr "Отфильтровать ÑпиÑок типов или Ñоздать новый пользовательÑкий тип:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Available Node-based types:" -msgstr "ДоÑтупные профили:" +msgstr "ДоÑтупные типы на оÑнове Node:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Type name is empty!" -msgstr "ПуÑтое Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°." +msgstr "Ð˜Ð¼Ñ Ñ‚Ð¸Ð¿Ð° пуÑто!" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Are you sure you want to create an empty type?" -msgstr "Ð’Ñ‹ уверены, что хотите открыть более одного проекта?" +msgstr "Ð’Ñ‹ уверены, что хотите Ñоздать пуÑтой тип?" #: editor/plugins/theme_editor_plugin.cpp msgid "Confirm Item Rename" @@ -9802,7 +9803,8 @@ msgid "TileSet" msgstr "Ðабор тайлов" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "Ðет доÑтупных VCS плагинов." #: editor/plugins/version_control_editor_plugin.cpp @@ -9810,16 +9812,56 @@ msgid "Error" msgstr "Ошибка" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "Ðе добавлены файлы Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ð°" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Ðе предоÑтавлено имÑ." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "Коммит" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "Плагин VCS не инициализирован" +#, fuzzy +msgid "Staged Changes" +msgstr "Шейдеров изменено:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Шейдеров изменено:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Коммит" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Поддерево" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Ð’Ñ‹ уверены, что хотите Ñоздать пуÑтой тип?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Применить ÑброÑ" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9830,16 +9872,148 @@ msgid "Initialize" msgstr "Инициализировать" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "ОблаÑть коммита" +#, fuzzy +msgid "Remote Login" +msgstr "Удалить точку" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Переименовать" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Проверить изменениÑ" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "ИзменениÑ" +#, fuzzy +msgid "Discard all changes" +msgstr "Закрыть и Ñохранить изменениÑ?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Сохранение локальных изменений..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Материалов изменено:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Закоммитить изменениÑ" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "Закоммитить изменениÑ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Коммит" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "СовпадениÑ:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Создать новый проект" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Удалить дорожку" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Удаленный" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Создать новый проект" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Удалить Ñлемент" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Удаленный " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Удаленный " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "ИÑÑ…Ð¾Ð´Ð½Ð°Ñ Ð¿Ð¾Ð»Ð¸Ñетка:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9858,28 +10032,23 @@ msgid "Typechange" msgstr "Изменить тип" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "ИндекÑ. выбранные" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "ИндекÑ. вÑÑ‘" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "Закоммитить изменениÑ" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "ПроÑмотр различий в файлах перед коммитом" +#, fuzzy +msgid "View:" +msgstr "Вид" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "Ðет выбранных изменений" +#, fuzzy +msgid "Split" +msgstr "Разделить путь" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "Обнаружение изменений в разнице в файлах" +#, fuzzy +msgid "Unified" +msgstr "Изменён" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12028,6 +12197,11 @@ msgid "" "To save this branch into its own scene, open the original scene, right click " "on this branch, and select \"Save Branch as Scene\"." msgstr "" +"Ðевозможно Ñохранить ветку, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÑвлÑетÑÑ Ð´Ð¾Ñ‡ÐµÑ€Ð½Ð¸Ð¼ Ñлементом уже " +"инÑтанцированной Ñцены.\n" +"Чтобы Ñохранить Ñту ветку в отдельной Ñцене, откройте иÑходную Ñцену, " +"щёлкните правой кнопкой мыши по Ñтой ветке и выберите «Сохранить ветку как " +"Ñцену»." #: editor/scene_tree_dock.cpp msgid "" @@ -12035,6 +12209,10 @@ msgid "" "To save this branch into its own scene, open the original scene, right click " "on this branch, and select \"Save Branch as Scene\"." msgstr "" +"Ðевозможно Ñохранить ветку, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÑвлÑетÑÑ Ñ‡Ð°Ñтью унаÑледованной Ñцены.\n" +"Чтобы Ñохранить Ñту ветку в отдельной Ñцене, откройте иÑходную Ñцену, " +"щёлкните правой кнопкой мыши по Ñтой ветке и выберите «Сохранить ветку как " +"Ñцену»." #: editor/scene_tree_dock.cpp msgid "Save New Scene As..." @@ -12576,6 +12754,7 @@ msgid "Export list to a CSV file" msgstr "ÐкÑпортировать профиль в CSV файл" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Путь к реÑурÑу" @@ -13421,6 +13600,40 @@ msgstr "Обновить график" msgid "Edit Member" msgstr "Редактировать Ñлемент" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Задать выражение" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "анимациÑ" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Входной тип не итерируемый: " @@ -13433,6 +13646,88 @@ msgstr "Итератор Ñтал недейÑтвительным" msgid "Iterator became invalid: " msgstr "Итератор Ñтал недейÑтвительным: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Переименование папки:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Ð’Ñ‹Ñота:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Типы:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Субъект" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Ðа Ñимволе %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Добавить %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Задать %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Закреплено %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Получить %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Ðеверный Ð¸Ð½Ð´ÐµÐºÑ ÑвойÑтва имени." @@ -13449,6 +13744,21 @@ msgstr "Путь не приводит к узлу!" msgid "Invalid index property name '%s' in node %s." msgstr "ÐедопуÑтимое Ð¸Ð¼Ñ ÑвойÑтва-индекÑа «%s» в узле %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Задать %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Функции" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Изменить размер маÑÑива" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": ÐедопуÑтимый аргумент типа: " @@ -13458,6 +13768,10 @@ msgid ": Invalid arguments: " msgstr ": ÐедопуÑтимые аргументы: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet не найден в Ñкрипте: " @@ -13466,6 +13780,66 @@ msgid "VariableSet not found in script: " msgstr "VariableSet не найден в Ñкрипте: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Перезагрузить" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Z-индекÑ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Z-индекÑ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "КонÑтанта" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "КонÑтанта" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "КонÑтанта" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "КонÑтанта" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "Включён GDNative Ñинглтон" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "TimeSeek узел" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Редактирование дерева Ñцены" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Субъект" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Вырезать узлы" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" "ПользовательÑкий узел не имеет метода _step(), не возможно обрабатывать граф." @@ -13478,13 +13852,75 @@ msgstr "" "ÐедопуÑтимое значение, возвращаемое _step(), должно быть целое чиÑло(seq " "out) или Ñтрока (error)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Вызовы" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "КонÑтанты" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "ИÑпользовать локальное проÑтранÑтво" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "ИÑпользовать локальное проÑтранÑтво" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "ДейÑтвие" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "ИÑкать VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Получить %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "ПеремеÑтить кадр" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Кадр физики %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Сигнал" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Сигнал" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Добавить ÑкземплÑÑ€" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14089,13 +14525,15 @@ msgstr "" #: scene/2d/navigation_agent_2d.cpp msgid "The NavigationAgent2D can be used only under a Node2D node." -msgstr "" +msgstr "NavigationAgent2D можно иÑпользовать только под узлом Node2D." #: scene/2d/navigation_obstacle_2d.cpp msgid "" "The NavigationObstacle2D only serves to provide collision avoidance to a " "Node2D object." msgstr "" +"NavigationObstacle2D Ñлужит только Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¾Ñ‚Ð²Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ Ñтолкновений Ñ " +"объектом Node2D." #: scene/2d/navigation_polygon.cpp msgid "" @@ -14121,15 +14559,25 @@ msgstr "" "узла ParallaxBackground." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "GPU-чаÑтицы не поддерживаютÑÑ Ð²Ð¸Ð´ÐµÐ¾Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð¾Ð¼ GLES2.\n" "ВмеÑто Ñтого иÑпользуйте узел CPUParticles2D. Ð”Ð»Ñ Ñтого можно " "воÑпользоватьÑÑ Ð¾Ð¿Ñ†Ð¸ÐµÐ¹ «Преобразовать в CPUParticles»." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14358,7 +14806,7 @@ msgstr "SpotLight Ñ ÑƒÐ³Ð»Ð¾Ð¼ более 90 градуÑов не может Ð #: scene/3d/navigation_agent.cpp msgid "The NavigationAgent can be used only under a spatial node." -msgstr "" +msgstr "NavigationAgent можно иÑпользовать только под узлом Spatial." #: scene/3d/navigation_mesh_instance.cpp msgid "" @@ -14373,6 +14821,8 @@ msgid "" "The NavigationObstacle only serves to provide collision avoidance to a " "spatial object." msgstr "" +"NavigationObstacle Ñлужит только Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¾Ñ‚Ð²Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ Ñтолкновений Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð¼ " +"Spatial." #: scene/3d/occluder.cpp msgid "No shape is set." @@ -14383,10 +14833,11 @@ msgid "Only uniform scales are supported." msgstr "ПоддерживаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ маÑштабирование uniform." #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "GPU-чаÑтицы не поддерживаютÑÑ Ð²Ð¸Ð´ÐµÐ¾Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð¾Ð¼ GLES2.\n" "ВмеÑто Ñтого иÑпользуйте узел CPUParticles. Ð”Ð»Ñ Ñтого можно воÑпользоватьÑÑ " @@ -14394,6 +14845,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "Ðичего не видно, потому что полиÑетки не были назначены на отриÑовку." diff --git a/editor/translations/si.po b/editor/translations/si.po index c1b97c5ebf..f3802b7346 100644 --- a/editor/translations/si.po +++ b/editor/translations/si.po @@ -368,6 +368,7 @@ msgstr "%d සදහ෠ලුහුබදින්නන් à·ƒà·à¶¯à· යච#: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -829,6 +830,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -879,8 +881,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1907,7 +1908,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2024,7 +2024,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2192,7 +2193,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2223,6 +2224,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2920,7 +2923,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3055,10 +3058,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3277,6 +3276,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3353,7 +3353,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3579,6 +3578,12 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "à¶šà·à¶©à¶´à¶" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4438,6 +4443,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6108,6 +6114,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9421,7 +9428,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9429,7 +9436,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9437,7 +9449,35 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9449,7 +9489,36 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "මෙම ලුහුබදින්න෠ඉවà¶à·Š කරන්න." + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Username" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9457,49 +9526,133 @@ msgid "Detect new changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "Stage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +msgid "Unstage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit List" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "යà¶à·”රු මක෠දමන්න" +msgid "Create New Branch" +msgstr "à·ƒà·à¶¯à¶±à·Šà¶±" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +#, fuzzy +msgid "Remove Branch" +msgstr "Anim ලුහුබදින්න෠ඉවà¶à·Š කරන්න" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "à¶à·à¶»à·à¶œà¶à·Š යà¶à·”රු මක෠දමන්න" +msgid "Remotes" +msgstr "මෙම ලුහුබදින්න෠ඉවà¶à·Š කරන්න." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "à·ƒà·à¶¯à¶±à·Šà¶±" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "මෙම ලුහුබදින්න෠ඉවà¶à·Š කරන්න." #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Remote Name" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" +msgid "Remote URL" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "යà¶à·”රු මක෠දමන්න" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Unmerged" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "View:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12025,6 +12178,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12868,6 +13022,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "à·à·Šâ€à¶»à·’à¶:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12880,6 +13067,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12896,6 +13157,19 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "à·à·Šâ€à¶»à·’à¶:" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12905,6 +13179,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12913,6 +13191,57 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "යà¶à·”රු මක෠දමන්න" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "à·ƒà·à¶¯à¶±à·Šà¶±" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "යà¶à·”රු à¶´à·’à¶§à¶´à¶à·Š කරන්න" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12922,12 +13251,65 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "à·à·Šâ€à¶»à·’à¶:" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13489,7 +13871,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13702,7 +14093,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/sk.po b/editor/translations/sk.po index 09e2d1221d..f7acfad23a 100644 --- a/editor/translations/sk.po +++ b/editor/translations/sk.po @@ -366,6 +366,7 @@ msgstr "VytvoriÅ¥ %d NOVÉ track-y a vložiÅ¥ kľúÄe?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -834,6 +835,7 @@ msgstr "PridaÅ¥" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -883,8 +885,7 @@ msgstr "Nedá sa pripojiÅ¥ signál" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1961,7 +1962,6 @@ msgid "New Folder..." msgstr "Nový PrieÄinok..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "ObnoviÅ¥" @@ -2078,7 +2078,8 @@ msgstr "PrieÄinky a Súbory:" msgid "Preview:" msgstr "PredzobraziÅ¥:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Súbor:" @@ -2253,7 +2254,7 @@ msgstr "Metóda" msgid "Signal" msgstr "Signál" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "KonÅ¡tant" @@ -2284,6 +2285,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -3033,8 +3036,9 @@ msgid "Install Android Build Template..." msgstr "InÅ¡talovaÅ¥ Android Build Template..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "OtvoriÅ¥ Project Data Folder" +#, fuzzy +msgid "Open User Data Folder" +msgstr "OtvoriÅ¥ prieÄinok Editor Data" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3192,10 +3196,6 @@ msgid "Toggle Fullscreen" msgstr "Prepnúť na Celú Obrazovku" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Prepnúť Systémovú Konzolu" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "OtvoriÅ¥ Editor Data/Settings Folder" @@ -3429,6 +3429,7 @@ msgid "Load Errors" msgstr "NaÄÃtaÅ¥ Chyby" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "ZvoliÅ¥" @@ -3509,7 +3510,6 @@ msgid "Author" msgstr "Autori" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3750,6 +3750,12 @@ msgstr "Cesta Scény:" msgid "Import From Node:" msgstr "ImportovaÅ¥ Z Node-u:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Chyba!" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4658,6 +4664,7 @@ msgid "Subfolder:" msgstr "Subfolder:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Autor:" @@ -6370,6 +6377,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "PridaÅ¥ %s" @@ -9860,7 +9868,7 @@ msgid "TileSet" msgstr "Súbor:" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9868,16 +9876,54 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy +msgid "No commit message was provided." +msgstr "Nieje uvedené žiadne meno." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy msgid "Commit" msgstr "Komunita" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "ZmeniÅ¥" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "ZmeniÅ¥" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Komunita" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Naozaj chcete odstrániÅ¥ vÅ¡etky pripojenia z tohto signálu?" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9889,7 +9935,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "VymazaÅ¥ Bod" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "PremenovaÅ¥" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9899,52 +9975,144 @@ msgstr "VytvoriÅ¥ adresár" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Changes" +msgid "Discard all changes" +msgstr "Parameter sa Zmenil" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Ukladanie lokálnych zmien..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Parameter sa Zmenil" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" msgstr "ZmeniÅ¥" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +#, fuzzy +msgid "Commit Changes" +msgstr "ZmeniÅ¥" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Komunita" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" +msgid "Branches" +msgstr "Zhody:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "VytvoriÅ¥ Nový %s" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "VymazaÅ¥ Track Animácie" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" msgstr "VÅ¡etky vybrané" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "VymazaÅ¥" +msgid "Create New Remote" +msgstr "VytvoriÅ¥ Nový %s" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Typechange" -msgstr "ZmeniÅ¥" +msgid "Remove Remote" +msgstr "VymazaÅ¥ Predmet" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "ZmeniÅ¥ veľkosÅ¥ výberu" +msgid "Remote Name" +msgstr "Diaľkový " #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +#, fuzzy +msgid "Remote URL" +msgstr "Diaľkový " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" +msgid "Renamed" +msgstr "VÅ¡etky vybrané" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "VymazaÅ¥" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Typechange" msgstr "ZmeniÅ¥" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Unmerged" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +#, fuzzy +msgid "View:" +msgstr "Zobrazenie" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12534,6 +12702,7 @@ msgid "Export list to a CSV file" msgstr "ExportovaÅ¥ Profil" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13407,6 +13576,39 @@ msgstr "" msgid "Edit Member" msgstr "Súbor:" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Animácie" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -13419,6 +13621,84 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Zostávajúce prieÄinky:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Vlastné" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "PridaÅ¥ %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "PridaÅ¥ %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -13435,6 +13715,20 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funkcie" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "ZmeniÅ¥ veľkosÅ¥ Array-u" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -13444,6 +13738,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -13452,6 +13750,64 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Znovu naÄÃtaÅ¥" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "NastaviÅ¥ Rukoväť" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "KonÅ¡tant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "KonÅ¡tant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "KonÅ¡tant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "KonÅ¡tant" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "TimeSeek Node" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Editovanie Stromu Scén" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Vlastné" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "VložiÅ¥" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -13461,15 +13817,75 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Volania" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "KonÅ¡tanty" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "VÅ¡etky vybrané" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp #, fuzzy msgid "Search VisualScript" msgstr "VložiÅ¥" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "VložiÅ¥" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Fyzická SnÃmka %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" msgstr "" +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Signál" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Signál" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "InÅ¡tancie" + #: platform/android/export/export_plugin.cpp msgid "Package name is missing." msgstr "" @@ -14065,7 +14481,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14286,7 +14711,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/sl.po b/editor/translations/sl.po index afb725022c..3c6fc8e571 100644 --- a/editor/translations/sl.po +++ b/editor/translations/sl.po @@ -389,6 +389,7 @@ msgstr "Ustvarim %d NOVO sled in vstavim kljuÄe?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -878,6 +879,7 @@ msgstr "Dodaj" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -930,8 +932,7 @@ msgstr "Povezovanje Signala:" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -2033,7 +2034,6 @@ msgid "New Folder..." msgstr "Nova Mapa..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Osveži" @@ -2158,7 +2158,8 @@ msgstr "Mape & Datoteke:" msgid "Preview:" msgstr "Predogled:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Datoteka:" @@ -2350,7 +2351,7 @@ msgstr "Metode" msgid "Signal" msgstr "Signali" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Konstanta" @@ -2383,6 +2384,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -3142,7 +3145,7 @@ msgstr "" #: editor/editor_node.cpp #, fuzzy -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "Odprem Upravljalnik Projekta?" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3306,11 +3309,6 @@ msgstr "Preklopi na Celozaslonski NaÄin" #: editor/editor_node.cpp #, fuzzy -msgid "Toggle System Console" -msgstr "Preklopi NaÄin" - -#: editor/editor_node.cpp -#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "Nastavitve Urejevalnika" @@ -3543,6 +3541,7 @@ msgid "Load Errors" msgstr "Napake pri Nalaganju" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Izberi" @@ -3624,7 +3623,6 @@ msgid "Author" msgstr "Avtorji" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3860,6 +3858,12 @@ msgstr "Pot Prizora:" msgid "Import From Node:" msgstr "Uvozi iz Gradnika:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Napaka!" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4803,6 +4807,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Avtor:" @@ -6612,6 +6617,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -10147,7 +10153,7 @@ msgid "TileSet" msgstr "Izvozi PloÅ¡Äno Zbirko" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -10155,19 +10161,57 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy +msgid "No commit message was provided." +msgstr "Ime ni doloÄeno." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy msgid "Commit" msgstr "Skupnost" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "Spremebe v Shader" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Spremebe v Shader" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Skupnost" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Ponastavi PoveÄavo/PomanjÅ¡avo" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -10176,7 +10220,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Odstrani toÄko" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Preimenuj" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -10186,53 +10260,145 @@ msgstr "Ustvari Nov %s" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Changes" -msgstr "Spremeni" +msgid "Discard all changes" +msgstr "Spremebe v Shader" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +#, fuzzy +msgid "Stage all changes" +msgstr "Shranjevanje lokalnih sprememb..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Spremebe v Shader" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Usklajuj Spremembe Skript" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Changes" +msgstr "Usklajuj Spremembe Skript" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Skupnost" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "Preimenuj" +msgid "Branches" +msgstr "Zadetki:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "IzbriÅ¡i" +msgid "Create New Branch" +msgstr "Ustvarite Nov Projekt" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Typechange" -msgstr "Spremeni" +msgid "Remove Branch" +msgstr "Odstrani animacijsko sled" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "IzbriÅ¡i Izbrano" +msgid "Remotes" +msgstr "Upravljalnik" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "Zamenjaj Vse" +msgid "Create New Remote" +msgstr "Ustvarite Nov Projekt" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" -msgstr "Usklajuj Spremembe Skript" +msgid "Remove Remote" +msgstr "Odstrani Predlogo" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Upravljalnik " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Upravljalnik " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Modified" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +#, fuzzy +msgid "Renamed" +msgstr "Preimenuj" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "IzbriÅ¡i" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Typechange" +msgstr "Spremeni" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +#, fuzzy +msgid "View:" +msgstr "Pogled" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Split" +msgstr "Uredi krivuljo vozliÅ¡Äa" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12877,6 +13043,7 @@ msgid "Export list to a CSV file" msgstr "Izvozi Projekt" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13760,6 +13927,40 @@ msgstr "Osveži" msgid "Edit Member" msgstr "ÄŒlani" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Trenutna RazliÄica:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Animacija" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Vhodni tip ni spremenljiv: " @@ -13772,6 +13973,84 @@ msgstr "Iterator je bil neveljaven" msgid "Iterator became invalid: " msgstr "Iterator je neveljaven: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Preimenovanje mape:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Osnovni Tip:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Samo" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Veljavni znaki:" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Neveljaven indeks lastnosti imena." @@ -13788,6 +14067,20 @@ msgstr "Pot ne vodi do vozliÅ¡Äa!" msgid "Invalid index property name '%s' in node %s." msgstr "Neveljaven indeks lastnosti imena '%s' v vozliÅ¡Äu %s." +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funkcije:" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "PoveÄaj Niz" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Neveljaven argument od tipa: " @@ -13797,6 +14090,10 @@ msgid ": Invalid arguments: " msgstr ": Neveljavni argumenti: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet ni najden v skripti: " @@ -13805,6 +14102,65 @@ msgid "VariableSet not found in script: " msgstr "VariableSet ni najden v skripti: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Dodaj prednaloženo vozliÅ¡Äe" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "NaÄin PloÅ¡Äe" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "NaÄin PloÅ¡Äe" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Konstanta" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Konstanta" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Konstanta" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Konstanta" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Gradnik ÄŒasovniIskalnik" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Shrani Prizor" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Samo" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Gradnik Prehod" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "VozliÅ¡Äe po meri nima metode _step(); grafa ni mogoÄe obdelati." @@ -13816,15 +14172,77 @@ msgstr "" "Neveljavna vrnitev vrednosti od _step(), mora biti Å¡tevilo (seq out), ali " "string (error)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Klici" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Konstante" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Lokalno prostorski naÄin (%s)" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Lokalno prostorski naÄin (%s)" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Premakni Dejanje" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp #, fuzzy msgid "Search VisualScript" msgstr "Odstrani Gradnik VizualnaSkripta" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "NaÄin Premika" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Fizikalni Okvir %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" msgstr "" +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Signali" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Signali" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Primer" + #: platform/android/export/export_plugin.cpp msgid "Package name is missing." msgstr "" @@ -14426,7 +14844,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14646,7 +15073,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/sq.po b/editor/translations/sq.po index 6669292e99..6e4a0c84fe 100644 --- a/editor/translations/sq.po +++ b/editor/translations/sq.po @@ -362,6 +362,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -819,6 +820,7 @@ msgstr "Shto" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -871,8 +873,7 @@ msgstr "Lidh Sinjalin: " #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1981,7 +1982,6 @@ msgid "New Folder..." msgstr "Folder i Ri..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Rifresko" @@ -2102,7 +2102,8 @@ msgstr "Direktorit & Skedarët:" msgid "Preview:" msgstr "Shikim paraprak:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Skedar:" @@ -2283,7 +2284,7 @@ msgstr "Metodat" msgid "Signal" msgstr "Sinjalet" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2316,6 +2317,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -3080,8 +3083,9 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Hap Folderin e të Dhënave të Projektit" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Hap Folderin e të Dhënave të Editorit" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3243,11 +3247,6 @@ msgid "Toggle Fullscreen" msgstr "Ndrysho Ekranin e Plotë" #: editor/editor_node.cpp -#, fuzzy -msgid "Toggle System Console" -msgstr "Ndrysho metodën e ndarjes" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Hap Folderin e Editorit për të Dhënat/Opsionet" @@ -3476,6 +3475,7 @@ msgid "Load Errors" msgstr "Ngarko Gabimet" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Zgjidh" @@ -3556,7 +3556,6 @@ msgid "Author" msgstr "Autorët" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3797,6 +3796,12 @@ msgstr "Rruga Skenës:" msgid "Import From Node:" msgstr "Importo nga Nyja:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Pasqyrë" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4727,6 +4732,7 @@ msgid "Subfolder:" msgstr "Subfolderi:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Autori:" @@ -6406,6 +6412,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9808,7 +9815,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9816,16 +9823,54 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy +msgid "No commit message was provided." +msgstr "Nuk u dha një emër." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy msgid "Commit" msgstr "Komuniteti" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "Ndrysho" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Ndrysho" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Komuniteti" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "A jeni i sigurt që doni të hiqni të gjitha lidhjet nga ky sinjal?" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9837,7 +9882,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Hiq Artikullin" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Riemërto" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9846,9 +9921,109 @@ msgid "Detect new changes" msgstr "Sinkronizo Nryshimet e Skenës" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Discard all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Changes" -msgstr "Ndrysho" +msgid "Stage all changes" +msgstr "Duke ruajtur ndryshimet lokale..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Duke ruajtur ndryshimet lokale..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Sinkronizo Ndryshimet e Shkrimit" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Changes" +msgstr "Sinkronizo Ndryshimet e Shkrimit" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Komuniteti" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Përputhjet:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Krijo %s të ri" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Hiq Artikullin" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Hiq" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Krijo %s të ri" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Hiq Artikullin" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Emri i Nyjes:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Hiq" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9870,29 +10045,20 @@ msgid "Typechange" msgstr "Ndrysho" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy -msgid "Stage Selected" -msgstr "Zgjidh" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Unmerged" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" -msgstr "Sinkronizo Ndryshimet e Shkrimit" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "" +msgid "View:" +msgstr "Shikim paraprak:" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Split" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12478,6 +12644,7 @@ msgid "Export list to a CSV file" msgstr "Eksporto Projektin" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13334,6 +13501,40 @@ msgstr "Rifresko" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Versioni Aktual:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Animacionet:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -13346,6 +13547,83 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Duke riemërtuar folderin:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Vetja" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Karakteret e lejuar:" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -13362,6 +13640,19 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funksionet:" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -13371,6 +13662,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -13379,6 +13674,62 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Konstantet" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Konstantet" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Konstantet" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Konstantet" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Fshi Nyjen" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Ruaj Skenën" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Vetja" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Dyfisho Nyjet" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -13388,14 +13739,74 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Thërritjet" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Konstantet" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Funksionet:" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" msgstr "" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Lëviz të Preferuarën Lartë" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Hapi i Fizikës %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Sinjalet" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Sinjalet" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instanco" + #: platform/android/export/export_plugin.cpp msgid "Package name is missing." msgstr "" @@ -13975,7 +14386,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14190,7 +14610,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po index fb013c20a9..95723f17e4 100644 --- a/editor/translations/sr_Cyrl.po +++ b/editor/translations/sr_Cyrl.po @@ -401,6 +401,7 @@ msgstr "Ðаправите %d нових трака и убаците кључе #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -921,6 +922,7 @@ msgstr "Додај" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -975,8 +977,7 @@ msgstr "Везујући Ñигнал:" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -2123,7 +2124,6 @@ msgid "New Folder..." msgstr "Ðови директоријум..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "ОÑвежи" @@ -2248,7 +2248,8 @@ msgstr "Директоријуми и датотеке:" msgid "Preview:" msgstr "Преглед:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Датотека:" @@ -2447,7 +2448,7 @@ msgstr "Методе" msgid "Signal" msgstr "Сигнали" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "КонÑтантан" @@ -2481,6 +2482,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp #, fuzzy msgid "Set %s" @@ -3266,8 +3269,8 @@ msgstr "ИнÑталирај Android образце градње" #: editor/editor_node.cpp #, fuzzy -msgid "Open Project Data Folder" -msgstr "Отвори менаџер пројекта?" +msgid "Open User Data Folder" +msgstr "Отвори Фолдер Уређивача Података" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3432,11 +3435,6 @@ msgstr "Укљ./ИÑкљ. режим целог екрана" #: editor/editor_node.cpp #, fuzzy -msgid "Toggle System Console" -msgstr "Промени режим" - -#: editor/editor_node.cpp -#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "ПоÑтавке уредника" @@ -3690,6 +3688,7 @@ msgid "Load Errors" msgstr "Учитај грешке" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Одабери" @@ -3774,7 +3773,6 @@ msgid "Author" msgstr "Ðутори" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp #, fuzzy msgid "Status" @@ -4038,6 +4036,12 @@ msgstr "Пут Ñцене:" msgid "Import From Node:" msgstr "Увоз преко чвора:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Грешка" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -5019,6 +5023,7 @@ msgid "Subfolder:" msgstr "ПодФолдер:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Ðутор:" @@ -6912,6 +6917,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Додај %s" @@ -10685,7 +10691,7 @@ msgstr "TileSet..." #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr " VCS додатци ниÑу доÑтупни." #: editor/plugins/version_control_editor_plugin.cpp @@ -10693,9 +10699,14 @@ msgid "Error" msgstr "Грешка" #: editor/plugins/version_control_editor_plugin.cpp +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "No files added to stage" -msgstr "Ðи један фајл није додат на позорницу" +msgid "No commit message was provided." +msgstr "Име није дато." #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy @@ -10704,8 +10715,41 @@ msgstr "Заједница" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "VCS Addon is not initialized" -msgstr "VCS додатак није иницијализован" +msgid "Staged Changes" +msgstr "Промене шејдера" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Промене шејдера" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Заједница" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Под-Ñтабло" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Да ли Ñигурно желиш да отвориш више одједног пројекта?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "РеÑетуј увеличање" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy @@ -10719,8 +10763,37 @@ msgstr "Велика Ñлова" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Staging area" -msgstr "СценÑки проÑтор" +msgid "Remote Login" +msgstr "Обриши тачку" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Преименуј" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy @@ -10729,8 +10802,112 @@ msgstr "Ðаправи нов" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Changes" -msgstr "Промене шејдера" +msgid "Discard all changes" +msgstr "" +"Затвори и Ñачувај измене?\n" +"\"" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Чувам локалне промене..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Промене материјала" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Синхронизуј промене Ñкриптица" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Changes" +msgstr "Синхронизуј промене Ñкриптица" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Заједница" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Подударање:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Креирај Ðов Пројекат" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Обриши траку анимације" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Удаљени уређај" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Креирај Ðов Пројекат" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Обриши Ñтавку" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Удаљени уређај " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Удаљени уређај " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Изворна мрежа:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy @@ -10753,34 +10930,23 @@ msgid "Typechange" msgstr "Промена типа" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy -msgid "Stage Selected" -msgstr "Увећај одабрано" - -#: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy -msgid "Stage All" -msgstr "Сачувај Ñве" - -#: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy -msgid "Commit Changes" -msgstr "Синхронизуј промене Ñкриптица" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "View file diffs before committing them to the latest version" -msgstr "Погледај фајл разлике пре него га предаш задњој верзији." +msgid "View:" +msgstr "Поглед" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "No file diff is active" -msgstr "Ðи једна фајл разлика није активна" +msgid "Split" +msgstr "Раздели пут" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Detect changes in file diff" -msgstr "Пронађене промене у фајл разликама" +msgid "Unified" +msgstr "Измењено" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -13971,6 +14137,7 @@ msgid "Export list to a CSV file" msgstr "Извези лиÑту у CSV фајл" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp #, fuzzy msgid "Resource Path" msgstr "Путања РеÑурÑа" @@ -14959,6 +15126,40 @@ msgstr "ОÑвежи" msgid "Edit Member" msgstr "Чланови" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "ПоÑтави правоугаони регион" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Ðнимација" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -14971,6 +15172,89 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Преименовање директоријума:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Лево-ДеÑно" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Тип:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Сам" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Код карактера %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Додај %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "ПоÑтави %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Додај %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +#, fuzzy +msgid "Get %s" +msgstr "Повуци %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -14987,6 +15271,21 @@ msgstr "Путања не води ка чвору!" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "ПоÑтави %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Промени векторÑку функцију" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Промени величину низа" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -14996,6 +15295,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -15006,6 +15309,66 @@ msgstr "СкупПроменљивих није нађен у Ñкрипти:" #: modules/visual_script/visual_script_nodes.cpp #, fuzzy +msgid "Preload" +msgstr "ОÑвежи" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Режим инÑпекције" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Режим инÑпекције" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "КонÑтантан" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "КонÑтантан" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "КонÑтантан" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "КонÑтантан" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "Омогућен GDNative Singleton" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "TimeSeek чвор" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Едитовање Стабла Сцене" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Сам" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Ðаправи чвор" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy msgid "Custom node has no _step() method, can't process graph." msgstr "Произвољни чвор нема _step() методу, граф не моће бити обрађен." @@ -15018,15 +15381,76 @@ msgstr "" "Ðеважећа повратна вредноÑÑ‚ од _step(), мора бити интиџер (seq out), или " "Ñтринг (грешка)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Позиви цртања" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Ðепроменљиве" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Режим Ñкалирања (R)" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Режим Ñкалирања (R)" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Радња" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp #, fuzzy msgid "Search VisualScript" msgstr "Потражи VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp #, fuzzy -msgid "Get %s" -msgstr "Повуци %s" +msgid "Next Frame" +msgstr "Ðалепи оквир" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Слика физике %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Сигнали" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Сигнали" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Додај инÑтанцу" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -15711,12 +16135,21 @@ msgstr "ПаралакÑСлој чвор Ñамо ради кад је дете msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "ЧеÑтице базиране на графичкој ниÑу подржане од Ñтране GLES2 видео " "управљача.\n" "УмеÑто тога кориÑти ПроцеÑорЧеÑтице2Д чвор." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp #, fuzzy msgid "" @@ -16003,10 +16436,18 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "GPU-базиране чеÑтице ниÑу подржане од Ñтране GLES2 видео управљача." #: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp #, fuzzy msgid "" "Nothing is visible because meshes have not been assigned to draw passes." diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po index 9a5bbeb2ec..a3db7ebbae 100644 --- a/editor/translations/sr_Latn.po +++ b/editor/translations/sr_Latn.po @@ -376,6 +376,7 @@ msgstr "Napravi %d novih kanala i dodaj kljuÄeve?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -837,6 +838,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -886,8 +888,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1916,7 +1917,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2035,7 +2035,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2205,7 +2206,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Kontanta" @@ -2236,6 +2237,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2934,7 +2937,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3070,10 +3073,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3293,6 +3292,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3370,7 +3370,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3598,6 +3597,12 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Ogledalo" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4457,6 +4462,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6141,6 +6147,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9515,7 +9522,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9523,7 +9530,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9532,7 +9544,36 @@ msgid "Commit" msgstr "Zajednica" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Zajednica" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9544,7 +9585,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "ObriÅ¡i Selekciju" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Animacija Preimenuj Kanal" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9553,50 +9624,139 @@ msgid "Detect new changes" msgstr "Napravi" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +#, fuzzy +msgid "Stage all changes" +msgstr "Napravi" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "Animacija Preimenuj Kanal" +msgid "Commit Message" +msgstr "Zajednica" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "Animacija ObriÅ¡i KljuÄeve" +msgid "Commit List" +msgstr "Zajednica" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "Skaliraj Selekciju" +msgid "Create New Branch" +msgstr "Napravi" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Odstrani Kanal Animacije" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Branch Name" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" +#, fuzzy +msgid "Remotes" +msgstr "ObriÅ¡i Selekciju" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Napravi" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "ObriÅ¡i Selekciju" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "ObriÅ¡i Selekciju" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote URL" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Force Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "Animacija Preimenuj Kanal" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "Animacija ObriÅ¡i KljuÄeve" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Split" +msgstr "Izmjeni Krivulju ÄŒvora" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12135,6 +12295,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12985,6 +13146,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Optimizuj Animaciju" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12997,6 +13191,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -13013,6 +13281,19 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funkcije:" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -13022,6 +13303,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -13030,6 +13315,61 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Kontanta" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Kontanta" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Kontanta" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Kontanta" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Animacija ObriÅ¡i KljuÄeve" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Napravi" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Animacija Uduplaj KljuÄeve" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -13039,12 +13379,66 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Kontanta" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Sve sekcije" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13606,7 +14000,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13819,7 +14222,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/sv.po b/editor/translations/sv.po index b8c190d92a..87d39fb5ee 100644 --- a/editor/translations/sv.po +++ b/editor/translations/sv.po @@ -379,6 +379,7 @@ msgstr "Skapa %d NYA spÃ¥r och infoga nycklar?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -849,6 +850,7 @@ msgstr "Lägg till" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -900,8 +902,7 @@ msgstr "Kan ej ansluta signal" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1978,7 +1979,6 @@ msgid "New Folder..." msgstr "Ny Mapp..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Uppdatera" @@ -2095,7 +2095,8 @@ msgstr "Kataloger & Filer:" msgid "Preview:" msgstr "Förhandsvisning:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Fil:" @@ -2288,7 +2289,7 @@ msgstr "Metoder" msgid "Signal" msgstr "Signaler" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Konstant" @@ -2321,6 +2322,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -3092,7 +3095,8 @@ msgid "Install Android Build Template..." msgstr "Installera Android Build Template..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" +#, fuzzy +msgid "Open User Data Folder" msgstr "Öppna Projekthanteraren" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3230,11 +3234,6 @@ msgid "Toggle Fullscreen" msgstr "Växla Fullskärm" #: editor/editor_node.cpp -#, fuzzy -msgid "Toggle System Console" -msgstr "Växla Läge" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3463,6 +3462,7 @@ msgid "Load Errors" msgstr "Ladda Felmeddelanden" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Välj" @@ -3544,7 +3544,6 @@ msgid "Author" msgstr "Författare" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Status" @@ -3776,6 +3775,12 @@ msgstr "Scen Filsökväg:" msgid "Import From Node:" msgstr "Importera FrÃ¥n Node:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Fel" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4713,6 +4718,7 @@ msgid "Subfolder:" msgstr "Undermapp:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Författare:" @@ -6439,6 +6445,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Lägg till %s" @@ -9951,7 +9958,7 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9959,19 +9966,58 @@ msgid "Error" msgstr "Fel" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy +msgid "No commit message was provided." +msgstr "Inget namn har angetts." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy msgid "Commit" msgstr "Community" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "Shader Ändringar:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Shader Ändringar:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Community" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Är du säker att du vill ta bort alla kopplingar frÃ¥n denna signal?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Ã…terställ Zoom" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -9980,7 +10026,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Flytta Ner" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Byt namn" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9989,53 +10065,146 @@ msgid "Detect new changes" msgstr "Skapa Ny" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Ändringar" +#, fuzzy +msgid "Discard all changes" +msgstr "Stäng och spara ändringar?" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +#, fuzzy +msgid "Stage all changes" +msgstr "Lagrar lokala ändringar..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Materialförändringar:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "Synkronisera Skript-ändringar" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Changes" +msgstr "Synkronisera Skript-ändringar" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Community" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "Byt namn" +msgid "Branches" +msgstr "Matchar:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" +msgid "Create New Branch" +msgstr "Skapa Nytt Projekt" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Ta bort Anim spÃ¥r" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" msgstr "Ta bort" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Typechange" -msgstr "Ändra" +msgid "Create New Remote" +msgstr "Skapa Nytt Projekt" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "Skala urval" +msgid "Remove Remote" +msgstr "Ta Bort Mall" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "Spara Alla" +msgid "Remote Name" +msgstr "Node Namn:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" -msgstr "Synkronisera Skript-ändringar" +msgid "Remote URL" +msgstr "Ta bort" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Fetch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Pull" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "Byt namn" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "Ta bort" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Typechange" +msgstr "Ändra" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "View:" +msgstr "Visa" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Split" +msgstr "Redigera Nodkurva" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12636,6 +12805,7 @@ msgid "Export list to a CSV file" msgstr "Exportera Projekt" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13496,6 +13666,40 @@ msgstr "Uppdatera" msgid "Edit Member" msgstr "Medlemmar" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Ställ in uttryck" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animering" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -13508,6 +13712,87 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Byter namn pÃ¥ mappen:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Växla" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Typ:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Själv" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Vid tecken %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Lägg till %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Lägg till %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -13524,6 +13809,20 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Funktioner" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Ändra storlek pÃ¥ Array" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -13533,6 +13832,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet hittades inte i Skript: " @@ -13541,6 +13844,65 @@ msgid "VariableSet not found in script: " msgstr "VariableSet hittades inte i Skript: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Ladda om" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Automatisk Indentering" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Automatisk Indentering" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Ny Scenrot" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Scenträd Redigering" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Själv" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Klipp ut Noder" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -13550,15 +13912,76 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Begränsningar" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Gör Patch" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Gör Patch" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Ã…tgärd" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp #, fuzzy msgid "Search VisualScript" msgstr "Fäst Skript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Flytta Nod(er)" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Fysik Bildruta %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" msgstr "" +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Signaler" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Signaler" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instans" + #: platform/android/export/export_plugin.cpp msgid "Package name is missing." msgstr "" @@ -14150,7 +14573,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14377,7 +14809,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/ta.po b/editor/translations/ta.po index b7c8cf73e3..4de4a497eb 100644 --- a/editor/translations/ta.po +++ b/editor/translations/ta.po @@ -375,6 +375,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -832,6 +833,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -881,8 +883,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1910,7 +1911,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2027,7 +2027,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2195,7 +2196,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2225,6 +2226,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2922,7 +2925,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3058,10 +3061,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3279,6 +3278,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3356,7 +3356,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3583,6 +3582,11 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +msgid "%s Error" +msgstr "" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4442,6 +4446,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6109,6 +6114,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9425,7 +9431,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9433,7 +9439,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9441,7 +9452,35 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9453,7 +9492,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "அசைவூடà¯à®Ÿà¯ பாதையை நீகà¯à®•à¯" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "அசைவூடà¯à®Ÿà¯ பாதைகà¯à®•௠மறà¯à®ªà¯†à®¯à®°à¯ இடà¯" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9461,50 +9530,133 @@ msgid "Detect new changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "Stage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit List" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Branch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "அசைவூடà¯à®Ÿà¯ பாதைகà¯à®•௠மறà¯à®ªà¯†à®¯à®°à¯ இடà¯" +msgid "Remove Branch" +msgstr "அசைவூடà¯à®Ÿà¯ பாதையை நீகà¯à®•à¯" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•ளà¯" +msgid "Remotes" +msgstr "அசைவூடà¯à®Ÿà¯ பாதையை நீகà¯à®•à¯" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Create New Remote" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•ளà¯" +msgid "Remove Remote" +msgstr "அசைவூடà¯à®Ÿà¯ பாதையை நீகà¯à®•à¯" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Remote Name" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" +msgid "Remote URL" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Fetch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Pull" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "அசைவூடà¯à®Ÿà¯ பாதைகà¯à®•௠மறà¯à®ªà¯†à®¯à®°à¯ இடà¯" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•ளà¯" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Split" +msgstr "கண௠வளைவை[Node Curve] திரà¯à®¤à¯à®¤à¯" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12030,6 +12182,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12873,6 +13026,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "மாறà¯à®±à®™à¯à®•ளை இதறà¯à®•௠அமை:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12885,6 +13071,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12901,6 +13161,19 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•ளà¯" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12910,6 +13183,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12918,6 +13195,56 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•ளà¯" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Tree" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "அசைவூடà¯à®Ÿà¯ போலிபசà¯à®šà®¾à®µà®¿à®•ளà¯" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12927,12 +13254,66 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•ளà¯" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "சேர௠மà¯à®•à¯à®•ியபà¯à®ªà¯à®³à¯à®³à®¿à®¯à¯ˆ நகரà¯à®¤à¯à®¤à¯" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13494,7 +13875,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13707,7 +14097,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/te.po b/editor/translations/te.po index 448aa534eb..8c86f7f276 100644 --- a/editor/translations/te.po +++ b/editor/translations/te.po @@ -358,6 +358,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -807,6 +808,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -856,8 +858,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1880,7 +1881,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -1997,7 +1997,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2165,7 +2166,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2195,6 +2196,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2888,7 +2891,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3023,10 +3026,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3244,6 +3243,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3320,7 +3320,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3545,6 +3544,11 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +msgid "%s Error" +msgstr "" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4400,6 +4404,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6043,6 +6048,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9325,7 +9331,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9333,7 +9339,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9342,7 +9353,36 @@ msgid "Commit" msgstr "సంఘం" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "సంఘం" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9354,55 +9394,165 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +msgid "Remote Login" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect new changes" +msgid "Username" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Password" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "SSH Public Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +msgid "Select SSH public key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" +msgid "SSH Private Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect new changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +msgid "Stage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Unstage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "సంఘం" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +#, fuzzy +msgid "Commit List" +msgstr "సంఘం" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Branch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remove Branch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remotes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remove Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote URL" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Modified" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -11911,6 +12061,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12739,6 +12890,38 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Condition" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12751,6 +12934,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12767,6 +13024,18 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Function" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12776,6 +13045,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12784,6 +13057,58 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "à°¸à±à°¥à°¿à°°à°¾à°‚కాలà±" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "à°¸à±à°¥à°¿à°°à°¾à°‚కాలà±" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "à°¸à±à°¥à°¿à°°à°¾à°‚కాలà±" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "à°¸à±à°¥à°¿à°°à°¾à°‚కాలà±" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Node" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Tree" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "CustomNode" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12793,12 +13118,66 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "à°¸à±à°¥à°¿à°°à°¾à°‚కాలà±" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Action %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "సంకేతాలà±" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13360,7 +13739,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13573,7 +13961,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/th.po b/editor/translations/th.po index acb8f8cbf3..4f1443f031 100644 --- a/editor/translations/th.po +++ b/editor/translations/th.po @@ -374,6 +374,7 @@ msgstr "เพิ่มà¹à¸—ร็à¸à¹ƒà¸«à¸¡à¹ˆ %d à¹à¸—ร็à¸à¹à¸¥à¸°à¹ #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -838,6 +839,7 @@ msgstr "เพิ่ม" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -887,8 +889,7 @@ msgstr "ไม่สามารถเชื่à¸à¸¡à¸•่à¸à¸ªà¸±à¸à¸à¸²à¸“ #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1959,7 +1960,6 @@ msgid "New Folder..." msgstr "สร้างโฟลเดà¸à¸£à¹Œ..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "รีเฟรช" @@ -2076,7 +2076,8 @@ msgstr "ไฟล์à¹à¸¥à¸°à¹‚ฟลเดà¸à¸£à¹Œ:" msgid "Preview:" msgstr "ตัวà¸à¸¢à¹ˆà¸²à¸‡:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "ไฟล์:" @@ -2249,7 +2250,7 @@ msgstr "เมธà¸à¸”" msgid "Signal" msgstr "สัà¸à¸à¸²à¸“" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "คงที่" @@ -2280,6 +2281,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "ตั้ง %s" @@ -3012,8 +3015,9 @@ msgid "Install Android Build Template..." msgstr "ติดตั้งเทมเพลตà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¸‚à¸à¸‡à¹à¸à¸™à¸”รà¸à¸¢à¸”์" #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "เปิดโฟลเดà¸à¸£à¹Œà¸‚้à¸à¸¡à¸¹à¸¥à¹‚ปรเจà¸à¸•์" +#, fuzzy +msgid "Open User Data Folder" +msgstr "เปิดโฟลเดà¸à¸£à¹Œà¸‚à¸à¸‡à¸•ัวà¹à¸à¹‰à¹„ข" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3164,10 +3168,6 @@ msgid "Toggle Fullscreen" msgstr "เปิด/ปิด โหมดเต็มหน้าจà¸" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "เปิด/ปิด คà¸à¸™à¹‚ซลระบบ" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "เปิดโฟลเดà¸à¸£à¹Œà¸‚้à¸à¸¡à¸¹à¸¥/ตั้งค่าขà¸à¸‡à¸•ัวà¹à¸à¹‰à¹„ข" @@ -3400,6 +3400,7 @@ msgid "Load Errors" msgstr "โหลดผิดพลาด" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "เลืà¸à¸" @@ -3480,7 +3481,6 @@ msgid "Author" msgstr "ทีมงาน" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "สถานะ" @@ -3716,6 +3716,12 @@ msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่à¸à¸¢à¸¹à¹ˆà¸‰à¸²à¸:" msgid "Import From Node:" msgstr "นำเข้าจาà¸à¹‚หนด:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "ผิดพลาด" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4617,6 +4623,7 @@ msgid "Subfolder:" msgstr "โฟลเดà¸à¸£à¹Œà¸¢à¹ˆà¸à¸¢:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "ผู้สร้าง:" @@ -6301,6 +6308,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "เพิ่ม %s" @@ -9752,7 +9760,8 @@ msgid "TileSet" msgstr "ไทล์เซต" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "ไม่พบส่วนเสริม VCS" #: editor/plugins/version_control_editor_plugin.cpp @@ -9760,16 +9769,56 @@ msgid "Error" msgstr "ผิดพลาด" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "ไม่มีไฟล์เพิ่มไฟยัง stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "ไม่ได้ระบุชื่à¸" #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "Commit" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "ส่วนเสริม VCS ยังไม่ได้ใช้งาน" +#, fuzzy +msgid "Staged Changes" +msgstr "จำนวนครั้งที่เปลี่ยน Shader" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "จำนวนครั้งที่เปลี่ยน Shader" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Commit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "ผังย่à¸à¸¢" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "ยืนยันà¸à¸²à¸£à¹€à¸›à¸´à¸”โปรเจà¸à¸•์มาà¸à¸à¸§à¹ˆà¸² 1 โปรเจà¸à¸•์?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "นำà¸à¸²à¸£à¸£à¸µà¹€à¸‹à¹‡à¸•ไปใช้" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9780,16 +9829,148 @@ msgid "Initialize" msgstr "เริ่มต้น" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "Stage พื้นที่" +#, fuzzy +msgid "Remote Login" +msgstr "ลบจุด" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "เปลี่ยนชื่à¸" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "พบà¸à¸²à¸£à¹à¸à¹‰à¹„ขใหม่" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "เปลี่ยน" +#, fuzzy +msgid "Discard all changes" +msgstr "ปิดà¹à¸¥à¸°à¸šà¸±à¸™à¸—ึà¸?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "เà¸à¹‡à¸šà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸ ายใน..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "จำนวนครั้งที่เปลี่ยนวัสดุ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡ commit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡ commit" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Commit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "พบ:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "สร้างโปรเจà¸à¸•์ใหม่" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "ลบà¹à¸—ร็à¸à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "ระยะไà¸à¸¥" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "สร้างโปรเจà¸à¸•์ใหม่" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "ลบไà¸à¹€à¸—ม" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "ควบคุม " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "ควบคุม " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Mesh ต้นฉบับ:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9808,28 +9989,23 @@ msgid "Typechange" msgstr "เปลี่ยนชนิด" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "เลืà¸à¸ stage" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "Stage ทั้งหมด" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡ commit" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "ดู diffs ขà¸à¸‡à¹„ฟล์à¸à¹ˆà¸à¸™à¸—ี่จะ commit ไปยังเวà¸à¸£à¹Œà¸Šà¸±à¸™à¸¥à¹ˆà¸²à¸ªà¸¸à¸”" +#, fuzzy +msgid "View:" +msgstr "มุมมà¸à¸‡" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "ไม่มีà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¹„ฟล์ diff" +#, fuzzy +msgid "Split" +msgstr "ตัดเส้น" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "ตรวจสà¸à¸šà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¹ƒà¸™ file diff" +#, fuzzy +msgid "Unified" +msgstr "à¹à¸à¹‰à¹„ขà¹à¸¥à¹‰à¸§" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12466,6 +12642,7 @@ msgid "Export list to a CSV file" msgstr "ส่งà¸à¸à¸à¸£à¸²à¸¢à¸à¸²à¸£à¹€à¸›à¹‡à¸™à¹„ฟล์ CSV" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸£à¸µà¸‹à¸à¸£à¹Œà¸ª" @@ -13308,6 +13485,40 @@ msgstr "รีเฟรชà¸à¸£à¸²à¸Ÿ" msgid "Edit Member" msgstr "à¹à¸à¹‰à¹„ขสมาชิà¸" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "ตั้งค่านิพจน์" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "ตัวà¹à¸›à¸£à¸›à¸£à¸°à¹€à¸ ทนี้ใช้วนซ้ำไม่ได้: " @@ -13320,6 +13531,88 @@ msgstr "ตัววนซ้ำใช้ไม่ได้à¸à¸µà¸à¸•่à¸à¹„ msgid "Iterator became invalid: " msgstr "ตัววนซ้ำใช้ไม่ได้: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "เปลี่ยนชื่à¸à¹‚ฟลเดà¸à¸£à¹Œ:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Pitch" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "ประเภท:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "ตัวเà¸à¸‡" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "ตัวà¸à¸±à¸à¸©à¸£à¸—ี่ใช้ได้ %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "เพิ่ม %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "ตั้ง %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "เพิ่ม %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "รับ %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "ไม่พบคุณสมบัติ" @@ -13336,6 +13629,21 @@ msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่ระบุไม่ได้นำไป msgid "Invalid index property name '%s' in node %s." msgstr "ไม่พบคุณสมบัติ '%s' ในโหนด %s" +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "ตั้ง %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "ปรับขนาดà¸à¸²à¸£à¹Œà¹€à¸£à¸¢à¹Œ" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": ประเภทตัวà¹à¸›à¸£à¹„ม่ถูà¸à¸•้à¸à¸‡: " @@ -13345,6 +13653,10 @@ msgid ": Invalid arguments: " msgstr ": ตัวà¹à¸›à¸£à¹„ม่ถูà¸à¸•้à¸à¸‡: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "ไม่พบ VariableGet ในสคริปต์: " @@ -13353,6 +13665,66 @@ msgid "VariableSet not found in script: " msgstr "ไม่พบ VariableSet ในสคริปต์: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "โหลดใหม่" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Z Index" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Z Index" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "คงที่" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "คงที่" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "คงที่" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "คงที่" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "เปิดà¸à¸²à¸£à¸—ำงานซิงเà¸à¸´à¸¥à¸•ัน GDNative" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "โหนด TimeSeek" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "à¹à¸à¹‰à¹„ขผังฉาà¸" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "ตัวเà¸à¸‡" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "ตัดโหนด" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "โหนดà¸à¸³à¸«à¸™à¸”เà¸à¸‡à¹„ม่มีเมท็à¸à¸” _step() ไม่สามารถประมวลผลà¸à¸£à¸²à¸Ÿà¹„ด้" @@ -13362,13 +13734,75 @@ msgid "" "(error)." msgstr "ค่าคืนจาภ_step() ผิดพลาด ต้à¸à¸‡à¹€à¸›à¹‡à¸™à¸ˆà¸³à¸™à¸§à¸™à¹€à¸•็ม (ลำดับ) หรืà¸à¸ªà¸•ริง (ข้à¸à¸œà¸´à¸”พลาด)" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "จำนวนครั้ง" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "ค่าคงที่" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "ใช้พื้นที่ภายใน" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "ใช้พื้นที่ภายใน" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "à¸à¸²à¸£à¸à¸£à¸°à¸—ำ" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "ค้นหาโหนด VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "รับ %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "เลื่à¸à¸™à¹€à¸Ÿà¸£à¸¡" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "% ขà¸à¸‡à¹€à¸Ÿà¸£à¸¡à¸Ÿà¸´à¸ªà¸´à¸à¸ªà¹Œ" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "สัà¸à¸à¸²à¸“" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "สัà¸à¸à¸²à¸“" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "à¸à¸´à¸™à¸ªà¹à¸•นซ์" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -13982,14 +14416,24 @@ msgid "" msgstr "ParallaxLayer จะทำงานได้ต้à¸à¸‡à¹€à¸›à¹‡à¸™à¹‚หนดลูà¸à¸‚à¸à¸‡à¹‚หนด ParallaxBackground" #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "ไดรเวà¸à¸£à¹Œ GLES2 ไม่สนับสนุนระบบพาร์ติเคิลโดยใช้à¸à¸²à¸£à¹Œà¸”จà¸\n" "ใช้โหนด CPUParticles2D à¹à¸—น คุณสามารถใช้ตัวเลืà¸à¸ \"à¹à¸›à¸¥à¸‡à¹€à¸›à¹‡à¸™ CPUParticles\" ได้" +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14217,16 +14661,25 @@ msgid "Only uniform scales are supported." msgstr "" #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "ไดรเวà¸à¸£à¹Œ GLES2 ไม่สนับสนุนระบบพาร์ติเคิลโดยใช้à¸à¸²à¸£à¹Œà¸”จà¸\n" "ใช้โหนด CPUParticles à¹à¸—น คุณสามารถใช้ตัวเลืà¸à¸ \"à¹à¸›à¸¥à¸‡à¹€à¸›à¹‡à¸™ CPUParticles\" ได้" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "ไม่มีà¸à¸²à¸£à¹à¸ªà¸”งผลเนื่à¸à¸‡à¸ˆà¸²à¸à¹„ม่ได้à¸à¸³à¸«à¸™à¸” mesh ใน draw pass" diff --git a/editor/translations/tl.po b/editor/translations/tl.po index 3e48f9d911..ecf0928c49 100644 --- a/editor/translations/tl.po +++ b/editor/translations/tl.po @@ -362,6 +362,7 @@ msgstr "Gumawa ng %d BAGONG mga track at maglagay ng mga key?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -830,6 +831,7 @@ msgstr "Maglagay" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -881,8 +883,7 @@ msgstr "Hindi maikabit ang hudyat" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1920,7 +1921,6 @@ msgid "New Folder..." msgstr "Bagong Folder..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "I-refresh" @@ -2037,7 +2037,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "File:" @@ -2210,7 +2211,7 @@ msgstr "Method" msgid "Signal" msgstr "Hudyat" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Constant" @@ -2241,6 +2242,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Itakda ang %s" @@ -2944,7 +2947,8 @@ msgid "Install Android Build Template..." msgstr "Ikabit ang Android Build Template..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" +#, fuzzy +msgid "Open User Data Folder" msgstr "Buksan ang Folder ng Datos ng Proyekto" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3080,10 +3084,6 @@ msgid "Toggle Fullscreen" msgstr "Pumalit sa Buong Tabing" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3300,6 +3300,7 @@ msgid "Load Errors" msgstr "Mga Kabugian Sa Pagloload" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Magpili" @@ -3376,7 +3377,6 @@ msgid "Author" msgstr "May-akda" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Kalagayan" @@ -3601,6 +3601,12 @@ msgstr "Kinalalagyan ng Eksena:" msgid "Import From Node:" msgstr "Magangkat mula sa Node:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Nabigo" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4458,6 +4464,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6113,6 +6120,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9402,7 +9410,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9410,15 +9418,53 @@ msgid "Error" msgstr "Nabigo" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Walang pangalang binagay." + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "Magcommit" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "Mga Pagbabago" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Mga Pagbabago" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Magcommit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Gusto mo bang alisin lahat ng pagkakabit sa hudyat na ito?" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9430,7 +9476,37 @@ msgid "Initialize" msgstr "Simulan" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "Alisin ang Hudyat" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Inibang Pangalan" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9438,8 +9514,107 @@ msgid "Detect new changes" msgstr "Pansinin ang anumang pagbabago" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Mga Pagbabago" +msgid "Discard all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Pansinin ang anumang pagbabago" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "I-commit Lahat ng Pagbabago" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "I-commit Lahat ng Pagbabago" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "Magcommit" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Mga Tugma:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Gumawa ng Bagong %s" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Alisin ang Anim Track" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Alisin" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Gumawa ng Bagong %s" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Alisin ang Gamit" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Pangalan ng Node:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Alisin" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9458,28 +9633,22 @@ msgid "Typechange" msgstr "Pagbabago ng uri" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +msgid "Unmerged" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "I-commit Lahat ng Pagbabago" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "" +#, fuzzy +msgid "View:" +msgstr "Tingnan" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Split" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "" +#, fuzzy +msgid "Unified" +msgstr "Binago" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -11989,6 +12158,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12817,6 +12987,40 @@ msgstr "" msgid "Edit Member" msgstr "Ayusin ang Kasapi" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Ibahin ang Ekspresyon" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animation" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12829,6 +13033,83 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Mga Uri:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Sarili" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Itakda ang %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12845,6 +13126,21 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "Di-wastong index ng pangalan ng katangian na '%s' sa node %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Itakda ang %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Mga Punsyon:" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Ibahin Ang Sukat ng Array" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12854,6 +13150,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12862,6 +13162,64 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Index ng Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Index ng Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Constant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Constant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Constant" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Constant" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Panibagong Eksena" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Panibagong Eksena" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Sarili" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Kopyahin ang mga Node" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12871,12 +13229,70 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Mga Tawag" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Mga Konstant" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Mga Punsyon:" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Maghanap ng VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Susunod na tab" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Hudyat" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Hudyat" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13440,7 +13856,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13653,7 +14078,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/tr.po b/editor/translations/tr.po index 221e209621..f318616c3e 100644 --- a/editor/translations/tr.po +++ b/editor/translations/tr.po @@ -421,6 +421,7 @@ msgstr "%d YENİ izler oluÅŸtur ve anahtarlar gir?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -889,6 +890,7 @@ msgstr "Ekle" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -938,8 +940,7 @@ msgstr "Sinyale baÄŸlanamıyor" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -2005,7 +2006,6 @@ msgid "New Folder..." msgstr "Yeni Klasör..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Yenile" @@ -2122,7 +2122,8 @@ msgstr "Dizinler & Dosyalar:" msgid "Preview:" msgstr "Önizleme:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Dosya:" @@ -2298,7 +2299,7 @@ msgstr "Metot" msgid "Signal" msgstr "Sinyal" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Sabit" @@ -2329,6 +2330,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Ayarla %s" @@ -3084,8 +3087,9 @@ msgid "Install Android Build Template..." msgstr "Android İnÅŸa Åžablonunu Yükle ..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Proje Verileri Klasörünü Aç" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Düzenleyici Verileri Klasörünü Aç" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3244,10 +3248,6 @@ msgid "Toggle Fullscreen" msgstr "Tam Ekranı Aç/Kapat" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Sistem Terminalini Aç / Kapat" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Düzenleyici Verileri/Ayarları Klasörünü Aç" @@ -3478,6 +3478,7 @@ msgid "Load Errors" msgstr "Hataları Yükle" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Seç" @@ -3554,7 +3555,6 @@ msgid "Author" msgstr "Yaratıcı" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Durum" @@ -3799,6 +3799,12 @@ msgstr "Sahne Yolu:" msgid "Import From Node:" msgstr "Düğümden İçe Aktar:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Hata" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "Bu ÅŸablonları içeren klasörü açın." @@ -4692,6 +4698,7 @@ msgid "Subfolder:" msgstr "Alt Klasör:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Yazar:" @@ -6386,6 +6393,7 @@ msgid "Zoom to 1600%" msgstr "%1600'e yakınlaÅŸtır" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Ekle %s" @@ -9759,7 +9767,8 @@ msgid "TileSet" msgstr "DöşemeTakımı" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "Hiçbir VCS eklentisi mevcut deÄŸil." #: editor/plugins/version_control_editor_plugin.cpp @@ -9767,16 +9776,56 @@ msgid "Error" msgstr "Hata" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "Sahneye hiç dosya eklenmedi" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "SaÄŸlanan isim yok." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "İşle" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "VCS eklentileri etkinleÅŸtirilmedi" +#, fuzzy +msgid "Staged Changes" +msgstr "Gölgelendirici DeÄŸiÅŸiklikleri:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Gölgelendirici DeÄŸiÅŸiklikleri:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "İşle" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "AltaÄŸaç" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Birden fazla proje açmakta kararlı mısınız?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Sıfırla" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9787,16 +9836,148 @@ msgid "Initialize" msgstr "EtkinleÅŸtir" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "Sahne Öncesi" +#, fuzzy +msgid "Remote Login" +msgstr "Noktayı kaldır" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Yeniden Adlandır" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Yeni deÄŸiÅŸiklikleri tespit et" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "DeÄŸiÅŸiklikler" +#, fuzzy +msgid "Discard all changes" +msgstr "Kapa ve deÄŸiÅŸiklikleri kaydet?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Yerel deÄŸiÅŸiklikler kayıt ediliyor..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Materyal DeÄŸiÅŸiklikleri:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "DeÄŸiÅŸiklikleri İşle" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "DeÄŸiÅŸiklikleri İşle" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "İşle" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "EÅŸleÅŸmeler:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Yeni Proje OluÅŸtur" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Animasyon İzini Kaldır" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Uzak" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Yeni Proje OluÅŸtur" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Öğeyi Kaldır" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Uzak " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Uzak " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Kaynak Örüntü:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9815,28 +9996,23 @@ msgid "Typechange" msgstr "TürdeÄŸiÅŸtir" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "Sahne Seçildi" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "Tümünü Sahneye Al" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "DeÄŸiÅŸiklikleri İşle" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "Son versiyona iÅŸlemeden önce dosya diff 'lerini incele" +#, fuzzy +msgid "View:" +msgstr "Görüş" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "Dosya diff etkin deÄŸil" +#, fuzzy +msgid "Split" +msgstr "Yolu Ayır" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "Diff dosyasındaki deÄŸiÅŸiklikleri tespit et" +#, fuzzy +msgid "Unified" +msgstr "DeÄŸiÅŸti" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12522,6 +12698,7 @@ msgid "Export list to a CSV file" msgstr "Listeyi CSV dosyasına aktar" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "Kaynak Yolu" @@ -13365,6 +13542,40 @@ msgstr "GrafiÄŸi Yenile" msgid "Edit Member" msgstr "Üye Düzenle" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "İfadeyi ayarla" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "animasyon" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Girdi türü yinelenebilir deÄŸil: " @@ -13377,6 +13588,88 @@ msgstr "Yineleyici geçersiz durumda" msgid "Iterator became invalid: " msgstr "Yineleyici geçersiz durumda: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Klasör yeniden adlandırma:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Perde:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Türler:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Kendi" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "%s karakterinde" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Ekle %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Ayarla %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Ekle %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Getir %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Geçersiz indeks özelliÄŸi ismi." @@ -13393,6 +13686,21 @@ msgstr "Yol bir düğüme çıkmıyor!" msgid "Invalid index property name '%s' in node %s." msgstr "%s düğümünde geçersiz indeks özelliÄŸi ismi '%s'." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Ayarla %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "İşlevler" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Diziyi Yeniden Boyutlandır" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Åžu tür için geçersiz deÄŸiÅŸtirgen: " @@ -13402,6 +13710,10 @@ msgid ": Invalid arguments: " msgstr ": Geçersiz deÄŸiÅŸtirgenler: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "VariableGet betikte bulunamadı: " @@ -13410,6 +13722,66 @@ msgid "VariableSet not found in script: " msgstr "VariableSet betikte bulunamadı: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Yeniden Yükle" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Derinlik İndeksi" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Derinlik İndeksi" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Sabit" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Sabit" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Sabit" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Sabit" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "GDNative İskelet EtkinleÅŸtirildi" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "TimeSeek Düğümü" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Sahne AÄŸacı Düzenleme" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Kendi" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Düğümleri Kes" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "Özel düğüm _step() metoduna sahip deÄŸil, grafiÄŸi iÅŸleyemez." @@ -13421,13 +13793,75 @@ msgstr "" "_step()'ten geçersiz dönüş deÄŸeri, tam sayı (dizi çıkışı) ya da dize " "(hatası) olmalı." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "ÇaÄŸrılar" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Sabitler" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Yerel Ekseni Kullan" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Yerel Ekseni Kullan" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Eylem" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Görsel Betikte Ara" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Getir %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Çerçeveyi Taşı" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Fizik Kare %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Sinyal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Sinyal" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Örnek" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14064,15 +14498,25 @@ msgstr "" "çalışır." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "GPU tabanlı parçacıklar GLES2 video sürücüsü tarafından desteklenmez.\n" "Bunun yerine CPUParçacıklar2B düğümünü kullanın. Bu amaçla " "\"CPUParçacıklar'a Dönüştür\" seçeneÄŸini kullanabilirsiniz." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14327,10 +14771,11 @@ msgid "Only uniform scales are supported." msgstr "Yalnızca tek tip ölçekler desteklenir." #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "GPU tabanlı parçacıklar GLES2 video sürücüsü tarafından desteklenmez.\n" "Bunun yerine CPUParçacık düğümünü kullanın. Bu amaçla \"CPUParçacık'a " @@ -14338,6 +14783,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" "HiçbirÅŸey görünebilir deÄŸil çünkü örüntüler çizim geçiÅŸlerine atanmış deÄŸil." diff --git a/editor/translations/tt.po b/editor/translations/tt.po index 5032eb753a..abbc0eed73 100644 --- a/editor/translations/tt.po +++ b/editor/translations/tt.po @@ -358,6 +358,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -807,6 +808,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -856,8 +858,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1880,7 +1881,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -1997,7 +1997,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2165,7 +2166,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2195,6 +2196,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2888,7 +2891,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3023,10 +3026,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3243,6 +3242,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3319,7 +3319,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3544,6 +3543,11 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +msgid "%s Error" +msgstr "" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4399,6 +4403,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6042,6 +6047,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9324,7 +9330,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9332,7 +9338,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9340,7 +9351,36 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Җәмәгать" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9352,39 +9392,55 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +msgid "Remote Login" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect new changes" +msgid "Username" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Password" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "SSH Public Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +msgid "Select SSH public key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" +msgid "SSH Private Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect new changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +msgid "Stage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Unstage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9392,15 +9448,108 @@ msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +#, fuzzy +msgid "Commit List" +msgstr "Җәмәгать" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Create New Branch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Remove Branch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remotes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remove Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote URL" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -11909,6 +12058,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12737,6 +12887,38 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Condition" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12749,6 +12931,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12765,6 +13021,18 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Function" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12774,6 +13042,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12782,6 +13054,54 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Node" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Tree" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "CustomNode" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12791,12 +13111,64 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Action %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13358,7 +13730,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13571,7 +13952,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/tzm.po b/editor/translations/tzm.po index 77ca1dae62..e83ce5dc02 100644 --- a/editor/translations/tzm.po +++ b/editor/translations/tzm.po @@ -356,6 +356,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -805,6 +806,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -854,8 +856,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1878,7 +1879,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -1995,7 +1995,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2163,7 +2164,7 @@ msgstr "" msgid "Signal" msgstr "" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2193,6 +2194,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2886,7 +2889,7 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3021,10 +3024,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3241,6 +3240,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3317,7 +3317,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3542,6 +3541,11 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +msgid "%s Error" +msgstr "" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4397,6 +4401,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6040,6 +6045,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9322,7 +9328,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9330,7 +9336,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9338,7 +9349,35 @@ msgid "Commit" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +msgid "Staged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unstaged Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9350,39 +9389,55 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +msgid "Remote Login" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect new changes" +msgid "Username" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" +msgid "Password" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "SSH Public Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" +msgid "Select SSH public key path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" +msgid "SSH Private Key Path" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect new changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Discard all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" +msgid "Stage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +msgid "Unstage all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Message" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9390,15 +9445,107 @@ msgid "Commit Changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Commit List" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Create New Branch" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Remove Branch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remotes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Create New Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remove Remote" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Remote URL" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Split" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -11907,6 +12054,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -12735,6 +12883,38 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Condition" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -12747,6 +12927,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -12763,6 +13017,18 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Function" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -12772,6 +13038,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -12780,6 +13050,54 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Global Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Class Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Basic Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Math Constant" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Node" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Scene Tree" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "CustomNode" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -12789,12 +13107,64 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Construct %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Action %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitNodeSignal" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13356,7 +13726,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13569,7 +13948,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/uk.po b/editor/translations/uk.po index 9ded993590..e1d0021c08 100644 --- a/editor/translations/uk.po +++ b/editor/translations/uk.po @@ -3,7 +3,7 @@ # Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). # This file is distributed under the same license as the Godot source code. # Aleksandr <XpycT.TOP@gmail.com>, 2017. -# Yuri Chornoivan <yurchor@ukr.net>, 2018, 2019, 2020, 2021. +# Yuri Chornoivan <yurchor@ukr.net>, 2018, 2019, 2020, 2021, 2022. # Ðндрій Бандура <andriykopanytsia@gmail.com>, 2018. # Гидеон Теон <t.kudely94@gmail.com>, 2017. # МакÑим Якимчук <xpinovo@gmail.com>, 2018, 2019. @@ -22,7 +22,7 @@ msgstr "" "Project-Id-Version: Ukrainian (Godot Engine)\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-12-11 06:25+0000\n" +"PO-Revision-Date: 2022-01-12 16:52+0000\n" "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n" "Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/" "godot/uk/>\n" @@ -32,7 +32,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.10-dev\n" +"X-Generator: Weblate 4.10.1\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -338,9 +338,8 @@ msgid "Duplicate Key(s)" msgstr "Дублювати ключі" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add RESET Value(s)" -msgstr "Додати %d кадри" +msgstr "Додати Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ RESET" #: editor/animation_track_editor.cpp msgid "Delete Key(s)" @@ -377,6 +376,7 @@ msgstr "Створити %d нові доріжки Ñ– вÑтавити ключ #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -513,9 +513,8 @@ msgstr "" "одинарна доріжка." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Add RESET Keys" -msgstr "МаÑÑˆÑ‚Ð°Ð±ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ»ÑŽÑ‡Ñ–Ð² анімації" +msgstr "Додати RESET-ключові до анімації" #: editor/animation_track_editor.cpp msgid "" @@ -848,6 +847,7 @@ msgstr "Додати" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -899,8 +899,7 @@ msgstr "Ðе вдалоÑÑ Ð·'єднати Ñигнал" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1503,7 +1502,7 @@ msgstr "Ðекоректна назва." #: editor/editor_autoload_settings.cpp msgid "Cannot begin with a digit." -msgstr "" +msgstr "Ðе може починатиÑÑ Ð· цифри." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" @@ -1970,7 +1969,6 @@ msgid "New Folder..." msgstr "Створити теку..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Оновити" @@ -2087,7 +2085,8 @@ msgstr "Каталоги та файли:" msgid "Preview:" msgstr "Попередній переглÑд:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Файл:" @@ -2137,9 +2136,8 @@ msgid "Properties" msgstr "ВлаÑтивоÑті" #: editor/editor_help.cpp -#, fuzzy msgid "overrides %s:" -msgstr "перевизначеннÑ:" +msgstr "Ð¿ÐµÑ€ÐµÐ²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %s:" #: editor/editor_help.cpp msgid "default:" @@ -2262,7 +2260,7 @@ msgstr "Метод" msgid "Signal" msgstr "Сигнал" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Сталий" @@ -2279,20 +2277,24 @@ msgid "Property:" msgstr "ВлаÑтивіÑть:" #: editor/editor_inspector.cpp -#, fuzzy msgid "Pin value" -msgstr "(значеннÑ)" +msgstr "Пришпилити значеннÑ" #: editor/editor_inspector.cpp msgid "" "Pinning a value forces it to be saved even if it's equal to the default." msgstr "" +"ÐŸÑ€Ð¸ÑˆÐ¿Ð¸Ð»ÐµÐ½Ð½Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¸Ð·Ð²ÐµÐ´Ðµ до примуÑового Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ, навіть " +"Ñкщо воно дорівнює типовому." #: editor/editor_inspector.cpp msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" +"Пришпилити Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ [вимкнено, оÑкільки «%s» призначено лише Ð´Ð»Ñ Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ]" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Ð’Ñтановити %s" @@ -2303,26 +2305,23 @@ msgstr "Ð’Ñтановити кратніÑть:" #: editor/editor_inspector.cpp msgid "Pinned %s" -msgstr "" +msgstr "Пришпилено %s" #: editor/editor_inspector.cpp msgid "Unpinned %s" -msgstr "" +msgstr "Відшпилено %s" #: editor/editor_inspector.cpp -#, fuzzy msgid "Copy Property" -msgstr "Копіювати влаÑтивоÑті" +msgstr "Копіювати влаÑтивіÑть" #: editor/editor_inspector.cpp -#, fuzzy msgid "Paste Property" -msgstr "Ð’Ñтавити влаÑтивоÑті" +msgstr "Ð’Ñтавити влаÑтивіÑть" #: editor/editor_inspector.cpp -#, fuzzy msgid "Copy Property Path" -msgstr "Копіювати шлÑÑ… до Ñкрипту" +msgstr "Копіювати шлÑÑ… до влаÑтивоÑті" #: editor/editor_log.cpp msgid "Output:" @@ -3051,8 +3050,9 @@ msgid "Install Android Build Template..." msgstr "Ð’Ñтановити шаблон Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð´Ð»Ñ Android…" #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ‚ÐµÐºÐ¸ даних проєкту" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ‚ÐµÐºÐ¸ даних редактора" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3142,7 +3142,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Force Shader Fallbacks" -msgstr "" +msgstr "ПримуÑово вÑтановити резерви Ð´Ð»Ñ ÑˆÐµÐ¹Ð´ÐµÑ€Ñ–Ð²" #: editor/editor_node.cpp msgid "" @@ -3153,6 +3153,13 @@ msgid "" "Asynchronous shader compilation must be enabled in the project settings for " "this option to make a difference." msgstr "" +"Якщо позначено цей пункт, шейдери буде викориÑтано у їхній резервній формі " +"(або зроблено видимими через убершейдер чи приховано) протÑгом уÑього чаÑу " +"роботи.\n" +"Це кориÑно Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸ виглÑду Ñ– швидкодіії резервних варіантів, Ñкі за " +"звичайних умов буде показано дуже коротко.\n" +"Щоб цей пункт запрацював, у параметрах проєкту має бути увімкнено аÑинхронну " +"компілÑцію шейдерів." #: editor/editor_node.cpp msgid "Synchronize Scene Changes" @@ -3211,10 +3218,6 @@ msgid "Toggle Fullscreen" msgstr "Перемикач повноекранного режиму" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "Увімкнути або вимкнути конÑоль ÑиÑтеми" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ‚ÐµÐºÐ¸ даних/параметрів редактора" @@ -3445,6 +3448,7 @@ msgid "Load Errors" msgstr "Помилки завантаженнÑ" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Виділити" @@ -3521,7 +3525,6 @@ msgid "Author" msgstr "Ðвтор" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "СтатуÑ" @@ -3767,6 +3770,12 @@ msgstr "ШлÑÑ… до Ñцени:" msgid "Import From Node:" msgstr "Імпортувати з вузла:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Помилка" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "Відкрити теку, Ñка міÑтить ці шаблони." @@ -4309,9 +4318,8 @@ msgid "Replace..." msgstr "Замінити..." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Replace in Files" -msgstr "Замінити вÑÑ–" +msgstr "Замінити у файлах" #: editor/find_in_files.cpp msgid "Find: " @@ -4322,9 +4330,8 @@ msgid "Replace: " msgstr "Замінити: " #: editor/find_in_files.cpp -#, fuzzy msgid "Replace All (NO UNDO)" -msgstr "Замінити вÑÑ–" +msgstr "Замінити вÑÑ– (БЕЗ СКÐСУВÐÐÐЯ)" #: editor/find_in_files.cpp msgid "Searching..." @@ -4549,6 +4556,8 @@ msgid "" "Select a resource file in the filesystem or in the inspector to adjust " "import settings." msgstr "" +"Виберіть файл реÑурÑів у файловій ÑиÑтемі або у інÑпекторі Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ð³ÑƒÐ²Ð°Ð½Ð½Ñ " +"параметрів імпортуваннÑ." #: editor/inspector_dock.cpp msgid "Failed to load resource." @@ -4657,6 +4666,7 @@ msgid "Subfolder:" msgstr "Підтека:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Ðвтор:" @@ -6018,9 +6028,8 @@ msgid "Alt+Drag: Move selected node." msgstr "Alt+ПеретÑгнути: переміÑтити позначений вузол." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Alt+Drag: Scale selected node." -msgstr "Alt+ПеретÑгнути: переміÑтити позначений вузол." +msgstr "Alt+ПеретÑгнути: маÑштабувати позначений вузол." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "V: Set selected node's pivot position." @@ -6054,7 +6063,7 @@ msgstr "Режим маÑштабуваннÑ" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Shift: Scale proportionally." -msgstr "" +msgstr "Shift: маÑштабувати пропорційно." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6153,9 +6162,8 @@ msgstr "Ð‘Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±Ñ€Ð°Ð½Ð¾Ð³Ð¾ об'єкта на міÑці (нР#: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected Node(s)" -msgstr "Заблокувати позначене" +msgstr "Заблокувати позначені вузли" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6164,9 +6172,8 @@ msgstr "Розблокувати вибраний об'єкт (можна пер #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected Node(s)" -msgstr "Розблокувати позначене" +msgstr "Розблокувати позначені вузли" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6175,9 +6182,8 @@ msgstr "Гарантує нащадки об'єкта не можуть бути #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected Node(s)" -msgstr "Згрупувати позначені" +msgstr "Згрупувати позначені вузли" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6186,9 +6192,8 @@ msgstr "Відновлює можливіÑть вибору нащадків о #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected Node(s)" -msgstr "Розгрупувати позначені" +msgstr "Розгрупувати позначені вузли" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Skeleton Options" @@ -6361,6 +6366,7 @@ msgid "Zoom to 1600%" msgstr "МаÑштаб у 1600%" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Додати %s" @@ -7835,9 +7841,8 @@ msgid "Find in Files..." msgstr "Знайти у файлах…" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Replace in Files..." -msgstr "Замінити..." +msgstr "Замінити у файлах…" #: editor/plugins/script_text_editor.cpp msgid "Contextual Help" @@ -8365,16 +8370,15 @@ msgstr "ÐŸÐµÑ€ÐµÐ¼Ð¸ÐºÐ°Ð½Ð½Ñ Ð¾Ð³Ð»Ñду" #: editor/plugins/spatial_editor_plugin.cpp msgid "Decrease Field of View" -msgstr "" +msgstr "Зменшити поле зору" #: editor/plugins/spatial_editor_plugin.cpp msgid "Increase Field of View" -msgstr "" +msgstr "Збільшити поле зору" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Reset Field of View to Default" -msgstr "ПовернутиÑÑ Ð´Ð¾ типового" +msgstr "ПовернутиÑÑ Ð´Ð¾ типового Ð¿Ð¾Ð»Ñ Ð·Ð¾Ñ€Ñƒ" #: editor/plugins/spatial_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9105,22 +9109,19 @@ msgstr "Додати тип" #: editor/plugins/theme_editor_plugin.cpp msgid "Filter the list of types or create a new custom type:" -msgstr "" +msgstr "Фільтрувати ÑпиÑок типів або Ñтворити неÑтандартний тип:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Available Node-based types:" -msgstr "ДоÑтупні профілі:" +msgstr "ДоÑтупні типи на оÑнові вузлів:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Type name is empty!" -msgstr "ÐŸÐ¾Ñ€Ð¾Ð¶Ð½Ñ Ð½Ð°Ð·Ð²Ð° файла." +msgstr "Ðазва типу Ñ” порожньою!" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Are you sure you want to create an empty type?" -msgstr "Ви Ñправді хочете відкрити декілька проєктів одразу?" +msgstr "Ви Ñправді хочете Ñтворити порожній тип?" #: editor/plugins/theme_editor_plugin.cpp msgid "Confirm Item Rename" @@ -9747,7 +9748,8 @@ msgid "TileSet" msgstr "Ðабір плиток" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "Ðемає доÑтупних доданків ÑиÑтем ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð²ÐµÑ€ÑÑ–Ñми." #: editor/plugins/version_control_editor_plugin.cpp @@ -9755,16 +9757,56 @@ msgid "Error" msgstr "Помилка" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "Ðе додано жодних файлів Ð´Ð»Ñ Ð²Ð½ÐµÑку" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Ім'Ñ Ð½Ðµ вказано." #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "ВнеÑок" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "Додаток ÑиÑтеми ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð²ÐµÑ€ÑÑ–Ñми не ініціалізовано" +#, fuzzy +msgid "Staged Changes" +msgstr "Зміни шейдерів:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Зміни шейдерів:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "ВнеÑок" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Піддерево" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Ви Ñправді хочете Ñтворити порожній тип?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "ЗаÑтоÑувати ÑкиданнÑ" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9775,16 +9817,148 @@ msgid "Initialize" msgstr "Ініціалізувати" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "ОблаÑть внеÑку" +#, fuzzy +msgid "Remote Login" +msgstr "Вилучити точку" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Перейменувати" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "ВиÑвити зміни" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Зміни" +#, fuzzy +msgid "Discard all changes" +msgstr "Закрити та зберегти зміни?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¸Ñ… змін..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "Зміни матеріалу:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "ВнеÑти зміни" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "ВнеÑти зміни" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "ВнеÑок" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "Збіги:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "Створити новий проєкт" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Видалити доріжку" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "Віддалений" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Створити новий проєкт" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Вилучити елемент" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Віддалений " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Віддалений " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "Початкова Ñітка:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9803,29 +9977,23 @@ msgid "Typechange" msgstr "Зміна типу" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "Вибрано Ð´Ð»Ñ Ð²Ð½ÐµÑку" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "ВнеÑти вÑе" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "ВнеÑти зміни" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "" -"ПереглÑнути відмінноÑті у файлах, перш ніж внеÑти Ñ—Ñ… до найÑвіжішої верÑÑ–Ñ—" +#, fuzzy +msgid "View:" +msgstr "ПереглÑд" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "Ðемає активних відмінноÑтей між файлами" +#, fuzzy +msgid "Split" +msgstr "Розділити шлÑÑ…" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "ВиÑвити зміни у відмінноÑÑ‚ÑÑ… між файлами" +#, fuzzy +msgid "Unified" +msgstr "Змінено" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -11978,6 +12146,11 @@ msgid "" "To save this branch into its own scene, open the original scene, right click " "on this branch, and select \"Save Branch as Scene\"." msgstr "" +"Ðе можна зберігати гілку, Ñка Ñ” дочірньою щодо Ñцени, Ñка вже має " +"екземплÑÑ€.\n" +"Щоб зберегти цю гілку до Ñ—Ñ— влаÑної Ñцени, відкрийте початкову Ñцену, " +"клацніть правою кнопкою миші на Ñ—Ñ— гілці Ñ– виберіть «Зберегти гілку Ñк " +"Ñцену»." #: editor/scene_tree_dock.cpp msgid "" @@ -11985,6 +12158,10 @@ msgid "" "To save this branch into its own scene, open the original scene, right click " "on this branch, and select \"Save Branch as Scene\"." msgstr "" +"Ðе можна зберігати гілку, Ñка Ñ” чаÑтиною уÑпадкованої Ñцени.\n" +"Щоб зберегти цю гілку до Ñ—Ñ— влаÑної Ñцени, відкрийте початкову Ñцену, " +"клацніть правою кнопкою миші на Ñ—Ñ— гілці Ñ– виберіть «Зберегти гілку Ñк " +"Ñцену»." #: editor/scene_tree_dock.cpp msgid "Save New Scene As..." @@ -12524,6 +12701,7 @@ msgid "Export list to a CSV file" msgstr "ЕкÑпортувати ÑпиÑок до файла CSV" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "ШлÑÑ… до реÑурÑу" @@ -13372,6 +13550,40 @@ msgstr "Оновити граф" msgid "Edit Member" msgstr "Редагувати член" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Ð’Ñтановити вираз" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "анімаціÑ" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Тип вводу не ітерабельний: " @@ -13384,6 +13596,88 @@ msgstr "Ітератор Ñтав недійÑним" msgid "Iterator became invalid: " msgstr "Ітератор Ñтав недійÑним: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "ÐŸÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚ÐµÐºÐ¸:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "Тон:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Типи:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "Цей об'єкт" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Ðа Ñимволі %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Додати %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Ð’Ñтановити %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Пришпилено %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Отримати %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Ðеправильний Ñ–Ð½Ð´ÐµÐºÑ Ð²Ð»Ð°ÑтивоÑті імені." @@ -13400,6 +13694,21 @@ msgstr "ШлÑÑ… не веде до вузла!" msgid "Invalid index property name '%s' in node %s." msgstr "Ðекоректна назва влаÑтивоÑті індекÑу, «%s», у вузлі %s." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Ð’Ñтановити %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Функції" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Змінити розмір маÑиву" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Ðеправильний тип аргументу: " @@ -13409,6 +13718,10 @@ msgid ": Invalid arguments: " msgstr ": ÐеприпуÑтимі аргументи: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "Ðе знайдено VariableGet у Ñкрипті: " @@ -13417,6 +13730,66 @@ msgid "VariableSet not found in script: " msgstr "Ðе знайдено VariableSet у Ñкрипті: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Перезавантажити" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Z-індекÑ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Z-індекÑ" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Сталий" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Сталий" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Сталий" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Сталий" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "Увімкнений одинак GDNative" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Вузол пошуку чаÑу" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ñ–Ñ”Ñ€Ð°Ñ€Ñ…Ñ–Ñ— Ñцени" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "Цей об'єкт" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Вирізати вузли" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "У нетиповому вузлі немає методу _step(). Обробка графу неможлива." @@ -13428,13 +13801,75 @@ msgstr "" "_step() повертає некоректне значеннÑ. ЗначеннÑм має бути ціле чиÑло (seq " "out) або Ñ€Ñдок (error)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Виклики" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "КонÑтанти" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "ВикориÑтати локальний проÑтір" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "ВикориÑтати локальний проÑтір" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "ДіÑ" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Шукати VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Отримати %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "ПереÑунути кадр" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Фізичний кадр %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "Сигнал" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "Сигнал" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "ЕкземплÑÑ€" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14061,13 +14496,15 @@ msgstr "" #: scene/2d/navigation_agent_2d.cpp msgid "The NavigationAgent2D can be used only under a Node2D node." -msgstr "" +msgstr "NavigationAgent2D можна викориÑтовувати лише під вузлом Node2D." #: scene/2d/navigation_obstacle_2d.cpp msgid "" "The NavigationObstacle2D only serves to provide collision avoidance to a " "Node2D object." msgstr "" +"NavigationObstacle2D призначено лише Ð´Ð»Ñ Ð½Ð°Ð´Ð°Ð½Ð½Ñ Ð·Ð°Ñобів ÑƒÐ½Ð¸ÐºÐ½ÐµÐ½Ð½Ñ Ð·Ñ–Ñ‚ÐºÐ½ÐµÐ½Ð½Ñ " +"Ð´Ð»Ñ Ð¾Ð±'єкта Node2D." #: scene/2d/navigation_polygon.cpp msgid "" @@ -14094,16 +14531,26 @@ msgstr "" "ParallaxBackground." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "У драйвері GLES2 не передбачено підтримки чаÑток із обробкою за допомогою " "графічного процеÑора.\n" "Вам Ñлід ÑкориÑтатиÑÑ Ð²ÑƒÐ·Ð»Ð¾Ð¼ CPUParticles2D. Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ можете вибрати пункт " "«Перетворити на CPUParticles»." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14332,7 +14779,7 @@ msgstr "SpotLight з кутом, Ñкий Ñ” більшим за 90 Ð³Ñ€Ð°Ð´ÑƒÑ #: scene/3d/navigation_agent.cpp msgid "The NavigationAgent can be used only under a spatial node." -msgstr "" +msgstr "NavigationAgent можна викориÑтовувати лише під проÑторовим вузлом." #: scene/3d/navigation_mesh_instance.cpp msgid "" @@ -14347,6 +14794,8 @@ msgid "" "The NavigationObstacle only serves to provide collision avoidance to a " "spatial object." msgstr "" +"NavigationObstacle призначено лише Ð´Ð»Ñ Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð·Ð°Ñобів ÑƒÐ½Ð¸ÐºÐ½ÐµÐ½Ð½Ñ " +"Ð·Ñ–Ñ‚ÐºÐ½ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñторового об'єкта." #: scene/3d/occluder.cpp msgid "No shape is set." @@ -14357,10 +14806,11 @@ msgid "Only uniform scales are supported." msgstr "Передбачено підтримку лише однорідних маÑштабів." #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "У драйвері GLES2 не передбачено підтримки чаÑток із обробкою за допомогою " "графічного процеÑора.\n" @@ -14369,6 +14819,14 @@ msgstr "" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" "Ðічого не видно, оÑкільки Ñітки не було пов'Ñзано із проходами малюваннÑ." diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po index c84931094f..a93f7f85b5 100644 --- a/editor/translations/ur_PK.po +++ b/editor/translations/ur_PK.po @@ -364,6 +364,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -819,6 +820,7 @@ msgstr "" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -869,8 +871,7 @@ msgstr ".تمام کا انتخاب" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1917,7 +1918,6 @@ msgid "New Folder..." msgstr "" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "" @@ -2039,7 +2039,8 @@ msgstr "" msgid "Preview:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "" @@ -2212,7 +2213,7 @@ msgstr "" msgid "Signal" msgstr ".تمام کا انتخاب" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "" @@ -2243,6 +2244,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -2947,8 +2950,9 @@ msgid "Install Android Build Template..." msgstr "" #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "" +#, fuzzy +msgid "Open User Data Folder" +msgstr "سب سکریپشن بنائیں" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3083,10 +3087,6 @@ msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3308,6 +3308,7 @@ msgid "Load Errors" msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "" @@ -3386,7 +3387,6 @@ msgid "Author" msgstr "" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3615,6 +3615,11 @@ msgstr "" msgid "Import From Node:" msgstr "" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +msgid "%s Error" +msgstr "" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4499,6 +4504,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "" @@ -6195,6 +6201,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -9613,7 +9620,7 @@ msgid "TileSet" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9621,7 +9628,12 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No commit message was provided." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9630,7 +9642,38 @@ msgid "Commit" msgstr "کمیونٹی" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr ".Ù†ÙˆÙ¹ÙØ¦Ø± Ú©Û’ اکسٹنٹ Ú©Ùˆ تبدیل کیجیۓ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr ".Ù†ÙˆÙ¹ÙØ¦Ø± Ú©Û’ اکسٹنٹ Ú©Ùˆ تبدیل کیجیۓ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "کمیونٹی" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Apply" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9642,7 +9685,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr ".تمام کا انتخاب" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr ".تمام کا انتخاب" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -9651,51 +9724,139 @@ msgid "Detect new changes" msgstr "سب سکریپشن بنائیں" #: editor/plugins/version_control_editor_plugin.cpp +msgid "Discard all changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Changes" -msgstr ".Ù†ÙˆÙ¹ÙØ¦Ø± Ú©Û’ اکسٹنٹ Ú©Ùˆ تبدیل کیجیۓ" +msgid "Stage all changes" +msgstr "سب سکریپشن بنائیں" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +msgid "Unstage all changes" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" +msgid "Commit Message" +msgstr "کمیونٹی" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "کمیونٹی" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branches" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "سب سکریپشن بنائیں" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "انیم ٹریک Ûٹائیں" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" msgstr ".تمام کا انتخاب" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr ".اینیمیشن Ú©ÛŒ کیز Ú©Ùˆ ڈیلیٹ کرو" +msgid "Create New Remote" +msgstr "سب سکریپشن بنائیں" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Typechange" +#, fuzzy +msgid "Remove Remote" +msgstr ".تمام کا انتخاب" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "ریموٹ " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "ریموٹ " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" +msgid "Renamed" msgstr ".تمام کا انتخاب" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" +#, fuzzy +msgid "Deleted" +msgstr ".اینیمیشن Ú©ÛŒ کیز Ú©Ùˆ ڈیلیٹ کرو" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" +msgid "Unmerged" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "View:" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Split" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12257,6 +12418,7 @@ msgid "Export list to a CSV file" msgstr "" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13125,6 +13287,39 @@ msgstr "" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "سب سکریپشن بنائیں" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -13137,6 +13332,80 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "in order:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Subtract %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -13153,6 +13422,19 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr ".تمام کا انتخاب" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -13162,6 +13444,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -13170,6 +13456,61 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "Preload" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "مستقل" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "مستقل" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "مستقل" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "مستقل" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr ".اینیمیشن Ú©ÛŒ کیز Ú©Ùˆ ڈیلیٹ کرو" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "سب سکریپشن بنائیں" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "ایکشن منتقل کریں" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -13179,13 +13520,70 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "مستقل" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "ایکشن منتقل کریں" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp #, fuzzy msgid "Search VisualScript" msgstr "سب سکریپشن بنائیں" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "ایکشن منتقل کریں" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Next Physics Frame" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr ".تمام کا انتخاب" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr ".تمام کا انتخاب" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "WaitInstanceSignal" msgstr "" #: platform/android/export/export_plugin.cpp @@ -13755,7 +14153,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -13968,7 +14375,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/vi.po b/editor/translations/vi.po index 1a7c450e3d..f9bec13fd9 100644 --- a/editor/translations/vi.po +++ b/editor/translations/vi.po @@ -376,6 +376,7 @@ msgstr "Tạo %d track má»›i và chèn key?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -842,6 +843,7 @@ msgstr "Thêm" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -892,8 +894,7 @@ msgstr "Không thể kết nối tÃn hiệu" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1954,7 +1955,6 @@ msgid "New Folder..." msgstr "Thư mục má»›i ..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "Là m má»›i" @@ -2071,7 +2071,8 @@ msgstr "Các Thư mục và Tệp tin:" msgid "Preview:" msgstr "Xem thá»:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "Tệp tin:" @@ -2250,7 +2251,7 @@ msgstr "Phương thức" msgid "Signal" msgstr "TÃn hiệu" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "Hằng số" @@ -2281,6 +2282,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "Gán %s" @@ -3025,8 +3028,9 @@ msgid "Install Android Build Template..." msgstr "Cà i đặt mẫu xây dá»±ng Android..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "Mở Thư mục dữ liệu cá»§a Dá»± Ãn" +#, fuzzy +msgid "Open User Data Folder" +msgstr "Mở thư mục dữ liệu cá»§a trình chỉnh sá»a" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3174,10 +3178,6 @@ msgid "Toggle Fullscreen" msgstr "Chế độ Toà n mà n hình" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "KÃch hoạt Console Hệ thống" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Mở thư mục dữ liệu cá»§a trình chỉnh sá»a" @@ -3410,6 +3410,7 @@ msgid "Load Errors" msgstr "Nạp Lá»—i" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "Chá»n" @@ -3489,7 +3490,6 @@ msgid "Author" msgstr "Tác giả" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "Trạng thái" @@ -3719,6 +3719,12 @@ msgstr "ÄÆ°á»ng dẫn Cảnh:" msgid "Import From Node:" msgstr "Nháºp từ Nút:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "Lá»—i" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4628,6 +4634,7 @@ msgid "Subfolder:" msgstr "Thư mục phụ:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "Tác giả:" @@ -6314,6 +6321,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "Thêm %s" @@ -9770,7 +9778,8 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "Không có phần má»m kiểm soát phiên bản khả dụng." #: editor/plugins/version_control_editor_plugin.cpp @@ -9778,8 +9787,14 @@ msgid "Error" msgstr "Lá»—i" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "Không có tệp nà o trong giai Ä‘oạn chá»" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "Không có tên được cung cấp." #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy @@ -9787,8 +9802,42 @@ msgid "Commit" msgstr "Cá»™ng đồng" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "Trình kiểm soát phiên bản chưa được khởi tạo" +#, fuzzy +msgid "Staged Changes" +msgstr "Những thay đổi" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "Những thay đổi" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "Cá»™ng đồng" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "Cây con" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "Bạn chắc chắn mở nhiá»u hÆ¡n má»™t dá»± án?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "Ãp dụng đặt lại" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9799,61 +9848,186 @@ msgid "Initialize" msgstr "Khởi tạo" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "Vùng chá»" +#, fuzzy +msgid "Remote Login" +msgstr "Xoá Ä‘iểm" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "Äổi tên" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "Phát hiện thay đổi má»›i" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "Những thay đổi" +#, fuzzy +msgid "Discard all changes" +msgstr "Äóng và lưu thay đổi?" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" -msgstr "Äã sá»a đổi" +#, fuzzy +msgid "Stage all changes" +msgstr "Lưu các thay đổi cục bá»™ ..." #: editor/plugins/version_control_editor_plugin.cpp -msgid "Renamed" -msgstr "Äã đổi tên" +#, fuzzy +msgid "Unstage all changes" +msgstr "Äối số đã thay đổi" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Deleted" -msgstr "Äã Xóa" +#, fuzzy +msgid "Commit Message" +msgstr "Äổi" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Typechange" +msgid "Commit Changes" msgstr "Äổi" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "Xoá lá»±a chá»n" +msgid "Commit List" +msgstr "Cá»™ng đồng" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "Chá»n Toà n Bá»™" +msgid "Branches" +msgstr "Phù hợp:" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" -msgstr "Äổi" +msgid "Create New Branch" +msgstr "Tạo má»›i Dá»± án" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "Xóa Anim Track" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "Kiểm tra các khác biệt trước khi xác nháºn và o phiên bản má»›i nhất" +#, fuzzy +msgid "Remotes" +msgstr "Xóa" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "Tạo má»›i Dá»± án" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "Gõ bá» Mục" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "Tên Node:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "Xóa" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +#, fuzzy +msgid "Force Push" +msgstr "Lưới nguồn:" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "Äã sá»a đổi" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "Äã đổi tên" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "Äã Xóa" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Typechange" +msgstr "Äổi" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" msgstr "" +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "View:" +msgstr "Hiện thị" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Split" +msgstr "Tách đưá»ng" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unified" +msgstr "Äã sá»a đổi" + #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" msgstr "(Chỉ dà nh cho GLES3)" @@ -12516,6 +12690,7 @@ msgid "Export list to a CSV file" msgstr "Xuất hồ sÆ¡" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "ÄÆ°á»ng dẫn Tà i nguyên" @@ -13370,6 +13545,40 @@ msgstr "Là m má»›i đồ thị" msgid "Edit Member" msgstr "" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "Äặt phép diá»…n đạt" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "Hoạt ảnh" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "Kiểu đầu và o không lặp được: " @@ -13382,6 +13591,87 @@ msgstr "Trá» lặp không còn hợp lệ" msgid "Iterator became invalid: " msgstr "Trá» lặp không còn hợp lệ: " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "Äổi tên thư mục:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "Kiểu:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "ChÃnh nó" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "Tại kà tá»± %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "Thêm %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "Gán %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "Thêm %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "Lấy %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "Tên thuá»™c tÃnh chỉ mục không hợp lệ." @@ -13398,6 +13688,21 @@ msgstr "ÄÆ°á»ng dẫn không chỉ đến Nút!" msgid "Invalid index property name '%s' in node %s." msgstr "Tên thuá»™c tÃnh chỉ mục '%s' ở nút '%s' không hợp lệ." +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "Gán %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "Hà m" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "Thay đổi kÃch thước mảng" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": Tham số có loại không hợp lệ: " @@ -13407,6 +13712,10 @@ msgid ": Invalid arguments: " msgstr ": Tham số không hợp lệ: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "Không tìm thấy VariableGet trong tệp lệnh: " @@ -13416,6 +13725,66 @@ msgid "VariableSet not found in script: " msgstr "Không tìm thấy VariableSet trong tệp lệnh: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "Tải lại" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Chỉ số Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Chỉ số Z" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "Hằng số" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "Hằng số" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "Hằng số" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "Hằng số" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "Báºt đơn nhất GDNative" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "Nút TimeSeek" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "Chỉnh sá»a cảnh" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "ChÃnh nó" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "Cắt các nút" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "Nút tùy chá»n không có phương thức _step(), không thể xá» là đồ thị." @@ -13428,13 +13797,75 @@ msgstr "" "_step() trả giá trị không hợp lệ, phải là số nguyên (seq out), hoặc xâu " "(lá»—i)." +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "Lượt gá»i" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "Hằng số" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "Sá» dụng Không gian Cục bá»™" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "Sá» dụng Không gian Cục bá»™" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "Chá»n tất cả" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "Tìm VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "Lấy %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "Di chuyển Khung hình" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "Khung hình Váºt lý %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "TÃn hiệu" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "TÃn hiệu" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Thêm và o Cảnh" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -14067,15 +14498,25 @@ msgstr "" "Nút ParallaxLayer chỉ hoạt động khi là con cá»§a má»™t nút ParallaxBackground." #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "Video driver GLES2 không há»— trợ hạt dá»±a trên bá»™ xá» là GPU.\n" "Thay và o đó hãy dùng nút CPUParticles2D. Bạn có thể dùng tùy chá»n \"Chuyển " "thà nh CPUParticles\" cho mục Ä‘Ãch nà y." +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -14310,10 +14751,22 @@ msgid "Only uniform scales are supported." msgstr "" #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" +"Video driver GLES2 không há»— trợ hạt dá»±a trên bá»™ xá» là GPU.\n" +"Thay và o đó hãy dùng nút CPUParticles2D. Bạn có thể dùng tùy chá»n \"Chuyển " +"thà nh CPUParticles\" cho mục Ä‘Ãch nà y." + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po index 06fe826028..314cc33f9f 100644 --- a/editor/translations/zh_CN.po +++ b/editor/translations/zh_CN.po @@ -58,7 +58,7 @@ # idleman <1524328475@qq.com>, 2019. # king <wangding1992@126.com>, 2019. # silentbird <silentbird520@outlook.com>, 2019. -# Haoyu Qiu <timothyqiu32@gmail.com>, 2019, 2020, 2021. +# Haoyu Qiu <timothyqiu32@gmail.com>, 2019, 2020, 2021, 2022. # Revan Ji <jiruifancr@gmail.com>, 2020. # nieyuanhong <15625988003@163.com>, 2020. # binotaliu <binota@protonmail.ch>, 2020. @@ -88,7 +88,7 @@ msgstr "" "Project-Id-Version: Chinese (Simplified) (Godot Engine)\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: 2018-01-20 12:15+0200\n" -"PO-Revision-Date: 2021-12-31 08:52+0000\n" +"PO-Revision-Date: 2022-01-12 16:52+0000\n" "Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hans/>\n" @@ -106,7 +106,7 @@ msgstr "convert() çš„å‚æ•°ç±»åž‹æ— 效,请使用 TYPE_* 常é‡ã€‚" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp msgid "Expected a string of length 1 (a character)." -msgstr "应为长度为 1 çš„å—符串(1个å—符)。" +msgstr "应为长度为 1 çš„å—符串(å•个å—符)。" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/mono/glue/gd_glue.cpp @@ -399,9 +399,8 @@ msgid "Duplicate Key(s)" msgstr "å¤åˆ¶å…³é”®å¸§" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add RESET Value(s)" -msgstr "æ·»åŠ %d 帧" +msgstr "æ·»åŠ RESET 值" #: editor/animation_track_editor.cpp msgid "Delete Key(s)" @@ -438,6 +437,7 @@ msgstr "æ˜¯å¦æ–°å»º %d 个轨é“å¹¶æ’入关键帧?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -521,11 +521,11 @@ msgstr "æ·»åŠ è´å¡žå°”轨é“" #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a key." -msgstr "轨é“è·¯å¾„æ— æ•ˆï¼Œå› æ¤æ— æ³•æ·»åŠ é”®ã€‚" +msgstr "轨é“è·¯å¾„æ— æ•ˆï¼Œå› æ¤æ— æ³•æ·»åŠ å…³é”®å¸§ã€‚" #: editor/animation_track_editor.cpp msgid "Track is not of type Spatial, can't insert key" -msgstr "轨é“䏿˜¯ Spatial ç±»åž‹ï¼Œæ— æ³•æ’入帧" +msgstr "轨é“䏿˜¯ Spatial ç±»åž‹ï¼Œæ— æ³•æ’入关键帧" #: editor/animation_track_editor.cpp msgid "Add Transform Track Key" @@ -570,9 +570,8 @@ msgid "" msgstr "ç”±äºŽåªæœ‰å•一轨é“ï¼Œå› æ¤è¯¥é€‰é¡¹ä¸é€‚用于è´å¡žå°”编辑。" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Add RESET Keys" -msgstr "缩放动画关键帧" +msgstr "æ·»åŠ åŠ¨ç”» RESET 关键帧" #: editor/animation_track_editor.cpp msgid "" @@ -898,6 +897,7 @@ msgstr "æ·»åŠ " #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -947,8 +947,7 @@ msgstr "æ— æ³•è¿žæŽ¥ä¿¡å·" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1386,15 +1385,15 @@ msgstr "修改音频总线音é‡" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Solo" -msgstr "å¼€ï¼å…³éŸ³é¢‘总线独å¥" +msgstr "开关音频总线独å¥" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Mute" -msgstr "é™éŸ³ï¼å–消é™éŸ³éŸ³é¢‘总线" +msgstr "开关音频总线é™éŸ³" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Bypass Effects" -msgstr "å¼€å¯ï¼å…³é—音频总线æ—通效果" +msgstr "开关音频总线æ—通效果" #: editor/editor_audio_buses.cpp msgid "Select Audio Bus Send" @@ -1410,7 +1409,7 @@ msgstr "移动总线效果" #: editor/editor_audio_buses.cpp msgid "Delete Bus Effect" -msgstr "åˆ é™¤éŸ³é¢‘æ€»çº¿æ•ˆæžœ" +msgstr "åˆ é™¤æ€»çº¿æ•ˆæžœ" #: editor/editor_audio_buses.cpp msgid "Drag & drop to rearrange." @@ -1455,7 +1454,7 @@ msgstr "æ·»åŠ éŸ³é¢‘æ€»çº¿" #: editor/editor_audio_buses.cpp msgid "Master bus can't be deleted!" -msgstr "ä¸èƒ½åˆ 除主音频总线ï¼" +msgstr "ä¸èƒ½åˆ 除主总线ï¼" #: editor/editor_audio_buses.cpp msgid "Delete Audio Bus" @@ -1545,7 +1544,7 @@ msgstr "åç§°æ— æ•ˆã€‚" #: editor/editor_autoload_settings.cpp msgid "Cannot begin with a digit." -msgstr "" +msgstr "æ— æ³•ä»¥æ•°å—开头。" #: editor/editor_autoload_settings.cpp msgid "Valid characters:" @@ -1990,7 +1989,6 @@ msgid "New Folder..." msgstr "新建文件夹..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "刷新" @@ -2107,7 +2105,8 @@ msgstr "目录与文件:" msgid "Preview:" msgstr "预览:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "文件:" @@ -2155,9 +2154,8 @@ msgid "Properties" msgstr "属性" #: editor/editor_help.cpp -#, fuzzy msgid "overrides %s:" -msgstr "覆盖:" +msgstr "覆盖 %s:" #: editor/editor_help.cpp msgid "default:" @@ -2280,7 +2278,7 @@ msgstr "方法" msgid "Signal" msgstr "ä¿¡å·" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "常é‡" @@ -2297,20 +2295,21 @@ msgid "Property:" msgstr "属性:" #: editor/editor_inspector.cpp -#, fuzzy msgid "Pin value" -msgstr "(值)" +msgstr "固定值" #: editor/editor_inspector.cpp msgid "" "Pinning a value forces it to be saved even if it's equal to the default." -msgstr "" +msgstr "将值固定会强制ä¿å˜è¿™ä¸ªå€¼ï¼Œå³ä¾¿å®ƒä¸Žé»˜è®¤å€¼ç›¸ç‰ã€‚" #: editor/editor_inspector.cpp msgid "Pin value [Disabled because '%s' is editor-only]" -msgstr "" +msgstr "固定值 [å·²ç¦ç”¨ï¼Œå› 为“%sâ€ä»…适用于编辑器]" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "设置 %s" @@ -2321,26 +2320,23 @@ msgstr "批é‡è®¾ç½®ï¼š" #: editor/editor_inspector.cpp msgid "Pinned %s" -msgstr "" +msgstr "å°† %s 固定" #: editor/editor_inspector.cpp msgid "Unpinned %s" -msgstr "" +msgstr "å°† %s 解除固定" #: editor/editor_inspector.cpp -#, fuzzy msgid "Copy Property" msgstr "å¤åˆ¶å±žæ€§" #: editor/editor_inspector.cpp -#, fuzzy msgid "Paste Property" msgstr "粘贴属性" #: editor/editor_inspector.cpp -#, fuzzy msgid "Copy Property Path" -msgstr "å¤åˆ¶è„šæœ¬è·¯å¾„" +msgstr "å¤åˆ¶å±žæ€§è·¯å¾„" #: editor/editor_log.cpp msgid "Output:" @@ -2932,7 +2928,7 @@ msgstr "切æ¢ä¸“注模å¼ã€‚" #: editor/editor_node.cpp msgid "Add a new scene." -msgstr "æ·»åŠ åœºæ™¯ã€‚" +msgstr "æ·»åŠ æ–°åœºæ™¯ã€‚" #: editor/editor_node.cpp msgid "Scene" @@ -3038,8 +3034,9 @@ msgid "Install Android Build Template..." msgstr "安装 Android 构建模æ¿..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "æ‰“å¼€é¡¹ç›®æ•°æ®æ–‡ä»¶å¤¹" +#, fuzzy +msgid "Open User Data Folder" +msgstr "打开 “编辑器数æ®â€ 文件夹" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3120,7 +3117,7 @@ msgstr "å¯ç”¨è¯¥é€‰é¡¹æ—¶ï¼Œå¯¼èˆªç½‘æ ¼å’Œå¤šè¾¹å½¢å°†åœ¨é¡¹ç›®è¿è¡Œæ—¶å¯è§ #: editor/editor_node.cpp msgid "Force Shader Fallbacks" -msgstr "" +msgstr "强制备用ç€è‰²å™¨" #: editor/editor_node.cpp msgid "" @@ -3131,6 +3128,10 @@ msgid "" "Asynchronous shader compilation must be enabled in the project settings for " "this option to make a difference." msgstr "" +"å¯ç”¨è¯¥é€‰é¡¹æ—¶ï¼Œç€è‰²å™¨åœ¨è¿è¡Œæ—¶ä¼šä½¿ç”¨å…¶å¤‡ç”¨å½¢å¼ï¼ˆå€ŸåŠ©è¶…çº§ç€è‰²å™¨æ˜¾ç¤ºæˆ–è€…ä¸æ˜¾" +"示)。\n" +"å¯ç”¨äºŽéªŒè¯å¤‡ç”¨å¤–观和性能,æ£å¸¸æƒ…况下åªä¼šçŸæš‚显示。\n" +"必须在项目设置ä¸å¯ç”¨å¼‚æ¥ç€è‰²å™¨ç¼–译,该选项æ‰ä¼šæœ‰æ•ˆæžœã€‚" #: editor/editor_node.cpp msgid "Synchronize Scene Changes" @@ -3185,10 +3186,6 @@ msgid "Toggle Fullscreen" msgstr "切æ¢å…¨å±æ¨¡å¼" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "打开ï¼å…³é—系统命令行" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "打开 “编辑器数æ®/设置†文件夹" @@ -3415,6 +3412,7 @@ msgid "Load Errors" msgstr "åŠ è½½é”™è¯¯" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "选择" @@ -3491,7 +3489,6 @@ msgid "Author" msgstr "作者" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "状æ€" @@ -3727,6 +3724,12 @@ msgstr "场景路径:" msgid "Import From Node:" msgstr "从节点ä¸å¯¼å…¥ï¼š" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "错误" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "打开包å«è¿™äº›æ¨¡æ¿çš„æ–‡ä»¶å¤¹ã€‚" @@ -4254,9 +4257,8 @@ msgid "Replace..." msgstr "替æ¢..." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Replace in Files" -msgstr "全部替æ¢" +msgstr "åœ¨æ–‡ä»¶ä¸æ›¿æ¢" #: editor/find_in_files.cpp msgid "Find: " @@ -4267,9 +4269,8 @@ msgid "Replace: " msgstr "替æ¢ï¼š " #: editor/find_in_files.cpp -#, fuzzy msgid "Replace All (NO UNDO)" -msgstr "全部替æ¢" +msgstr "全部替æ¢ï¼ˆæ— 法撤销)" #: editor/find_in_files.cpp msgid "Searching..." @@ -4489,7 +4490,7 @@ msgstr "è¦å‘Šï¼šå˜åœ¨ä½¿ç”¨æœ¬èµ„æºçš„ç´ æï¼Œå°†ä¼šåœæ¢åŠ è½½ã€‚" msgid "" "Select a resource file in the filesystem or in the inspector to adjust " "import settings." -msgstr "" +msgstr "è¦è°ƒæ•´å¯¼å…¥è®¾ç½®ï¼Œè¯·åœ¨æ–‡ä»¶ç³»ç»Ÿæˆ–检查器ä¸é€‰ä¸èµ„æºæ–‡ä»¶ã€‚" #: editor/inspector_dock.cpp msgid "Failed to load resource." @@ -4598,6 +4599,7 @@ msgid "Subfolder:" msgstr "åæ–‡ä»¶å¤¹ï¼š" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "作者:" @@ -5694,7 +5696,7 @@ msgstr "创建垂直水平å‚考线" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)" -msgstr "å°† CanvasItem“%sâ€çš„ Pivot Offset 设为 (%d, %d)" +msgstr "å°† CanvasItem“%sâ€çš„轴心åç§»é‡è®¾ä¸º (%d, %d)" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotate %d CanvasItems" @@ -5922,20 +5924,19 @@ msgstr "选择模å¼" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Drag: Rotate selected node around pivot." -msgstr "拖动:围绕ä¸å¿ƒç‚¹æ—‹è½¬æ‰€é€‰èŠ‚ç‚¹ã€‚" +msgstr "拖动:围绕轴心旋转所选节点。" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Alt+Drag: Move selected node." msgstr "Alt+拖动:移动所选节点。" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Alt+Drag: Scale selected node." -msgstr "Alt+拖动:移动所选节点。" +msgstr "Alt+拖动:缩放所选节点。" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "V: Set selected node's pivot position." -msgstr "V:设置所选节点的ä¸å¿ƒç‚¹ä½ç½®ã€‚" +msgstr "V:设置所选节点的轴心ä½ç½®ã€‚" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5963,7 +5964,7 @@ msgstr "缩放模å¼" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Shift: Scale proportionally." -msgstr "" +msgstr "Shift:按比例缩放。" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5976,7 +5977,7 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Click to change object's rotation pivot." -msgstr "点击设置对象的旋转ä¸å¿ƒã€‚" +msgstr "点击更改对象的旋转轴心。" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Pan Mode" @@ -6062,9 +6063,8 @@ msgstr "将所选对象é”定到该ä½ç½®ï¼ˆæ— 法移动)。" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected Node(s)" -msgstr "é”定所选项" +msgstr "é”定所选节点" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6073,9 +6073,8 @@ msgstr "è§£é”æ‰€é€‰å¯¹è±¡ï¼ˆå¯ä»¥ç§»åŠ¨ï¼‰ã€‚" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected Node(s)" -msgstr "è§£é”æ‰€é€‰é¡¹" +msgstr "è§£é”æ‰€é€‰èŠ‚ç‚¹" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6084,9 +6083,8 @@ msgstr "ç¡®ä¿å¯¹è±¡çš„å项ä¸å¯é€‰æ‹©ã€‚" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected Node(s)" -msgstr "编组所选项" +msgstr "编组所选节点" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6095,9 +6093,8 @@ msgstr "æ¢å¤é€‰æ‹©å¯¹è±¡çš„å级的功能。" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected Node(s)" -msgstr "解组所选项" +msgstr "解组所选节点" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Skeleton Options" @@ -6268,6 +6265,7 @@ msgid "Zoom to 1600%" msgstr "缩放至 1600%" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "æ·»åŠ %s" @@ -7291,7 +7289,7 @@ msgstr "翻转入å£" #: editor/plugins/room_manager_editor_plugin.cpp msgid "Occluder Set Transform" -msgstr "鮿Œ¡é›†å˜æ¢" +msgstr "鮿Œ¡è®¾ç½®å˜æ¢" #: editor/plugins/room_manager_editor_plugin.cpp msgid "Center Node" @@ -7388,7 +7386,7 @@ msgstr "主题å¦å˜ä¸º..." #: editor/plugins/script_editor_plugin.cpp msgid "%s Class Reference" -msgstr "%s ç±»å‚考手册" +msgstr "%s ç±»å‚考" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -7541,7 +7539,7 @@ msgstr "打开 Godot 在线文档。" #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." -msgstr "æœç´¢æ–‡æ¡£ã€‚" +msgstr "æœç´¢å‚考文档。" #: editor/plugins/script_editor_plugin.cpp msgid "Go to previous edited document." @@ -7722,9 +7720,8 @@ msgid "Find in Files..." msgstr "åœ¨æ–‡ä»¶ä¸æŸ¥æ‰¾..." #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Replace in Files..." -msgstr "替æ¢..." +msgstr "åœ¨æ–‡ä»¶ä¸æ›¿æ¢..." #: editor/plugins/script_text_editor.cpp msgid "Contextual Help" @@ -7785,7 +7782,7 @@ msgstr "ç€è‰²å™¨" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "This skeleton has no bones, create some children Bone2D nodes." -msgstr "该骨架没有骨骼绑定,请创建一些 Bone2D 骨骼å节点。" +msgstr "该骨架没有骨骼,请创建一些 Bone2D å节点。" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "Set Rest Pose to Bones" @@ -7797,7 +7794,7 @@ msgstr "从骨骼创建放æ¾å§¿åŠ¿" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "Skeleton2D" -msgstr "2D 骨骼节点" +msgstr "Skeleton2D" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "Reset to Rest Pose" @@ -7813,7 +7810,7 @@ msgstr "创建物ç†éª¨éª¼" #: editor/plugins/skeleton_editor_plugin.cpp msgid "Skeleton" -msgstr "骨架" +msgstr "Skeleton" #: editor/plugins/skeleton_editor_plugin.cpp msgid "Create physical skeleton" @@ -7942,7 +7939,7 @@ msgstr "旋转 %s 度。" #: editor/plugins/spatial_editor_plugin.cpp msgid "Keying is disabled (no key inserted)." -msgstr "键控被ç¦ç”¨ï¼ˆæœªæ’入键)。" +msgstr "å·²ç¦ç”¨å…³é”®å¸§æ’入(未æ’入关键帧)。" #: editor/plugins/spatial_editor_plugin.cpp msgid "Animation Key Inserted." @@ -8249,16 +8246,15 @@ msgstr "切æ¢è‡ªç”±è§‚看" #: editor/plugins/spatial_editor_plugin.cpp msgid "Decrease Field of View" -msgstr "" +msgstr "å‡å°è§†é‡Ž" #: editor/plugins/spatial_editor_plugin.cpp msgid "Increase Field of View" -msgstr "" +msgstr "增大视野" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Reset Field of View to Default" -msgstr "é‡ç½®ä¸ºé»˜è®¤å€¼" +msgstr "é‡ç½®ä¸ºé»˜è®¤è§†é‡Ž" #: editor/plugins/spatial_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8460,7 +8456,7 @@ msgstr "创建 LightOccluder2D 兄弟节点" #: editor/plugins/sprite_editor_plugin.cpp msgid "Sprite" -msgstr "ç²¾çµ" +msgstr "Sprite" #: editor/plugins/sprite_editor_plugin.cpp msgid "Simplification: " @@ -8983,22 +8979,19 @@ msgstr "æ·»åŠ ç±»åž‹" #: editor/plugins/theme_editor_plugin.cpp msgid "Filter the list of types or create a new custom type:" -msgstr "" +msgstr "过滤类型列表或新建自定义类型:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Available Node-based types:" -msgstr "å¯ç”¨é…置文件:" +msgstr "å¯ç”¨ Node 类型:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Type name is empty!" -msgstr "文件å为空。" +msgstr "类型å称为空ï¼" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Are you sure you want to create an empty type?" -msgstr "æ‚¨ç¡®å®šè¦æ‰“开多个项目å—?" +msgstr "确定è¦åˆ›å»ºç©ºç±»åž‹å—?" #: editor/plugins/theme_editor_plugin.cpp msgid "Confirm Item Rename" @@ -9609,7 +9602,8 @@ msgid "TileSet" msgstr "图å—集" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "没有å¯ç”¨çš„ VCS æ’件。" #: editor/plugins/version_control_editor_plugin.cpp @@ -9617,16 +9611,56 @@ msgid "Error" msgstr "错误" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "æ²¡æœ‰æ–‡ä»¶è¢«æ·»åŠ åˆ°æš‚å˜åŒº" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "没有æä¾›å称。" #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "æäº¤" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "VCS æ’件未åˆå§‹åŒ–" +#, fuzzy +msgid "Staged Changes" +msgstr "ç€è‰²å™¨å˜æ›´ï¼š" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "ç€è‰²å™¨å˜æ›´ï¼š" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "æäº¤" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "åæ ‘" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "确定è¦åˆ›å»ºç©ºç±»åž‹å—?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "应用é‡ç½®" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9637,16 +9671,148 @@ msgid "Initialize" msgstr "åˆå§‹åŒ–" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "æš‚å˜åŒºåŸŸ" +#, fuzzy +msgid "Remote Login" +msgstr "移除点" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "é‡å‘½å" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "检测新å˜åŒ–" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "修改" +#, fuzzy +msgid "Discard all changes" +msgstr "å…³é—å¹¶ä¿å˜æ›´æ”¹å—?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "ä¿å˜æœ¬åœ°æ›´æ”¹..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "æè´¨å˜æ›´ï¼š" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "æäº¤å˜æ›´" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "æäº¤å˜æ›´" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "æäº¤" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "匹é…项:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "新建项目" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "移除动画轨é“" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "远程" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "新建项目" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "移除项目" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "远程 " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "远程 " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "æºç½‘æ ¼ï¼š" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9665,28 +9831,23 @@ msgid "Typechange" msgstr "类型更改" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "将选定放入暂å˜åŒº" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "æš‚å˜å…¨éƒ¨" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "æäº¤å˜æ›´" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "在æäº¤åˆ°æœ€æ–°ç‰ˆæœ¬ä¹‹å‰æŸ¥çœ‹æ–‡ä»¶å·®å¼‚" +#, fuzzy +msgid "View:" +msgstr "视图" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "没有文件差异处于活动状æ€" +#, fuzzy +msgid "Split" +msgstr "拆分路径" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "检测文件差异的å˜åŒ–" +#, fuzzy +msgid "Unified" +msgstr "已修改" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -9883,15 +10044,15 @@ msgstr "è¿”å›žä¸¤ä¸ªå‚æ•°ä¹‹é—´ %s 比较的布尔结果。" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Equal (==)" -msgstr "ç‰äºŽ (==)" +msgstr "ç‰äºŽï¼ˆ==)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Greater Than (>)" -msgstr "大于 (>)" +msgstr "大于(>)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Greater Than or Equal (>=)" -msgstr "大于或ç‰äºŽ (>=)" +msgstr "大于ç‰äºŽï¼ˆ>=)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9913,15 +10074,15 @@ msgstr "返回 NaN å’Œæ ‡é‡å‚数之间比较的布尔结果。" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Less Than (<)" -msgstr "å°äºŽ (<)" +msgstr "å°äºŽï¼ˆ<)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Less Than or Equal (<=)" -msgstr "å°äºŽæˆ–ç‰äºŽ (<=)" +msgstr "å°äºŽç‰äºŽï¼ˆ<=)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Not Equal (!=)" -msgstr "ä¸ç‰äºŽ (!=)" +msgstr "ä¸ç‰äºŽï¼ˆ!=)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -10525,7 +10686,7 @@ msgstr "(仅é™ç‰‡æ®µ/光照模å¼ï¼‰ï¼ˆæ ‡é‡ï¼‰â€œx†和 “y†ä¸çš„ç» #: editor/plugins/visual_shader_editor_plugin.cpp msgid "VisualShader" -msgstr "å¯è§†ç€è‰²å™¨" +msgstr "VisualShader" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Edit Visual Property:" @@ -11766,6 +11927,9 @@ msgid "" "To save this branch into its own scene, open the original scene, right click " "on this branch, and select \"Save Branch as Scene\"." msgstr "" +"æ— æ³•ä¿å˜åˆ†æ”¯ï¼Œè¯¥åˆ†æ”¯æ˜¯å®žä¾‹åŒ–场景的å项。\n" +"如果è¦å°†è¯¥åˆ†æ”¯ä¿å˜ä¸ºå•独的场景,请先打开原始场景,å³é”®å•击该分支,然åŽé€‰æ‹©â€œå°†" +"分支ä¿å˜ä¸ºåœºæ™¯â€ã€‚" #: editor/scene_tree_dock.cpp msgid "" @@ -11773,6 +11937,9 @@ msgid "" "To save this branch into its own scene, open the original scene, right click " "on this branch, and select \"Save Branch as Scene\"." msgstr "" +"æ— æ³•ä¿å˜åˆ†æ”¯ï¼Œè¯¥åˆ†æ”¯æ˜¯ç»§æ‰¿åœºæ™¯çš„å项。\n" +"如果è¦å°†è¯¥åˆ†æ”¯ä¿å˜ä¸ºå•独的场景,请先打开原始场景,å³é”®å•击该分支,然åŽé€‰æ‹©â€œå°†" +"分支ä¿å˜ä¸ºåœºæ™¯â€ã€‚" #: editor/scene_tree_dock.cpp msgid "Save New Scene As..." @@ -12299,6 +12466,7 @@ msgid "Export list to a CSV file" msgstr "将列表导出为 CSV 文件" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "资æºè·¯å¾„" @@ -12696,11 +12864,11 @@ msgstr "生æˆç¼“冲区" #: modules/lightmapper_cpu/lightmapper_cpu.cpp msgid "Direct lighting" -msgstr "直接照明" +msgstr "直接光照" #: modules/lightmapper_cpu/lightmapper_cpu.cpp msgid "Indirect lighting" -msgstr "间接照明" +msgstr "间接光照" #: modules/lightmapper_cpu/lightmapper_cpu.cpp msgid "Post processing" @@ -12937,19 +13105,19 @@ msgstr "å¤åˆ¶ VisualScript 节点" #: modules/visual_script/visual_script_editor.cpp msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature." -msgstr "æŒ‰ä½ %s 放置一个 Getter èŠ‚ç‚¹ï¼ŒæŒ‰ä½ Shift 键放置一个通用ç¾å。" +msgstr "æŒ‰ä½ %s 放置 Getter èŠ‚ç‚¹ï¼ŒæŒ‰ä½ Shift 键放置通用ç¾å。" #: modules/visual_script/visual_script_editor.cpp msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature." -msgstr "æŒ‰ä½ Ctrl 键放置一个 Getter èŠ‚ç‚¹ã€‚æŒ‰ä½ Shift 键放置一个通用ç¾å。" +msgstr "æŒ‰ä½ Ctrl 键放置 Getter èŠ‚ç‚¹ã€‚æŒ‰ä½ Shift 键放置通用ç¾å。" #: modules/visual_script/visual_script_editor.cpp msgid "Hold %s to drop a simple reference to the node." -msgstr "æŒ‰ä½ %s 放置一个场景节点的引用节点。" +msgstr "æŒ‰ä½ %s 放置该节点的简å•引用。" #: modules/visual_script/visual_script_editor.cpp msgid "Hold Ctrl to drop a simple reference to the node." -msgstr "æŒ‰ä½ Ctrl 键放置一个场景节点的引用节点。" +msgstr "æŒ‰ä½ Ctrl 键放置该节点的简å•引用。" #: modules/visual_script/visual_script_editor.cpp msgid "Hold %s to drop a Variable Setter." @@ -13131,6 +13299,40 @@ msgstr "刷新节点" msgid "Edit Member" msgstr "编辑æˆå‘˜" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "设置表达å¼" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "动画" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "输入类型ä¸å¯è¿ä»£ï¼š " @@ -13143,6 +13345,88 @@ msgstr "è¿ä»£å™¨å¤±æ•ˆ" msgid "Iterator became invalid: " msgstr "è¿ä»£å™¨å¤±æ•ˆï¼š " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "é‡å‘½å文件夹:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "俯仰角:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "类型:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "仅自己" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "ä½äºŽå—符 %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "æ·»åŠ %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "设置 %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "å°† %s 固定" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "èŽ·å– %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "属性åç§°ç´¢å¼•æ— æ•ˆã€‚" @@ -13159,6 +13443,21 @@ msgstr "路径必须指å‘节点ï¼" msgid "Invalid index property name '%s' in node %s." msgstr "节点 “%s†的索引属性å “%sâ€ æ— æ•ˆã€‚" +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "设置 %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "函数" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "调整数组大å°" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": æ— æ•ˆå‚æ•°ç±»åž‹: " @@ -13168,6 +13467,10 @@ msgid ": Invalid arguments: " msgstr ": æ— æ•ˆå‚æ•°: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "è„šæœ¬ä¸æœªæ‰¾åˆ° VariableGet: " @@ -13176,6 +13479,66 @@ msgid "VariableSet not found in script: " msgstr "è„šæœ¬ä¸æœªæ‰¾åˆ° VariableSet: " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "釿–°åŠ è½½" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Z 索引" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Z 索引" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "常é‡" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "常é‡" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "常é‡" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "常é‡" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "å¯ç”¨çš„ GDNative å•例" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "TimeSeek 节点" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "åœºæ™¯æ ‘ç¼–è¾‘" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "仅自己" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "剪切节点" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "自定义节点ä¸åŒ…å« _step() 方法,ä¸èƒ½ç”Ÿæˆå›¾åƒã€‚" @@ -13185,13 +13548,75 @@ msgid "" "(error)." msgstr "_step() çš„è¿”å›žå€¼æ— æ•ˆï¼Œå¿…é¡»æ˜¯æ•´å½¢ (Seq Out) 或å—符串 (Error)。" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "调用" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "常é‡" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "使用本地空间" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "使用本地空间" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "动作" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" -msgstr "æœç´¢å¯è§†åŒ–脚本节点" +msgstr "æœç´¢ VisualScript" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "èŽ·å– %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "移动帧" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "物ç†å¸§ %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "ä¿¡å·" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "ä¿¡å·" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "实例化" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -13756,13 +14181,13 @@ msgstr "æ¤é®å…‰ä½“çš„é®å…‰å¤šè¾¹å½¢ä¸ºç©ºã€‚请绘制一个多边形。" #: scene/2d/navigation_agent_2d.cpp msgid "The NavigationAgent2D can be used only under a Node2D node." -msgstr "" +msgstr "NavigationAgent2D åªèƒ½åœ¨ Node2D 节点下使用。" #: scene/2d/navigation_obstacle_2d.cpp msgid "" "The NavigationObstacle2D only serves to provide collision avoidance to a " "Node2D object." -msgstr "" +msgstr "NavigationObstacle2D åªèƒ½ç”¨äºŽä¸º Node2D 对象é¿å…碰撞。" #: scene/2d/navigation_polygon.cpp msgid "" @@ -13786,14 +14211,24 @@ msgstr "" "ParallaxLayer 类型的节点必须作为 ParallaxBackground çš„å节点æ‰èƒ½æ£å¸¸å·¥ä½œã€‚" #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "基于 GPU 的粒åä¸å— GLES2 视频驱动程åºçš„æ”¯æŒã€‚\n" "改为使用 CPUParticles2D 节点。为æ¤ï¼Œå¯ä»¥ä½¿ç”¨ “转æ¢ä¸º CPUParticles†选项。" +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -13981,7 +14416,7 @@ msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." msgstr "" -"GLES2 视频驱动程åºä¸æ”¯æŒ GIProbes。\n" +"GLES2 视频驱动程åºä¸æ”¯æŒ GIProbe。\n" "请改用 BakedLightmap。" #: scene/3d/gi_probe.cpp @@ -13999,7 +14434,7 @@ msgstr "角度宽于 90 度的 SpotLight æ— æ³•æŠ•å°„å‡ºé˜´å½±ã€‚" #: scene/3d/navigation_agent.cpp msgid "The NavigationAgent can be used only under a spatial node." -msgstr "" +msgstr "NavigationAgent åªèƒ½åœ¨ Spatial 节点下使用。" #: scene/3d/navigation_mesh_instance.cpp msgid "" @@ -14013,7 +14448,7 @@ msgstr "" msgid "" "The NavigationObstacle only serves to provide collision avoidance to a " "spatial object." -msgstr "" +msgstr "NavigationObstacle åªèƒ½ç”¨äºŽä¸º Spatial 对象é¿å…碰撞。" #: scene/3d/occluder.cpp msgid "No shape is set." @@ -14024,16 +14459,25 @@ msgid "Only uniform scales are supported." msgstr "仅支æŒç»Ÿä¸€çš„缩放。" #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "基于 GPU 的粒åä¸å— GLES2 视频驱动程åºçš„æ”¯æŒã€‚\n" "改为使用 CPUParticles 节点。为æ¤ï¼Œæ‚¨å¯ä»¥ä½¿ç”¨ “转æ¢ä¸º CPUParticles†选项。" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "ç²’åä¸å¯è§ï¼Œå› ä¸ºæ²¡æœ‰ç½‘æ ¼æŒ‡å®šåˆ°ç»˜åˆ¶é€šé“ (Draw Pass)。" diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po index e9cd6f0e5f..a6ee771fa8 100644 --- a/editor/translations/zh_HK.po +++ b/editor/translations/zh_HK.po @@ -383,6 +383,7 @@ msgstr "新增 %d 個新軌跡並æ’入關éµå¹€ï¼Ÿ" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -870,6 +871,7 @@ msgstr "æ·»åŠ " #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -919,8 +921,7 @@ msgstr "無法連接訊號" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -2016,7 +2017,6 @@ msgid "New Folder..." msgstr "新增資料夾" #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "釿–°æ•´ç†" @@ -2141,7 +2141,8 @@ msgstr "資料夾和檔案:" msgid "Preview:" msgstr "é 覽:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "檔案:" @@ -2325,7 +2326,7 @@ msgstr "" msgid "Signal" msgstr "訊號" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "常數" @@ -2355,6 +2356,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "" @@ -3100,7 +3103,7 @@ msgstr "" #: editor/editor_node.cpp #, fuzzy -msgid "Open Project Data Folder" +msgid "Open User Data Folder" msgstr "開啟 Project Manager?" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp @@ -3244,11 +3247,6 @@ msgstr "全螢幕" #: editor/editor_node.cpp #, fuzzy -msgid "Toggle System Console" -msgstr "(ä¸ï¼‰é¡¯ç¤ºéš±è—的文件" - -#: editor/editor_node.cpp -#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "編輯器è¨å®š" @@ -3480,6 +3478,7 @@ msgid "Load Errors" msgstr "載入錯誤" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "é¸å–" @@ -3567,7 +3566,6 @@ msgid "Author" msgstr "作者" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "" @@ -3801,6 +3799,12 @@ msgstr "å ´æ™¯è·¯å¾‘:" msgid "Import From Node:" msgstr "從Node導入:" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "錯誤!" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "" @@ -4751,6 +4755,7 @@ msgid "Subfolder:" msgstr "" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp #, fuzzy msgid "Author:" msgstr "作者:" @@ -6523,6 +6528,7 @@ msgid "Zoom to 1600%" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "" @@ -10068,7 +10074,7 @@ msgid "TileSet" msgstr "TileSet..." #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +msgid "No VCS plugins are available." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -10076,19 +10082,57 @@ msgid "Error" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy +msgid "No commit message was provided." +msgstr "沒有æä¾›åå—。" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy msgid "Commit" msgstr "社群" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" +#, fuzzy +msgid "Staged Changes" +msgstr "當改變時更新" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "當改變時更新" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "社群" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Subtitle:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s remote?" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "é‡è¨ç¸®æ”¾æ¯”例" + +#: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" msgstr "" @@ -10097,7 +10141,37 @@ msgid "Initialize" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" +#, fuzzy +msgid "Remote Login" +msgstr "åªé™é¸ä¸" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "釿–°å‘½å" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp @@ -10107,53 +10181,145 @@ msgstr "新增" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Changes" +msgid "Discard all changes" +msgstr "è¦é—œé–‰å ´æ™¯å—Žï¼Ÿï¼ˆæœªå„²å˜çš„æ›´æ”¹å°‡æœƒæ¶ˆå¤±ï¼‰" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "å„²å˜æœ¬åœ°æ›´æ”¹..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" msgstr "當改變時更新" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Modified" +#, fuzzy +msgid "Commit Message" +msgstr "åŒæ¥æ›´æ–°è…³æœ¬" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Changes" +msgstr "åŒæ¥æ›´æ–°è…³æœ¬" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "社群" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Renamed" -msgstr "釿–°å‘½å..." +msgid "Branches" +msgstr "å»åˆï¼š" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Deleted" -msgstr "刪除" +msgid "Create New Branch" +msgstr "新增" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Typechange" -msgstr "當改變時更新" +msgid "Remove Branch" +msgstr "移除動畫軌跡" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage Selected" -msgstr "刪除é¸ä¸æª”案" +msgid "Remotes" +msgstr "移除" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Stage All" -msgstr "å…¨é¸" +msgid "Create New Remote" +msgstr "新增" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy -msgid "Commit Changes" -msgstr "åŒæ¥æ›´æ–°è…³æœ¬" +msgid "Remove Remote" +msgstr "移除é¸é …" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "移除" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "移除" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" +msgid "Pull" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" +msgid "Push" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" +msgid "Force Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Renamed" +msgstr "釿–°å‘½å..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Deleted" +msgstr "刪除" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Typechange" +msgstr "當改變時更新" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unmerged" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "View:" +msgstr "é 覽:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Split" +msgstr "編輯Node Curve" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Unified" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -12815,6 +12981,7 @@ msgid "Export list to a CSV file" msgstr "匯出" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "" @@ -13704,6 +13871,39 @@ msgstr "釿–°æ•´ç†" msgid "Edit Member" msgstr "檔案" +#: modules/visual_script/visual_script_expression.cpp +msgid "Expression" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "新增動畫" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "" @@ -13716,6 +13916,82 @@ msgstr "" msgid "Iterator became invalid: " msgstr "" +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "釿–°å‘½å資料夾:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Switch" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Type Cast" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On Self" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "有效å—符:" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Mod %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftLeft %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitAnd %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "" @@ -13732,6 +14008,19 @@ msgstr "" msgid "Invalid index property name '%s' in node %s." msgstr "" +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Emit %s" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "行為" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Compose Array" +msgstr "" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr "" @@ -13741,6 +14030,10 @@ msgid ": Invalid arguments: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "" @@ -13749,6 +14042,62 @@ msgid "VariableSet not found in script: " msgstr "" #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "新增節點" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Index" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "常數" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "常數" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "常數" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "常數" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Engine Singleton" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "儲å˜å ´æ™¯" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "峿™‚編輯" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Self" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "貼上" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" @@ -13758,15 +14107,74 @@ msgid "" "(error)." msgstr "" +#: modules/visual_script/visual_script_nodes.cpp +msgid "SubCall" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "常數" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Get Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Set Local Var" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "行為" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp #, fuzzy msgid "Search VisualScript" msgstr "貼上" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "移動模å¼" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "物ç†å¹€ %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" msgstr "" +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "訊號" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "訊號" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "Instance" + #: platform/android/export/export_plugin.cpp msgid "Package name is missing." msgstr "" @@ -14359,7 +14767,16 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." msgstr "" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -14574,7 +14991,15 @@ msgstr "" msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." msgstr "" #: scene/3d/particles.cpp diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po index c75612316a..ba318ee632 100644 --- a/editor/translations/zh_TW.po +++ b/editor/translations/zh_TW.po @@ -383,6 +383,7 @@ msgstr "確定è¦å»ºç«‹ %d 個動畫軌並æ’å…¥ç•«æ ¼å—Žï¼Ÿ" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -843,6 +844,7 @@ msgstr "新增" #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" @@ -892,8 +894,7 @@ msgstr "無法連接訊號" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#: editor/plugins/theme_editor_plugin.cpp -#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/property_editor.cpp #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp @@ -1939,7 +1940,6 @@ msgid "New Folder..." msgstr "新增資料夾..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp -#: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" msgstr "釿–°æ•´ç†" @@ -2056,7 +2056,8 @@ msgstr "資料夾與檔案:" msgid "Preview:" msgstr "é 覽:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +#: editor/editor_file_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "File:" msgstr "檔案:" @@ -2227,7 +2228,7 @@ msgstr "方法" msgid "Signal" msgstr "訊號" -#: editor/editor_help_search.cpp +#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp msgid "Constant" msgstr "常數" @@ -2258,6 +2259,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]" msgstr "" #: editor/editor_inspector.cpp editor/scene_tree_dock.cpp +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" msgstr "è¨å®š %s" @@ -2985,8 +2988,9 @@ msgid "Install Android Build Template..." msgstr "å®‰è£ Android 建置樣æ¿..." #: editor/editor_node.cpp -msgid "Open Project Data Folder" -msgstr "開啟專案資料目錄" +#, fuzzy +msgid "Open User Data Folder" +msgstr "開啟編輯器資料目錄" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -3132,10 +3136,6 @@ msgid "Toggle Fullscreen" msgstr "開啟ï¼å–消全螢幕顯示" #: editor/editor_node.cpp -msgid "Toggle System Console" -msgstr "開啟ï¼é—œé–‰ç³»çµ±ä¸»æŽ§å°" - -#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "開啟編輯器資料ï¼ç·¨è¼¯å™¨è¨å®šè³‡æ–™å¤¾" @@ -3362,6 +3362,7 @@ msgid "Load Errors" msgstr "載入錯誤" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Select" msgstr "鏿“‡" @@ -3438,7 +3439,6 @@ msgid "Author" msgstr "作者" #: editor/editor_plugin_settings.cpp -#: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" msgstr "狀態" @@ -3674,6 +3674,12 @@ msgstr "å ´æ™¯è·¯å¾‘ï¼š" msgid "Import From Node:" msgstr "自節點ä¸åŒ¯å…¥ï¼š" +#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). +#: editor/editor_vcs_interface.cpp +#, fuzzy +msgid "%s Error" +msgstr "錯誤" + #: editor/export_template_manager.cpp msgid "Open the folder containing these templates." msgstr "開啟包å«é€™äº›æ¨£æ¿çš„資料夾。" @@ -4545,6 +4551,7 @@ msgid "Subfolder:" msgstr "å資料夾:" #: editor/plugin_config_dialog.cpp +#: editor/plugins/version_control_editor_plugin.cpp msgid "Author:" msgstr "作者:" @@ -6214,6 +6221,7 @@ msgid "Zoom to 1600%" msgstr "縮放至1600%" #: editor/plugins/canvas_item_editor_plugin.cpp +#: modules/visual_script/visual_script_func_nodes.cpp msgid "Add %s" msgstr "新增 %" @@ -9555,7 +9563,8 @@ msgid "TileSet" msgstr "圖塊集" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No VCS addons are available." +#, fuzzy +msgid "No VCS plugins are available." msgstr "ç„¡å¯ç”¨çš„版本控制 (VCS) 擴充功能。" #: editor/plugins/version_control_editor_plugin.cpp @@ -9563,16 +9572,56 @@ msgid "Error" msgstr "錯誤" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No files added to stage" -msgstr "é å˜å€ç„¡æª”案" +msgid "" +"Remote settings are empty. VCS features that use the network may not work." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "No commit message was provided." +msgstr "未æä¾›å稱。" #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit" msgstr "æäº¤" #: editor/plugins/version_control_editor_plugin.cpp -msgid "VCS Addon is not initialized" -msgstr "VCS 擴充功能尚未åˆå§‹åŒ–" +#, fuzzy +msgid "Staged Changes" +msgstr "著色器變更:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstaged Changes" +msgstr "著色器變更:" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit:" +msgstr "æäº¤" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Date:" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Subtitle:" +msgstr "忍¹" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Do you want to remove the %s branch?" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Do you want to remove the %s remote?" +msgstr "ç¢ºå®šè¦æ‰“開多個專案嗎?" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Apply" +msgstr "套用é‡è¨" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -9583,16 +9632,148 @@ msgid "Initialize" msgstr "åˆå§‹åŒ–" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Staging area" -msgstr "é å˜å€" +#, fuzzy +msgid "Remote Login" +msgstr "移除控制點" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Username" +msgstr "釿–°å‘½å" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Password" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Public Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH public key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Private Key Path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Select SSH private key path" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "SSH Passphrase" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "嵿¸¬æ–°æ”¹å‹•" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Changes" -msgstr "改動" +#, fuzzy +msgid "Discard all changes" +msgstr "關閉並ä¿å˜ä¿®æ”¹å—Žï¼Ÿ" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Stage all changes" +msgstr "æ£åœ¨å„²å˜è®Šæ›´..." + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Unstage all changes" +msgstr "æè³ªè®Šæ›´ï¼š" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit Message" +msgstr "æäº¤æ”¹å‹•" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "æäº¤æ”¹å‹•" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Commit List" +msgstr "æäº¤" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit list size" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "10" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "20" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "30" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Branches" +msgstr "ç¬¦åˆæ¢ä»¶ï¼š" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Branch" +msgstr "建立新專案" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Branch" +msgstr "刪除動畫軌" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Branch Name" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remotes" +msgstr "é 端" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Create New Remote" +msgstr "建立新專案" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remove Remote" +msgstr "ç§»é™¤é …ç›®" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote Name" +msgstr "é 端 " + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Remote URL" +msgstr "é 端 " + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Fetch" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Pull" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Push" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#, fuzzy +msgid "Force Push" +msgstr "來æºç¶²æ ¼ï¼š" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -9611,28 +9792,23 @@ msgid "Typechange" msgstr "æ ¼å¼æ›´æ”¹" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage Selected" -msgstr "é å˜æ‰€é¸" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Stage All" -msgstr "é å˜å…¨éƒ¨" - -#: editor/plugins/version_control_editor_plugin.cpp -msgid "Commit Changes" -msgstr "æäº¤æ”¹å‹•" +msgid "Unmerged" +msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -msgid "View file diffs before committing them to the latest version" -msgstr "在æäº¤è‡³æœ€æ–°ç‰ˆæœ¬å‰æª¢è¦–檔案的差異" +#, fuzzy +msgid "View:" +msgstr "檢視" #: editor/plugins/version_control_editor_plugin.cpp -msgid "No file diff is active" -msgstr "無有效的檔案差異" +#, fuzzy +msgid "Split" +msgstr "拆分路徑" #: editor/plugins/version_control_editor_plugin.cpp -msgid "Detect changes in file diff" -msgstr "在檔案差異ä¸åµæ¸¬æ”¹å‹•" +#, fuzzy +msgid "Unified" +msgstr "已修改" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -12246,6 +12422,7 @@ msgid "Export list to a CSV file" msgstr "匯出列表至 CSV 檔案" #: editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_nodes.cpp msgid "Resource Path" msgstr "資æºè·¯å¾‘" @@ -13077,6 +13254,40 @@ msgstr "釿–°æ•´ç†åœ–表" msgid "Edit Member" msgstr "編輯æˆå“¡" +#: modules/visual_script/visual_script_expression.cpp +#, fuzzy +msgid "Expression" +msgstr "è¨å®šè¡¨ç¤ºå¼" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Return" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Condition" +msgstr "å‹•ç•«" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "if (cond) is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "While" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "while (cond):" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "for (elem) in (input):" +msgstr "" + #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " msgstr "輸入型別éžå¯è¿ä»£åž‹åˆ¥ï¼š " @@ -13089,6 +13300,88 @@ msgstr "è¿ä»£å™¨å·²ä¸å¯ç”¨" msgid "Iterator became invalid: " msgstr "è¿ä»£å™¨å·²ä¸å¯ç”¨ï¼š " +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Sequence" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "in order:" +msgstr "釿–°å‘½å資料夾:" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Switch" +msgstr "仰角:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "'input' is:" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy +msgid "Type Cast" +msgstr "類別:" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Is %s?" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "On %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "On Self" +msgstr "僅自己" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Subtract %s" +msgstr "使–¼å—å…ƒ %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Multiply %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Divide %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Mod %s" +msgstr "新增 %" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "ShiftLeft %s" +msgstr "è¨å®š %s" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "ShiftRight %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "BitAnd %s" +msgstr "新增 %" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitOr %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "BitXor %s" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +#: modules/visual_script/visual_script_nodes.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "å–å¾— %s" + #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." msgstr "無效的索引屬性å稱。" @@ -13105,6 +13398,21 @@ msgstr "路徑未指å‘節點ï¼" msgid "Invalid index property name '%s' in node %s." msgstr "無效的索引屬性å稱「%sã€ï¼Œæ–¼ç¯€é»žã€Œ%sã€ã€‚" +#: modules/visual_script/visual_script_func_nodes.cpp +#, fuzzy +msgid "Emit %s" +msgstr "è¨å®š %s" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Function" +msgstr "函å¼" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Compose Array" +msgstr "調整陣列大å°" + #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " msgstr ": 無效的引數型別: " @@ -13114,6 +13422,10 @@ msgid ": Invalid arguments: " msgstr ": 無效的引數: " #: modules/visual_script/visual_script_nodes.cpp +msgid "a if cond, else b" +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script: " msgstr "è…³æœ¬ä¸æœªæ‰¾åˆ° VariableGet(å–得變數): " @@ -13122,6 +13434,66 @@ msgid "VariableSet not found in script: " msgstr "è…³æœ¬ä¸æœªæ‰¾åˆ° VariableSet(è¨å®šè®Šæ•¸ï¼‰ï¼š " #: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Preload" +msgstr "釿–°è¼‰å…¥" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Index" +msgstr "Z 索引" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Index" +msgstr "Z 索引" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Global Constant" +msgstr "常數" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Class Constant" +msgstr "常數" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Basic Constant" +msgstr "常數" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Math Constant" +msgstr "常數" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Engine Singleton" +msgstr "啟用 GDNative 單例" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Node" +msgstr "TimeSeek 節點" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Scene Tree" +msgstr "æ£åœ¨ç·¨è¼¯å ´æ™¯æ¨¹" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Self" +msgstr "僅自己" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "CustomNode" +msgstr "剪下節點" + +#: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "自定節點沒有 _step() 方法,無法產生圖表。" @@ -13131,13 +13503,75 @@ msgid "" "(error)." msgstr "_step() çš„å›žå‚³å€¼ç„¡æ•ˆï¼Œå¿…é ˆç‚ºæ•´æ•¸ (Seq Out) 或å—串 (Error)。" +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "SubCall" +msgstr "呼å«" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Construct %s" +msgstr "常數" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Get Local Var" +msgstr "使用本機空間" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Set Local Var" +msgstr "使用本機空間" + +#: modules/visual_script/visual_script_nodes.cpp +#, fuzzy +msgid "Action %s" +msgstr "æ“作" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Deconstruct %s" +msgstr "" + #: modules/visual_script/visual_script_property_selector.cpp msgid "Search VisualScript" msgstr "æœå°‹è¦–覺腳本 (VisualScript)" -#: modules/visual_script/visual_script_property_selector.cpp -msgid "Get %s" -msgstr "å–å¾— %s" +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Yield" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "Wait" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Frame" +msgstr "è²¼ä¸Šå½±æ ¼" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "Next Physics Frame" +msgstr "物ç†å½±æ ¼ %" + +#: modules/visual_script/visual_script_yield_nodes.cpp +msgid "%s sec(s)" +msgstr "" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitSignal" +msgstr "訊號" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitNodeSignal" +msgstr "訊號" + +#: modules/visual_script/visual_script_yield_nodes.cpp +#, fuzzy +msgid "WaitInstanceSignal" +msgstr "實體" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -13734,14 +14168,24 @@ msgid "" msgstr "ParallaxLayer 節點僅在當其被è¨ç‚º ParallaxBackground çš„å節點時有效。" #: scene/2d/particles_2d.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles2D node instead. You can use the \"Convert to " -"CPUParticles\" option for this purpose." +"CPUParticles2D\" toolbar option for this purpose." msgstr "" "GLES2 視訊驅動程å¼ç›®å‰ä¸æ”¯æ´åŸºæ–¼ GPU 的粒å。\n" "請改為使用 CPUParticles2D 節點。å¯ä½¿ç”¨ã€ŒConvert to CPUParticlesã€é¸é …。" +#: scene/2d/particles_2d.cpp +msgid "" +"On macOS, Particles2D rendering is much slower than CPUParticles2D due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles2D instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles2D\" toolbar option for this " +"purpose." +msgstr "" + #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " @@ -13970,16 +14414,25 @@ msgid "Only uniform scales are supported." msgstr "僅支æ´å‡ç‰ç¸®æ”¾ã€‚" #: scene/3d/particles.cpp +#, fuzzy msgid "" "GPU-based particles are not supported by the GLES2 video driver.\n" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" -"\" option for this purpose." +"\" toolbar option for this purpose." msgstr "" "GLES2 視訊驅動程å¼ä¸æ”¯æ´åŸºæ–¼ GPU 的粒å。\n" "請改為使用 CPUParticles 節點。å¯ä½¿ç”¨ã€ŒConvert to CPUParticlesã€é¸é …。" #: scene/3d/particles.cpp msgid "" +"On macOS, Particles rendering is much slower than CPUParticles due to " +"transform feedback being implemented on the CPU instead of the GPU.\n" +"Consider using CPUParticles instead when targeting macOS.\n" +"You can use the \"Convert to CPUParticles\" toolbar option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "ç”±æ–¼ç¶²æ ¼å°šæœªè¢«æŒ‡æ´¾è‡³æç¹ªè·¯å¾‘(Draw Pass),未顯示任何æ±è¥¿ã€‚" diff --git a/gles3_builders.py b/gles3_builders.py index 5288e66cc2..4f9247c938 100644 --- a/gles3_builders.py +++ b/gles3_builders.py @@ -6,16 +6,12 @@ All such functions are invoked in a subprocess on Windows to prevent build flaki from platform_methods import subprocess_main -class LegacyGLHeaderStruct: +class GLES3HeaderStruct: def __init__(self): self.vertex_lines = [] self.fragment_lines = [] self.uniforms = [] - self.attributes = [] - self.feedbacks = [] self.fbos = [] - self.conditionals = [] - self.enums = {} self.texunits = [] self.texunit_names = [] self.ubos = [] @@ -28,22 +24,64 @@ class LegacyGLHeaderStruct: self.line_offset = 0 self.vertex_offset = 0 self.fragment_offset = 0 + self.variant_defines = [] + self.variant_names = [] + self.specialization_names = [] + self.specialization_values = [] -def include_file_in_legacygl_header(filename, header_data, depth): +def include_file_in_gles3_header(filename, header_data, depth): fs = open(filename, "r") line = fs.readline() while line: - if line.find("[vertex]") != -1: + if line.find("=") != -1 and header_data.reading == "": + # Mode + eqpos = line.find("=") + defname = line[:eqpos].strip().upper() + define = line[eqpos + 1 :].strip() + header_data.variant_names.append(defname) + header_data.variant_defines.append(define) + line = fs.readline() + header_data.line_offset += 1 + header_data.vertex_offset = header_data.line_offset + continue + + if line.find("=") != -1 and header_data.reading == "specializations": + # Specialization + eqpos = line.find("=") + specname = line[:eqpos].strip() + specvalue = line[eqpos + 1 :] + header_data.specialization_names.append(specname) + header_data.specialization_values.append(specvalue) + line = fs.readline() + header_data.line_offset += 1 + header_data.vertex_offset = header_data.line_offset + continue + + if line.find("#[modes]") != -1: + # Nothing really, just skip + line = fs.readline() + header_data.line_offset += 1 + header_data.vertex_offset = header_data.line_offset + continue + + if line.find("#[specializations]") != -1: + header_data.reading = "specializations" + line = fs.readline() + header_data.line_offset += 1 + header_data.vertex_offset = header_data.line_offset + continue + + if line.find("#[vertex]") != -1: header_data.reading = "vertex" line = fs.readline() header_data.line_offset += 1 header_data.vertex_offset = header_data.line_offset continue - if line.find("[fragment]") != -1: + if line.find("#[fragment]") != -1: header_data.reading = "fragment" line = fs.readline() header_data.line_offset += 1 @@ -58,31 +96,15 @@ def include_file_in_legacygl_header(filename, header_data, depth): included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline) if not included_file in header_data.vertex_included_files and header_data.reading == "vertex": header_data.vertex_included_files += [included_file] - if include_file_in_legacygl_header(included_file, header_data, depth + 1) is None: + if include_file_in_gles3_header(included_file, header_data, depth + 1) is None: print("Error in file '" + filename + "': #include " + includeline + "could not be found!") elif not included_file in header_data.fragment_included_files and header_data.reading == "fragment": header_data.fragment_included_files += [included_file] - if include_file_in_legacygl_header(included_file, header_data, depth + 1) is None: + if include_file_in_gles3_header(included_file, header_data, depth + 1) is None: print("Error in file '" + filename + "': #include " + includeline + "could not be found!") line = fs.readline() - if line.find("#ifdef ") != -1: - if line.find("#ifdef ") != -1: - ifdefline = line.replace("#ifdef ", "").strip() - - if line.find("_EN_") != -1: - enumbase = ifdefline[: ifdefline.find("_EN_")] - ifdefline = ifdefline.replace("_EN_", "_") - line = line.replace("_EN_", "_") - if enumbase not in header_data.enums: - header_data.enums[enumbase] = [] - if ifdefline not in header_data.enums[enumbase]: - header_data.enums[enumbase].append(ifdefline) - - elif not ifdefline in header_data.conditionals: - header_data.conditionals += [ifdefline] - if line.find("uniform") != -1 and line.lower().find("texunit:") != -1: # texture unit texunitstr = line[line.find(":") + 1 :].strip() @@ -144,33 +166,6 @@ def include_file_in_legacygl_header(filename, header_data, depth): if not x in header_data.uniforms: header_data.uniforms += [x] - if line.strip().find("attribute ") == 0 and line.find("attrib:") != -1: - uline = line.replace("in ", "") - uline = uline.replace("attribute ", "") - uline = uline.replace("highp ", "") - uline = uline.replace(";", "") - uline = uline[uline.find(" ") :].strip() - - if uline.find("//") != -1: - name, bind = uline.split("//") - if bind.find("attrib:") != -1: - name = name.strip() - bind = bind.replace("attrib:", "").strip() - header_data.attributes += [(name, bind)] - - if line.strip().find("out ") == 0 and line.find("tfb:") != -1: - uline = line.replace("out ", "") - uline = uline.replace("highp ", "") - uline = uline.replace(";", "") - uline = uline[uline.find(" ") :].strip() - - if uline.find("//") != -1: - name, bind = uline.split("//") - if bind.find("tfb:") != -1: - name = name.strip() - bind = bind.replace("tfb:", "").strip() - header_data.feedbacks += [(name, bind)] - line = line.replace("\r", "") line = line.replace("\n", "") @@ -187,12 +182,14 @@ def include_file_in_legacygl_header(filename, header_data, depth): return header_data -def build_legacygl_header(filename, include, class_suffix, output_attribs): - header_data = LegacyGLHeaderStruct() - include_file_in_legacygl_header(filename, header_data, 0) +def build_gles3_header(filename, include, class_suffix, output_attribs): + header_data = GLES3HeaderStruct() + include_file_in_gles3_header(filename, header_data, 0) out_file = filename + ".gen.h" fd = open(out_file, "w") + defspec = 0 + defvariant = "" enum_constants = [] @@ -202,8 +199,8 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): out_file_base = out_file_base[out_file_base.rfind("/") + 1 :] out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :] out_file_ifdef = out_file_base.replace(".", "_").upper() - fd.write("#ifndef " + out_file_ifdef + class_suffix + "_120\n") - fd.write("#define " + out_file_ifdef + class_suffix + "_120\n") + fd.write("#ifndef " + out_file_ifdef + class_suffix + "_GLES3\n") + fd.write("#define " + out_file_ifdef + class_suffix + "_GLES3\n") out_file_class = ( out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "Shader" + class_suffix @@ -211,117 +208,206 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): fd.write("\n\n") fd.write('#include "' + include + '"\n\n\n') fd.write("class " + out_file_class + " : public Shader" + class_suffix + " {\n\n") - fd.write('\t virtual String get_shader_name() const { return "' + out_file_class + '"; }\n') fd.write("public:\n\n") - if header_data.conditionals: - fd.write("\tenum Conditionals {\n") - for x in header_data.conditionals: - fd.write("\t\t" + x.upper() + ",\n") - fd.write("\t};\n\n") - if header_data.uniforms: fd.write("\tenum Uniforms {\n") for x in header_data.uniforms: fd.write("\t\t" + x.upper() + ",\n") fd.write("\t};\n\n") - fd.write("\t_FORCE_INLINE_ int get_uniform(Uniforms p_uniform) const { return _get_uniform(p_uniform); }\n\n") - if header_data.conditionals: - fd.write( - "\t_FORCE_INLINE_ void set_conditional(Conditionals p_conditional,bool p_enable) { _set_conditional(p_conditional,p_enable); }\n\n" - ) - fd.write("\t#ifdef DEBUG_ENABLED\n ") - fd.write( - "\t#define _FU if (get_uniform(p_uniform)<0) return; if (!is_version_valid()) return; ERR_FAIL_COND( get_active()!=this ); \n\n " - ) - fd.write("\t#else\n ") - fd.write("\t#define _FU if (get_uniform(p_uniform)<0) return; \n\n ") - fd.write("\t#endif\n") - fd.write( - "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_value) { _FU glUniform1f(get_uniform(p_uniform),p_value); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, double p_value) { _FU glUniform1f(get_uniform(p_uniform),p_value); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint8_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int8_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint16_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int16_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint32_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int32_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Color& p_color) { _FU GLfloat col[4]={p_color.r,p_color.g,p_color.b,p_color.a}; glUniform4fv(get_uniform(p_uniform),1,col); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector2& p_vec2) { _FU GLfloat vec2[2]={(GLfloat)p_vec2.x,(GLfloat)p_vec2.y}; glUniform2fv(get_uniform(p_uniform),1,vec2); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Size2i& p_vec2) { _FU GLint vec2[2]={(GLint)p_vec2.x,(GLint)p_vec2.y}; glUniform2iv(get_uniform(p_uniform),1,vec2); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector3& p_vec3) { _FU GLfloat vec3[3]={(GLfloat)p_vec3.x,(GLfloat)p_vec3.y,(GLfloat)p_vec3.z}; glUniform3fv(get_uniform(p_uniform),1,vec3); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b) { _FU glUniform2f(get_uniform(p_uniform),p_a,p_b); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c) { _FU glUniform3f(get_uniform(p_uniform),p_a,p_b,p_c); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c, float p_d) { _FU glUniform4f(get_uniform(p_uniform),p_a,p_b,p_c,p_d); }\n\n" - ) - - fd.write( - """\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Transform3D& p_transform) { _FU + if header_data.variant_names: + fd.write("\tenum ShaderVariant {\n") + for x in header_data.variant_names: + fd.write("\t\t" + x + ",\n") + fd.write("\t};\n\n") + else: + fd.write("\tenum ShaderVariant { DEFAULT };\n\n") + defvariant = "=DEFAULT" + + if header_data.specialization_names: + fd.write("\tenum Specializations {\n") + counter = 0 + for x in header_data.specialization_names: + fd.write("\t\t" + x.upper() + "=" + str(1 << counter) + ",\n") + counter += 1 + fd.write("\t};\n\n") - const Transform3D &tr = p_transform; + for i in range(len(header_data.specialization_names)): + defval = header_data.specialization_values[i].strip() + if defval.upper() == "TRUE" or defval == "1": + defspec |= 1 << i - GLfloat matrix[16]={ /* build a 16x16 matrix */ - (GLfloat)tr.basis.elements[0][0], - (GLfloat)tr.basis.elements[1][0], - (GLfloat)tr.basis.elements[2][0], - (GLfloat)0, - (GLfloat)tr.basis.elements[0][1], - (GLfloat)tr.basis.elements[1][1], - (GLfloat)tr.basis.elements[2][1], - (GLfloat)0, - (GLfloat)tr.basis.elements[0][2], - (GLfloat)tr.basis.elements[1][2], - (GLfloat)tr.basis.elements[2][2], - (GLfloat)0, - (GLfloat)tr.origin.x, - (GLfloat)tr.origin.y, - (GLfloat)tr.origin.z, - (GLfloat)1 - }; + fd.write( + "\t_FORCE_INLINE_ void version_bind_shader(RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { _version_bind_shader(p_version,p_variant,p_specialization); }\n\n" + ) + if header_data.uniforms: + fd.write( + "\t_FORCE_INLINE_ int version_get_uniform(Uniforms p_uniform,RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { return _version_get_uniform(p_uniform,p_version,p_variant,p_specialization); }\n\n" + ) - glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix); + fd.write( + "\t#define _FU if (version_get_uniform(p_uniform,p_version,p_variant,p_specialization)<0) return; \n\n " + ) + fd.write( + "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_value,RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { _FU glUniform1f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n" + ) + fd.write( + "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, double p_value,RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { _FU glUniform1f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n" + ) + fd.write( + "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint8_t p_value,RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n" + ) + fd.write( + "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int8_t p_value,RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n" + ) + fd.write( + "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint16_t p_value,RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n" + ) + fd.write( + "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int16_t p_value,RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n" + ) + fd.write( + "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint32_t p_value,RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n" + ) + fd.write( + "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int32_t p_value,RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n" + ) + fd.write( + "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Color& p_color,RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { _FU GLfloat col[4]={p_color.r,p_color.g,p_color.b,p_color.a}; glUniform4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,col); }\n\n" + ) + fd.write( + "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Vector2& p_vec2,RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { _FU GLfloat vec2[2]={float(p_vec2.x),float(p_vec2.y)}; glUniform2fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,vec2); }\n\n" + ) + fd.write( + "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Size2i& p_vec2,RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { _FU GLint vec2[2]={GLint(p_vec2.x),GLint(p_vec2.y)}; glUniform2iv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,vec2); }\n\n" + ) + fd.write( + "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Vector3& p_vec3,RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { _FU GLfloat vec3[3]={float(p_vec3.x),float(p_vec3.y),float(p_vec3.z)}; glUniform3fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,vec3); }\n\n" + ) + fd.write( + "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b,RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { _FU glUniform2f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_a,p_b); }\n\n" + ) + fd.write( + "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c,RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { _FU glUniform3f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_a,p_b,p_c); }\n\n" + ) + fd.write( + "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c, float p_d,RID p_version,ShaderVariant p_variant" + + defvariant + + ",uint64_t p_specialization=" + + str(defspec) + + ") { _FU glUniform4f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_a,p_b,p_c,p_d); }\n\n" + ) + fd.write( + """\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Transform3D& p_transform,RID p_version,ShaderVariant p_variant""" + + defvariant + + """,uint64_t p_specialization=""" + + str(defspec) + + """) { _FU + + const Transform3D &tr = p_transform; + + GLfloat matrix[16]={ /* build a 16x16 matrix */ + (GLfloat)tr.basis.elements[0][0], + (GLfloat)tr.basis.elements[1][0], + (GLfloat)tr.basis.elements[2][0], + (GLfloat)0, + (GLfloat)tr.basis.elements[0][1], + (GLfloat)tr.basis.elements[1][1], + (GLfloat)tr.basis.elements[2][1], + (GLfloat)0, + (GLfloat)tr.basis.elements[0][2], + (GLfloat)tr.basis.elements[1][2], + (GLfloat)tr.basis.elements[2][2], + (GLfloat)0, + (GLfloat)tr.origin.x, + (GLfloat)tr.origin.y, + (GLfloat)tr.origin.z, + (GLfloat)1 + }; + + glUniformMatrix4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,false,matrix); - } + } - """ - ) + """ + ) - fd.write( - """_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Transform2D& p_transform) { _FU + fd.write( + """_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Transform2D& p_transform,RID p_version,ShaderVariant p_variant""" + + defvariant + + """,uint64_t p_specialization=""" + + str(defspec) + + """) { _FU - const Transform2D &tr = p_transform; + const Transform2D &tr = p_transform; GLfloat matrix[16]={ /* build a 16x16 matrix */ (GLfloat)tr.elements[0][0], @@ -342,90 +428,37 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): (GLfloat)1 }; + glUniformMatrix4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,false,matrix); - glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix); - - - } - - """ - ) - - fd.write( - """_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const CameraMatrix& p_matrix) { _FU - - GLfloat matrix[16]; - - for (int i=0;i<4;i++) { - for (int j=0;j<4;j++) { - matrix[i*4+j]=p_matrix.matrix[i][j]; - } } - glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix); -}""" - ) - - fd.write("\n\n#undef _FU\n\n\n") - - fd.write("\tvirtual void init() {\n\n") - - enum_value_count = 0 - - if header_data.enums: - - fd.write("\t\t//Written using math, given nonstandarity of 64 bits integer constants..\n") - fd.write("\t\tstatic const Enum _enums[]={\n") - - bitofs = len(header_data.conditionals) - enum_vals = [] - - for xv in header_data.enums: - x = header_data.enums[xv] - bits = 1 - amt = len(x) - while 2 ** bits < amt: - bits += 1 - strs = "{" - for i in range(amt): - strs += '"#define ' + x[i] + '\\n",' - - c = {} - c["set_mask"] = "uint64_t(" + str(i) + ")<<" + str(bitofs) - c["clear_mask"] = ( - "((uint64_t(1)<<40)-1) ^ (((uint64_t(1)<<" + str(bits) + ") - 1)<<" + str(bitofs) + ")" - ) - enum_vals.append(c) - enum_constants.append(x[i]) - - strs += "NULL}" - - fd.write( - "\t\t\t{(uint64_t(1<<" + str(bits) + ")-1)<<" + str(bitofs) + "," + str(bitofs) + "," + strs + "},\n" - ) - bitofs += bits - - fd.write("\t\t};\n\n") + """ + ) - fd.write("\t\tstatic const EnumValue _enum_values[]={\n") + fd.write( + """_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const CameraMatrix& p_matrix,RID p_version,ShaderVariant p_variant""" + + defvariant + + """,uint64_t p_specialization=""" + + str(defspec) + + """) { _FU + + GLfloat matrix[16]; + + for (int i=0;i<4;i++) { + for (int j=0;j<4;j++) { + matrix[i*4+j]=p_matrix.matrix[i][j]; + } + } - enum_value_count = len(enum_vals) - for x in enum_vals: - fd.write("\t\t\t{" + x["set_mask"] + "," + x["clear_mask"] + "},\n") + glUniformMatrix4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,false,matrix); + }""" + ) - fd.write("\t\t};\n\n") + fd.write("\n\n#undef _FU\n\n\n") - conditionals_found = [] - if header_data.conditionals: + fd.write("protected:\n\n") - fd.write("\t\tstatic const char* _conditional_strings[]={\n") - if header_data.conditionals: - for x in header_data.conditionals: - fd.write('\t\t\t"#define ' + x + '\\n",\n') - conditionals_found.append(x) - fd.write("\t\t};\n\n") - else: - fd.write("\t\tstatic const char **_conditional_strings=NULL;\n") + fd.write("\tvirtual void _init() override {\n\n") if header_data.uniforms: @@ -435,19 +468,18 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): fd.write('\t\t\t"' + x + '",\n') fd.write("\t\t};\n\n") else: - fd.write("\t\tstatic const char **_uniform_strings=NULL;\n") - - if output_attribs: - if header_data.attributes: + fd.write("\t\tstatic const char **_uniform_strings=nullptr;\n") - fd.write("\t\tstatic AttributePair _attribute_pairs[]={\n") - for x in header_data.attributes: - fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n") - fd.write("\t\t};\n\n") - else: - fd.write("\t\tstatic AttributePair *_attribute_pairs=NULL;\n") + variant_count = 1 + if len(header_data.variant_defines) > 0: - feedback_count = 0 + fd.write("\t\tstatic const char* _variant_defines[]={\n") + for x in header_data.variant_defines: + fd.write('\t\t\t"' + x + '",\n') + fd.write("\t\t};\n\n") + variant_count = len(header_data.variant_defines) + else: + fd.write("\t\tstatic const char **_variant_defines[]={" "};\n") if header_data.texunits: fd.write("\t\tstatic TexUnitPair _texunit_pairs[]={\n") @@ -455,7 +487,29 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n") fd.write("\t\t};\n\n") else: - fd.write("\t\tstatic TexUnitPair *_texunit_pairs=NULL;\n") + fd.write("\t\tstatic TexUnitPair *_texunit_pairs=nullptr;\n") + + if header_data.ubos: + fd.write("\t\tstatic UBOPair _ubo_pairs[]={\n") + for x in header_data.ubos: + fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n") + fd.write("\t\t};\n\n") + else: + fd.write("\t\tstatic UBOPair *_ubo_pairs=nullptr;\n") + + if header_data.specialization_names: + fd.write("\t\tstatic Specialization _spec_pairs[]={\n") + for i in range(len(header_data.specialization_names)): + defval = header_data.specialization_values[i].strip() + if defval.upper() == "TRUE" or defval == "1": + defal = "true" + else: + defval = "false" + + fd.write('\t\t\t{"' + header_data.specialization_names[i] + '",' + defval + "},\n") + fd.write("\t\t};\n\n") + else: + fd.write("\t\tstatic Specialization *_spec_pairs=nullptr;\n") fd.write("\t\tstatic const char _vertex_code[]={\n") for x in header_data.vertex_lines: @@ -465,8 +519,6 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): fd.write(str(ord("\n")) + ",") fd.write("\t\t0};\n\n") - fd.write("\t\tstatic const int _vertex_code_start=" + str(header_data.vertex_offset) + ";\n") - fd.write("\t\tstatic const char _fragment_code[]={\n") for x in header_data.fragment_lines: for c in x: @@ -475,45 +527,24 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): fd.write(str(ord("\n")) + ",") fd.write("\t\t0};\n\n") - fd.write("\t\tstatic const int _fragment_code_start=" + str(header_data.fragment_offset) + ";\n") - - if output_attribs: - fd.write( - "\t\tsetup(_conditional_strings," - + str(len(header_data.conditionals)) - + ",_uniform_strings," - + str(len(header_data.uniforms)) - + ",_attribute_pairs," - + str(len(header_data.attributes)) - + ", _texunit_pairs," - + str(len(header_data.texunits)) - + ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n" - ) - else: - fd.write( - "\t\tsetup(_conditional_strings," - + str(len(header_data.conditionals)) - + ",_uniform_strings," - + str(len(header_data.uniforms)) - + ",_texunit_pairs," - + str(len(header_data.texunits)) - + ",_enums," - + str(len(header_data.enums)) - + ",_enum_values," - + str(enum_value_count) - + ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n" - ) + fd.write( + '\t\t_setup(_vertex_code,_fragment_code,"' + + out_file_class + + '",' + + str(len(header_data.uniforms)) + + ",_uniform_strings," + + str(len(header_data.ubos)) + + ",_ubo_pairs," + + str(len(header_data.texunits)) + + ",_texunit_pairs," + + str(len(header_data.specialization_names)) + + ",_spec_pairs," + + str(variant_count) + + ",_variant_defines);\n" + ) fd.write("\t}\n\n") - if enum_constants: - - fd.write("\tenum EnumConditionals {\n") - for x in enum_constants: - fd.write("\t\t" + x.upper() + ",\n") - fd.write("\t};\n\n") - fd.write("\tvoid set_enum_conditional(EnumConditionals p_cond) { _set_enum_conditional(p_cond); }\n") - fd.write("};\n\n") fd.write("#endif\n\n") fd.close() @@ -521,7 +552,7 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): def build_gles3_headers(target, source, env): for x in source: - build_legacygl_header(str(x), include="drivers/gles3/shader_gles3.h", class_suffix="GLES3", output_attribs=True) + build_gles3_header(str(x), include="drivers/gles3/shader_gles3.h", class_suffix="GLES3", output_attribs=True) if __name__ == "__main__": diff --git a/main/main.cpp b/main/main.cpp index 9767d4f5fb..9393e8d99d 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -164,7 +164,6 @@ static bool init_windowed = false; static bool init_always_on_top = false; static bool init_use_custom_pos = false; static Vector2 init_custom_pos; -static bool force_lowdpi = false; // Debug @@ -340,7 +339,6 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" -t, --always-on-top Request an always-on-top window.\n"); OS::get_singleton()->print(" --resolution <W>x<H> Request window resolution.\n"); OS::get_singleton()->print(" --position <X>,<Y> Request window position.\n"); - OS::get_singleton()->print(" --low-dpi Force low-DPI mode (macOS and Windows only).\n"); OS::get_singleton()->print(" --single-window Use a single window (no separate subwindows).\n"); OS::get_singleton()->print(" --tablet-driver Pen tablet input driver.\n"); OS::get_singleton()->print("\n"); @@ -870,9 +868,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph goto error; } - } else if (I->get() == "--low-dpi") { // force low DPI (macOS only) - - force_lowdpi = true; } else if (I->get() == "--headless") { // enable headless mode (no audio, no rendering). audio_driver = "Dummy"; @@ -1365,9 +1360,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph GLOBAL_DEF("internationalization/rendering/force_right_to_left_layout_direction", false); GLOBAL_DEF("internationalization/locale/include_text_server_data", false); - if (!force_lowdpi) { - OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", false); - } + OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", true); // FIXME: Restore support. #if 0 diff --git a/misc/dist/shell/_godot.zsh-completion b/misc/dist/shell/_godot.zsh-completion index ba386b55cc..9d42f4fe05 100644 --- a/misc/dist/shell/_godot.zsh-completion +++ b/misc/dist/shell/_godot.zsh-completion @@ -49,7 +49,6 @@ _arguments \ '(-t --always-on-top)'{-t,--always-on-top}'[request an always-on-top window]' \ '--resolution[request window resolution]:resolution in WxH format' \ '--position[request window position]:position in X,Y format' \ - '--low-dpi[force low-DPI mode (macOS and Windows only)]' \ '--headless[enable headless mode (--display-driver headless --audio-driver Dummy). Useful for servers and with --script]' \ '(-d --debug)'{-d,--debug}'[debug (local stdout debugger)]' \ '(-b --breakpoints)'{-b,--breakpoints}'[specify the breakpoint list as source::line comma-separated pairs, no spaces (use %20 instead)]:breakpoint list' \ diff --git a/misc/dist/shell/godot.bash-completion b/misc/dist/shell/godot.bash-completion index 218fbd81b1..eeee538aba 100644 --- a/misc/dist/shell/godot.bash-completion +++ b/misc/dist/shell/godot.bash-completion @@ -52,7 +52,6 @@ _complete_godot_options() { --always-on-top --resolution --position ---low-dpi --headless --debug --breakpoints diff --git a/misc/dist/shell/godot.fish b/misc/dist/shell/godot.fish index 2a6b18ed8f..79df2de7f0 100644 --- a/misc/dist/shell/godot.fish +++ b/misc/dist/shell/godot.fish @@ -59,7 +59,6 @@ complete -c godot -s w -l windowed -d "Request windowed mode" complete -c godot -s t -l always-on-top -d "Request an always-on-top window" complete -c godot -l resolution -d "Request window resolution" -x complete -c godot -l position -d "Request window position" -x -complete -c godot -l low-dpi -d "Force low-DPI mode (macOS and Windows only)" complete -c godot -l headless -d "Enable headless mode (--display-driver headless --audio-driver Dummy). Useful for servers and with --script" # Debug options: diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp index d17e880fc0..f816691cde 100644 --- a/modules/bullet/area_bullet.cpp +++ b/modules/bullet/area_bullet.cpp @@ -39,10 +39,6 @@ #include <BulletCollision/CollisionDispatch/btGhostObject.h> #include <btBulletCollisionCommon.h> -/** - @author AndreaCatania -*/ - AreaBullet::AreaBullet() : RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_AREA) { btGhost = bulletnew(btGhostObject); diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h index caf81ef1be..740378d0e3 100644 --- a/modules/bullet/area_bullet.h +++ b/modules/bullet/area_bullet.h @@ -28,18 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AREABULLET_H -#define AREABULLET_H +#ifndef AREA_BULLET_H +#define AREA_BULLET_H #include "collision_object_bullet.h" #include "core/templates/vector.h" #include "servers/physics_server_3d.h" #include "space_bullet.h" -/** - @author AndreaCatania -*/ - class btGhostObject; class AreaBullet : public RigidCollisionObjectBullet { @@ -163,4 +159,4 @@ public: virtual void on_exit_area(AreaBullet *p_area); }; -#endif +#endif // AREA_BULLET_H diff --git a/modules/bullet/btRayShape.cpp b/modules/bullet/btRayShape.cpp index e67c9baacd..14bc7442a7 100644 --- a/modules/bullet/btRayShape.cpp +++ b/modules/bullet/btRayShape.cpp @@ -34,10 +34,6 @@ #include <LinearMath/btAabbUtil2.h> -/** - @author AndreaCatania -*/ - btRayShape::btRayShape(btScalar length) : btConvexInternalShape() { m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE; diff --git a/modules/bullet/btRayShape.h b/modules/bullet/btRayShape.h index 5d0a05b369..90e4524d64 100644 --- a/modules/bullet/btRayShape.h +++ b/modules/bullet/btRayShape.h @@ -35,10 +35,6 @@ #include <BulletCollision/CollisionShapes/btConvexInternalShape.h> -/** - @author AndreaCatania -*/ - /// Ray shape around z axis ATTRIBUTE_ALIGNED16(class) btRayShape : public btConvexInternalShape { diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index 9bf3e186ee..7e9e621032 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -45,10 +45,6 @@ #include <assert.h> -/** - @author AndreaCatania -*/ - #define CreateThenReturnRID(owner, ridData) \ RID rid = owner.make_rid(ridData); \ ridData->set_self(rid); \ diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index 5840eff815..06a6f62bcd 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -41,10 +41,6 @@ #include "soft_body_bullet.h" #include "space_bullet.h" -/** - @author AndreaCatania -*/ - class BulletPhysicsServer3D : public PhysicsServer3D { GDCLASS(BulletPhysicsServer3D, PhysicsServer3D); @@ -395,4 +391,4 @@ public: JointBullet *get_joint(RID p_rid) const; }; -#endif +#endif // BULLET_PHYSICS_SERVER_H diff --git a/modules/bullet/bullet_types_converter.cpp b/modules/bullet/bullet_types_converter.cpp index 571457f48f..a0698683e8 100644 --- a/modules/bullet/bullet_types_converter.cpp +++ b/modules/bullet/bullet_types_converter.cpp @@ -30,10 +30,6 @@ #include "bullet_types_converter.h" -/** - @author AndreaCatania -*/ - // ++ BULLET to GODOT ++++++++++ void B_TO_G(btVector3 const &inVal, Vector3 &outVal) { outVal[0] = inVal[0]; diff --git a/modules/bullet/bullet_types_converter.h b/modules/bullet/bullet_types_converter.h index b4d6dccc05..4ee855c266 100644 --- a/modules/bullet/bullet_types_converter.h +++ b/modules/bullet/bullet_types_converter.h @@ -40,10 +40,6 @@ #include <LinearMath/btTransform.h> #include <LinearMath/btVector3.h> -/** - @author AndreaCatania -*/ - // Bullet to Godot extern void B_TO_G(btVector3 const &inVal, Vector3 &outVal); extern void INVERT_B_TO_G(btVector3 const &inVal, Vector3 &outVal); @@ -59,4 +55,5 @@ extern void INVERT_G_TO_B(Basis const &inVal, btMatrix3x3 &outVal); extern void G_TO_B(Transform3D const &inVal, btTransform &outVal); extern void UNSCALE_BT_BASIS(btTransform &scaledBasis); -#endif + +#endif // BULLET_TYPES_CONVERTER_H diff --git a/modules/bullet/bullet_utilities.h b/modules/bullet/bullet_utilities.h index b832d3fc61..ab24cb5de6 100644 --- a/modules/bullet/bullet_utilities.h +++ b/modules/bullet/bullet_utilities.h @@ -31,10 +31,6 @@ #ifndef BULLET_UTILITIES_H #define BULLET_UTILITIES_H -/** - @author AndreaCatania -*/ - #define bulletnew(cl) \ new cl @@ -43,4 +39,5 @@ delete cl; \ cl = nullptr; \ } -#endif + +#endif // BULLET_UTILITIES_H diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp index 6bf01a63df..bc8e1a0718 100644 --- a/modules/bullet/collision_object_bullet.cpp +++ b/modules/bullet/collision_object_bullet.cpp @@ -39,10 +39,6 @@ #include <btBulletCollisionCommon.h> -/** - @author AndreaCatania -*/ - // We enable dynamic AABB tree so that we can actually perform a broadphase on bodies with compound collision shapes. // This is crucial for the performance of kinematic bodies and for bodies with transforming shapes. #define enableDynamicAabbTree true diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h index 09be2d99d2..8e9c34df27 100644 --- a/modules/bullet/collision_object_bullet.h +++ b/modules/bullet/collision_object_bullet.h @@ -39,10 +39,6 @@ #include <LinearMath/btTransform.h> -/** - @author AndreaCatania -*/ - class AreaBullet; class ShapeBullet; class btCollisionObject; @@ -256,4 +252,4 @@ private: void internal_shape_destroy(int p_index, bool p_permanentlyFromThisBody = false); }; -#endif +#endif // COLLISION_OBJECT_BULLET_H diff --git a/modules/bullet/cone_twist_joint_bullet.cpp b/modules/bullet/cone_twist_joint_bullet.cpp index 544d711259..fc73036713 100644 --- a/modules/bullet/cone_twist_joint_bullet.cpp +++ b/modules/bullet/cone_twist_joint_bullet.cpp @@ -36,10 +36,6 @@ #include <BulletDynamics/ConstraintSolver/btConeTwistConstraint.h> -/** - @author AndreaCatania -*/ - ConeTwistJointBullet::ConeTwistJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &rbAFrame, const Transform3D &rbBFrame) : JointBullet() { Transform3D scaled_AFrame(rbAFrame.scaled(rbA->get_body_scale())); diff --git a/modules/bullet/cone_twist_joint_bullet.h b/modules/bullet/cone_twist_joint_bullet.h index ebb51868f4..c81e11f144 100644 --- a/modules/bullet/cone_twist_joint_bullet.h +++ b/modules/bullet/cone_twist_joint_bullet.h @@ -33,10 +33,6 @@ #include "joint_bullet.h" -/** - @author AndreaCatania -*/ - class RigidBodyBullet; class ConeTwistJointBullet : public JointBullet { @@ -50,4 +46,5 @@ public: void set_param(PhysicsServer3D::ConeTwistJointParam p_param, real_t p_value); real_t get_param(PhysicsServer3D::ConeTwistJointParam p_param) const; }; -#endif + +#endif // CONE_TWIST_JOINT_BULLET_H diff --git a/modules/bullet/constraint_bullet.cpp b/modules/bullet/constraint_bullet.cpp index 5b4b0e75bc..c788f09cb9 100644 --- a/modules/bullet/constraint_bullet.cpp +++ b/modules/bullet/constraint_bullet.cpp @@ -33,10 +33,6 @@ #include "collision_object_bullet.h" #include "space_bullet.h" -/** - @author AndreaCatania -*/ - ConstraintBullet::ConstraintBullet() {} void ConstraintBullet::setup(btTypedConstraint *p_constraint) { diff --git a/modules/bullet/constraint_bullet.h b/modules/bullet/constraint_bullet.h index 5e63d7a1b5..5dc3958ee1 100644 --- a/modules/bullet/constraint_bullet.h +++ b/modules/bullet/constraint_bullet.h @@ -36,10 +36,6 @@ #include <BulletDynamics/ConstraintSolver/btTypedConstraint.h> -/** - @author AndreaCatania -*/ - class RigidBodyBullet; class SpaceBullet; class btTypedConstraint; @@ -68,4 +64,5 @@ public: _FORCE_INLINE_ btTypedConstraint *get_bt_constraint() { return constraint; } }; -#endif + +#endif // CONSTRAINT_BULLET_H diff --git a/modules/bullet/generic_6dof_joint_bullet.cpp b/modules/bullet/generic_6dof_joint_bullet.cpp index 01e1ecbdf6..0210064dc8 100644 --- a/modules/bullet/generic_6dof_joint_bullet.cpp +++ b/modules/bullet/generic_6dof_joint_bullet.cpp @@ -36,10 +36,6 @@ #include <BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h> -/** - @author AndreaCatania -*/ - Generic6DOFJointBullet::Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameInA, const Transform3D &frameInB) : JointBullet() { for (int i = 0; i < 3; i++) { diff --git a/modules/bullet/generic_6dof_joint_bullet.h b/modules/bullet/generic_6dof_joint_bullet.h index b5d1db8fd6..cc4ccf7ac4 100644 --- a/modules/bullet/generic_6dof_joint_bullet.h +++ b/modules/bullet/generic_6dof_joint_bullet.h @@ -33,10 +33,6 @@ #include "joint_bullet.h" -/** - @author AndreaCatania -*/ - class RigidBodyBullet; class Generic6DOFJointBullet : public JointBullet { @@ -70,4 +66,4 @@ public: bool get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag) const; }; -#endif +#endif // GENERIC_6DOF_JOINT_BULLET_H diff --git a/modules/bullet/godot_collision_configuration.cpp b/modules/bullet/godot_collision_configuration.cpp index 0e872fa1c1..354c4e271b 100644 --- a/modules/bullet/godot_collision_configuration.cpp +++ b/modules/bullet/godot_collision_configuration.cpp @@ -35,10 +35,6 @@ #include <BulletCollision/BroadphaseCollision/btBroadphaseProxy.h> #include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h> -/** - @author AndreaCatania -*/ - GodotCollisionConfiguration::GodotCollisionConfiguration(const btDiscreteDynamicsWorld *world, const btDefaultCollisionConstructionInfo &constructionInfo) : btDefaultCollisionConfiguration(constructionInfo) { void *mem = nullptr; diff --git a/modules/bullet/godot_collision_configuration.h b/modules/bullet/godot_collision_configuration.h index 3b1bc3a97d..7e29f6e03a 100644 --- a/modules/bullet/godot_collision_configuration.h +++ b/modules/bullet/godot_collision_configuration.h @@ -34,10 +34,6 @@ #include <BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h> #include <BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h> -/** - @author AndreaCatania -*/ - class btDiscreteDynamicsWorld; class GodotCollisionConfiguration : public btDefaultCollisionConfiguration { @@ -63,4 +59,5 @@ public: virtual btCollisionAlgorithmCreateFunc *getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1); virtual btCollisionAlgorithmCreateFunc *getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1); }; -#endif + +#endif // GODOT_COLLISION_CONFIGURATION_H diff --git a/modules/bullet/godot_collision_dispatcher.cpp b/modules/bullet/godot_collision_dispatcher.cpp index c926462eda..2ab1c7dd84 100644 --- a/modules/bullet/godot_collision_dispatcher.cpp +++ b/modules/bullet/godot_collision_dispatcher.cpp @@ -32,10 +32,6 @@ #include "collision_object_bullet.h" -/** - @author AndreaCatania -*/ - const int GodotCollisionDispatcher::CASTED_TYPE_AREA = static_cast<int>(CollisionObjectBullet::TYPE_AREA); GodotCollisionDispatcher::GodotCollisionDispatcher(btCollisionConfiguration *collisionConfiguration) : diff --git a/modules/bullet/godot_collision_dispatcher.h b/modules/bullet/godot_collision_dispatcher.h index 77b8cee0a6..97cae1ce6a 100644 --- a/modules/bullet/godot_collision_dispatcher.h +++ b/modules/bullet/godot_collision_dispatcher.h @@ -31,14 +31,8 @@ #ifndef GODOT_COLLISION_DISPATCHER_H #define GODOT_COLLISION_DISPATCHER_H -#include <cstdint> - #include <btBulletDynamicsCommon.h> -/** - @author AndreaCatania -*/ - /// This class is required to implement custom collision behaviour in the narrowphase class GodotCollisionDispatcher : public btCollisionDispatcher { private: @@ -49,4 +43,5 @@ public: virtual bool needsCollision(const btCollisionObject *body0, const btCollisionObject *body1); virtual bool needsResponse(const btCollisionObject *body0, const btCollisionObject *body1); }; -#endif + +#endif // GODOT_COLLISION_DISPATCHER_H diff --git a/modules/bullet/godot_motion_state.h b/modules/bullet/godot_motion_state.h index a37fef9d90..f1a5e0e3b5 100644 --- a/modules/bullet/godot_motion_state.h +++ b/modules/bullet/godot_motion_state.h @@ -35,10 +35,6 @@ #include <LinearMath/btMotionState.h> -/** - @author AndreaCatania -*/ - class RigidBodyBullet; // This class is responsible to move kinematic actor @@ -96,4 +92,5 @@ public: return bodyCurrentWorldTransform; } }; -#endif + +#endif // GODOT_MOTION_STATE_H diff --git a/modules/bullet/godot_ray_world_algorithm.cpp b/modules/bullet/godot_ray_world_algorithm.cpp index 3b7513916d..697ca12e7b 100644 --- a/modules/bullet/godot_ray_world_algorithm.cpp +++ b/modules/bullet/godot_ray_world_algorithm.cpp @@ -35,10 +35,6 @@ #include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h> -/** - @author AndreaCatania -*/ - // Epsilon to account for floating point inaccuracies #define RAY_PENETRATION_DEPTH_EPSILON 0.01 diff --git a/modules/bullet/godot_ray_world_algorithm.h b/modules/bullet/godot_ray_world_algorithm.h index f554108a75..94bdefb720 100644 --- a/modules/bullet/godot_ray_world_algorithm.h +++ b/modules/bullet/godot_ray_world_algorithm.h @@ -35,10 +35,6 @@ #include <BulletCollision/CollisionDispatch/btCollisionCreateFunc.h> #include <BulletCollision/CollisionDispatch/btCollisionDispatcher.h> -/** - @author AndreaCatania -*/ - class btDiscreteDynamicsWorld; class GodotRayWorldAlgorithm : public btActivatingCollisionAlgorithm { diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp index d4b6e90117..35b26fc2ec 100644 --- a/modules/bullet/godot_result_callbacks.cpp +++ b/modules/bullet/godot_result_callbacks.cpp @@ -34,11 +34,8 @@ #include "bullet_types_converter.h" #include "collision_object_bullet.h" #include "rigid_body_bullet.h" -#include <BulletCollision/CollisionDispatch/btInternalEdgeUtility.h> -/** - @author AndreaCatania -*/ +#include <BulletCollision/CollisionDispatch/btInternalEdgeUtility.h> bool godotContactAddedCallback(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) { if (!colObj1Wrap->getCollisionObject()->getCollisionShape()->isCompound()) { diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h index 94be993212..dd64762529 100644 --- a/modules/bullet/godot_result_callbacks.h +++ b/modules/bullet/godot_result_callbacks.h @@ -36,10 +36,6 @@ #include <BulletCollision/BroadphaseCollision/btBroadphaseProxy.h> #include <btBulletDynamicsCommon.h> -/** - @author AndreaCatania -*/ - class RigidBodyBullet; /// This callback is injected inside bullet server and allow me to smooth contacts against trimesh @@ -225,4 +221,5 @@ struct GodotDeepPenetrationContactResultCallback : public btManifoldResult { virtual void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorldOnB, btScalar depth); }; + #endif // GODOT_RESULT_CALLBACKS_H diff --git a/modules/bullet/hinge_joint_bullet.cpp b/modules/bullet/hinge_joint_bullet.cpp index 116d8caba7..0b1bb7890d 100644 --- a/modules/bullet/hinge_joint_bullet.cpp +++ b/modules/bullet/hinge_joint_bullet.cpp @@ -36,10 +36,6 @@ #include <BulletDynamics/ConstraintSolver/btHingeConstraint.h> -/** - @author AndreaCatania -*/ - HingeJointBullet::HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameA, const Transform3D &frameB) : JointBullet() { Transform3D scaled_AFrame(frameA.scaled(rbA->get_body_scale())); diff --git a/modules/bullet/hinge_joint_bullet.h b/modules/bullet/hinge_joint_bullet.h index 7b87576442..5575be564f 100644 --- a/modules/bullet/hinge_joint_bullet.h +++ b/modules/bullet/hinge_joint_bullet.h @@ -33,10 +33,6 @@ #include "joint_bullet.h" -/** - @author AndreaCatania -*/ - class HingeJointBullet : public JointBullet { class btHingeConstraint *hingeConstraint; @@ -54,4 +50,5 @@ public: void set_flag(PhysicsServer3D::HingeJointFlag p_flag, bool p_value); bool get_flag(PhysicsServer3D::HingeJointFlag p_flag) const; }; -#endif + +#endif // HINGE_JOINT_BULLET_H diff --git a/modules/bullet/joint_bullet.cpp b/modules/bullet/joint_bullet.cpp deleted file mode 100644 index 65a891e890..0000000000 --- a/modules/bullet/joint_bullet.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/*************************************************************************/ -/* joint_bullet.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "joint_bullet.h" - -#include "space_bullet.h" - -/** - @author AndreaCatania -*/ - -JointBullet::JointBullet() : - ConstraintBullet() {} - -JointBullet::~JointBullet() {} diff --git a/modules/bullet/joint_bullet.h b/modules/bullet/joint_bullet.h index 75f6055b2f..427221dd77 100644 --- a/modules/bullet/joint_bullet.h +++ b/modules/bullet/joint_bullet.h @@ -34,18 +34,15 @@ #include "constraint_bullet.h" #include "servers/physics_server_3d.h" -/** - @author AndreaCatania -*/ - class RigidBodyBullet; class btTypedConstraint; class JointBullet : public ConstraintBullet { public: - JointBullet(); - virtual ~JointBullet(); + JointBullet() {} + virtual ~JointBullet() {} virtual PhysicsServer3D::JointType get_type() const = 0; }; -#endif + +#endif // JOINT_BULLET_H diff --git a/modules/bullet/pin_joint_bullet.cpp b/modules/bullet/pin_joint_bullet.cpp index 03853cc830..72fdd5c408 100644 --- a/modules/bullet/pin_joint_bullet.cpp +++ b/modules/bullet/pin_joint_bullet.cpp @@ -35,10 +35,6 @@ #include <BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h> -/** - @author AndreaCatania -*/ - PinJointBullet::PinJointBullet(RigidBodyBullet *p_body_a, const Vector3 &p_pos_a, RigidBodyBullet *p_body_b, const Vector3 &p_pos_b) : JointBullet() { if (p_body_b) { diff --git a/modules/bullet/pin_joint_bullet.h b/modules/bullet/pin_joint_bullet.h index 0510cf99ad..0a688d55f9 100644 --- a/modules/bullet/pin_joint_bullet.h +++ b/modules/bullet/pin_joint_bullet.h @@ -33,10 +33,6 @@ #include "joint_bullet.h" -/** - @author AndreaCatania -*/ - class RigidBodyBullet; class PinJointBullet : public JointBullet { @@ -57,4 +53,5 @@ public: Vector3 getPivotInA(); Vector3 getPivotInB(); }; -#endif + +#endif // PIN_JOINT_BULLET_H diff --git a/modules/bullet/register_types.cpp b/modules/bullet/register_types.cpp index 675a5c8491..d5d0ee2cf4 100644 --- a/modules/bullet/register_types.cpp +++ b/modules/bullet/register_types.cpp @@ -34,10 +34,6 @@ #include "core/config/project_settings.h" #include "core/object/class_db.h" -/** - @author AndreaCatania -*/ - #ifndef _3D_DISABLED PhysicsServer3D *_createBulletPhysicsCallback() { return memnew(BulletPhysicsServer3D); diff --git a/modules/bullet/register_types.h b/modules/bullet/register_types.h index 739614dc52..93847d6dc3 100644 --- a/modules/bullet/register_types.h +++ b/modules/bullet/register_types.h @@ -31,10 +31,7 @@ #ifndef REGISTER_BULLET_TYPES_H #define REGISTER_BULLET_TYPES_H -/** - @author AndreaCatania -*/ - void register_bullet_types(); void unregister_bullet_types(); -#endif + +#endif // REGISTER_BULLET_TYPES_H diff --git a/modules/bullet/rid_bullet.h b/modules/bullet/rid_bullet.h index 982654441e..260d303cac 100644 --- a/modules/bullet/rid_bullet.h +++ b/modules/bullet/rid_bullet.h @@ -33,10 +33,6 @@ #include "core/templates/rid.h" -/** - @author AndreaCatania -*/ - class BulletPhysicsServer3D; class RIDBullet { @@ -50,4 +46,5 @@ public: _FORCE_INLINE_ void _set_physics_server(BulletPhysicsServer3D *p_physicsServer) { physicsServer = p_physicsServer; } _FORCE_INLINE_ BulletPhysicsServer3D *get_physics_server() const { return physicsServer; } }; -#endif + +#endif // RID_BULLET_H diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 0112712736..0603963332 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -42,12 +42,6 @@ #include <BulletDynamics/Dynamics/btRigidBody.h> #include <btBulletCollisionCommon.h> -#include <assert.h> - -/** - @author AndreaCatania -*/ - BulletPhysicsDirectBodyState3D *BulletPhysicsDirectBodyState3D::singleton = nullptr; Vector3 BulletPhysicsDirectBodyState3D::get_total_gravity() const { diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h index f41c5ca1c9..cd433c968f 100644 --- a/modules/bullet/rigid_body_bullet.h +++ b/modules/bullet/rigid_body_bullet.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BODYBULLET_H -#define BODYBULLET_H +#ifndef RIGID_BODY_BULLET_H +#define RIGID_BODY_BULLET_H #include "collision_object_bullet.h" #include "space_bullet.h" @@ -37,10 +37,6 @@ #include <BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h> #include <LinearMath/btTransform.h> -/** - @author AndreaCatania -*/ - class AreaBullet; class SpaceBullet; class btRigidBody; @@ -329,4 +325,4 @@ private: void _internal_set_mass(real_t p_mass); }; -#endif +#endif // RIGID_BODY_BULLET_H diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp index 2b2a7dd8f1..77a583ad86 100644 --- a/modules/bullet/shape_bullet.cpp +++ b/modules/bullet/shape_bullet.cpp @@ -42,10 +42,6 @@ #include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h> #include <btBulletCollisionCommon.h> -/** - @author AndreaCatania -*/ - ShapeBullet::ShapeBullet() {} ShapeBullet::~ShapeBullet() {} diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h index 93e9bed201..6377f8915d 100644 --- a/modules/bullet/shape_bullet.h +++ b/modules/bullet/shape_bullet.h @@ -40,10 +40,6 @@ #include <LinearMath/btScalar.h> #include <LinearMath/btVector3.h> -/** - @author AndreaCatania -*/ - class ShapeBullet; class btCollisionShape; class ShapeOwnerBullet; @@ -244,4 +240,5 @@ public: private: void setup(real_t p_length, bool p_slips_on_slope); }; -#endif + +#endif // SHAPE_BULLET_H diff --git a/modules/bullet/shape_owner_bullet.cpp b/modules/bullet/shape_owner_bullet.cpp deleted file mode 100644 index 7f516e83c0..0000000000 --- a/modules/bullet/shape_owner_bullet.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************/ -/* shape_owner_bullet.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "shape_owner_bullet.h" - -/** - @author AndreaCatania -*/ diff --git a/modules/bullet/shape_owner_bullet.h b/modules/bullet/shape_owner_bullet.h index 5f8bb61503..11cf1bc2d5 100644 --- a/modules/bullet/shape_owner_bullet.h +++ b/modules/bullet/shape_owner_bullet.h @@ -33,10 +33,6 @@ #include "rid_bullet.h" -/** - @author AndreaCatania -*/ - class ShapeBullet; class btCollisionShape; class CollisionObjectBullet; @@ -51,4 +47,5 @@ public: virtual void remove_shape_full(class ShapeBullet *p_shape) = 0; virtual ~ShapeOwnerBullet() {} }; -#endif + +#endif // SHAPE_OWNER_BULLET_H diff --git a/modules/bullet/slider_joint_bullet.cpp b/modules/bullet/slider_joint_bullet.cpp index a3190609a1..61c3b3b0a3 100644 --- a/modules/bullet/slider_joint_bullet.cpp +++ b/modules/bullet/slider_joint_bullet.cpp @@ -36,10 +36,6 @@ #include <BulletDynamics/ConstraintSolver/btSliderConstraint.h> -/** - @author AndreaCatania -*/ - SliderJointBullet::SliderJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameInA, const Transform3D &frameInB) : JointBullet() { Transform3D scaled_AFrame(frameInA.scaled(rbA->get_body_scale())); diff --git a/modules/bullet/slider_joint_bullet.h b/modules/bullet/slider_joint_bullet.h index 556f4e9e64..c355eb340b 100644 --- a/modules/bullet/slider_joint_bullet.h +++ b/modules/bullet/slider_joint_bullet.h @@ -33,10 +33,6 @@ #include "joint_bullet.h" -/** - @author AndreaCatania -*/ - class RigidBodyBullet; class SliderJointBullet : public JointBullet { @@ -118,4 +114,5 @@ public: void set_param(PhysicsServer3D::SliderJointParam p_param, real_t p_value); real_t get_param(PhysicsServer3D::SliderJointParam p_param) const; }; -#endif + +#endif // SLIDER_JOINT_BULLET_H diff --git a/modules/bullet/soft_body_bullet.h b/modules/bullet/soft_body_bullet.h index fea26e9449..82a7bb3b0c 100644 --- a/modules/bullet/soft_body_bullet.h +++ b/modules/bullet/soft_body_bullet.h @@ -49,10 +49,6 @@ #define None 0L #endif -/** - @author AndreaCatania -*/ - class RenderingServerHandler; class SoftBodyBullet : public CollisionObjectBullet { diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 55e822ba5a..460b78d778 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -54,10 +54,6 @@ #include <assert.h> -/** - @author AndreaCatania -*/ - BulletPhysicsDirectSpaceState::BulletPhysicsDirectSpaceState(SpaceBullet *p_space) : PhysicsDirectSpaceState3D(), space(p_space) {} diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h index 154bb6f01b..f858c5fcb5 100644 --- a/modules/bullet/space_bullet.h +++ b/modules/bullet/space_bullet.h @@ -43,10 +43,6 @@ #include <LinearMath/btTransform.h> #include <LinearMath/btVector3.h> -/** - @author AndreaCatania -*/ - class AreaBullet; class btBroadphaseInterface; class btCollisionDispatcher; @@ -220,4 +216,5 @@ private: int add_separation_result(PhysicsServer3D::SeparationResult *r_results, const SpaceBullet::RecoverResult &p_recover_result, int p_shape_id, const btCollisionObject *p_other_object) const; int recover_from_penetration_ray(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, int p_result_max, btVector3 &r_delta_recover_movement, PhysicsServer3D::SeparationResult *r_results); }; -#endif + +#endif // SPACE_BULLET_H diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp index f6e09067d2..9a6a33fad3 100644 --- a/modules/csg/csg_gizmos.cpp +++ b/modules/csg/csg_gizmos.cpp @@ -50,7 +50,7 @@ CSGShape3DGizmoPlugin::CSGShape3DGizmoPlugin() { create_handle_material("handles"); } -String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { +String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node()); if (Object::cast_to<CSGSphere3D>(cs)) { @@ -72,7 +72,7 @@ String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, return ""; } -Variant CSGShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { +Variant CSGShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node()); if (Object::cast_to<CSGSphere3D>(cs)) { @@ -98,7 +98,7 @@ Variant CSGShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo return Variant(); } -void CSGShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) { +void CSGShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node()); Transform3D gt = cs->get_global_transform(); @@ -201,7 +201,7 @@ void CSGShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_i } } -void CSGShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { +void CSGShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node()); if (Object::cast_to<CSGSphere3D>(cs)) { diff --git a/modules/csg/csg_gizmos.h b/modules/csg/csg_gizmos.h index 1dcee642c7..46761370dd 100644 --- a/modules/csg/csg_gizmos.h +++ b/modules/csg/csg_gizmos.h @@ -45,10 +45,10 @@ public: virtual bool is_selectable_when_hidden() const override; virtual void redraw(EditorNode3DGizmo *p_gizmo) override; - virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - virtual Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override; - virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) override; + virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + virtual Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override; + virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) override; CSGShape3DGizmoPlugin(); }; diff --git a/modules/freetype/SCsub b/modules/freetype/SCsub index 476cb9cf2a..27d0777c17 100644 --- a/modules/freetype/SCsub +++ b/modules/freetype/SCsub @@ -48,6 +48,7 @@ if env["builtin_freetype"]: "src/pshinter/pshinter.c", "src/psnames/psnames.c", "src/raster/raster.c", + "src/sdf/sdf.c", "src/smooth/smooth.c", "src/truetype/truetype.c", "src/type1/type1.c", diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 6f7e913864..84db97625b 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -2206,7 +2206,6 @@ GDScriptLanguage::GDScriptLanguage() { GLOBAL_DEF("debug/gdscript/warnings/enable", true); GLOBAL_DEF("debug/gdscript/warnings/treat_warnings_as_errors", false); GLOBAL_DEF("debug/gdscript/warnings/exclude_addons", true); - GLOBAL_DEF("debug/gdscript/completion/autocomplete_setters_and_getters", false); for (int i = 0; i < (int)GDScriptWarning::WARNING_MAX; i++) { String warning = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)i).to_lower(); bool default_enabled = !warning.begins_with("unsafe_"); diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 7c27a096e7..d10e120410 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -966,8 +966,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base if (!_static || Engine::get_singleton()->has_singleton(type)) { List<MethodInfo> methods; - bool is_autocompleting_getters = GLOBAL_GET("debug/gdscript/completion/autocomplete_setters_and_getters").booleanize(); - ClassDB::get_method_list(type, &methods, false, !is_autocompleting_getters); + ClassDB::get_method_list(type, &methods, false, true); for (const MethodInfo &E : methods) { if (E.name.begins_with("_")) { continue; diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 432d31f78f..10f1dd0a41 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -3497,7 +3497,7 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node variable->export_info.hint_string = hint_string; - // This is called after tne analyzer is done finding the type, so this should be set here. + // This is called after the analyzer is done finding the type, so this should be set here. DataType export_type = variable->get_datatype(); if (p_annotation->name == "@export") { diff --git a/modules/gdscript/icons/GDScriptInternal.svg b/modules/gdscript/icons/GDScriptInternal.svg new file mode 100644 index 0000000000..fcabaafbd0 --- /dev/null +++ b/modules/gdscript/icons/GDScriptInternal.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1-.56445 2.2578c-.2364329.0758517-.4668872.16921-.68945.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941c-.1119126.2211335-.2072287.4502818-.28516.68555l-2.2539.5625v2l2.2578.56445c.075942.2357685.1692993.465568.2793.6875l-1.1934 1.9902 1.4141 1.4141 1.9941-1.1953c.2211335.111913.4502818.207229.68555.28516l.5625 2.2539h2l.56445-2.2578c.2357685-.07594.465568-.169299.6875-.2793l1.9902 1.1934 1.4141-1.4141-1.1953-1.9941c.111913-.221133.207229-.4502818.28516-.68555l2.2539-.5625v-2l-2.2578-.56445c-.075942-.2357685-.169299-.4655679-.2793-.6875l1.1934-1.9902-1.4141-1.4141-1.9941 1.1953c-.221133-.1119126-.4502818-.2072287-.68555-.28516l-.5625-2.2539zm1 5c1.1045695 0 2 .8954305 2 2s-.8954305 2-2 2-2-.8954305-2-2 .8954305-2 2-2z" fill="none" stroke="#e0e0e0"/></svg> diff --git a/modules/glslang/SCsub b/modules/glslang/SCsub index 1954a32697..22ef1b5ea9 100644 --- a/modules/glslang/SCsub +++ b/modules/glslang/SCsub @@ -12,7 +12,6 @@ thirdparty_obj = [] if env["builtin_glslang"]: thirdparty_dir = "#thirdparty/glslang/" thirdparty_sources = [ - "glslang/CInterface/glslang_c_interface.cpp", "glslang/MachineIndependent/attribute.cpp", "glslang/MachineIndependent/Constant.cpp", "glslang/MachineIndependent/glslang_tab.cpp", @@ -44,7 +43,6 @@ if env["builtin_glslang"]: "glslang/GenericCodeGen/CodeGen.cpp", "glslang/GenericCodeGen/Link.cpp", "OGLCompilersDLL/InitializeDll.cpp", - "SPIRV/CInterface/spirv_c_interface.cpp", "SPIRV/disassemble.cpp", "SPIRV/doc.cpp", "SPIRV/GlslangToSpv.cpp", @@ -54,7 +52,6 @@ if env["builtin_glslang"]: "SPIRV/SpvPostProcess.cpp", "SPIRV/SPVRemapper.cpp", "SPIRV/SpvTools.cpp", - "StandAlone/ResourceLimits.cpp", ] if env["platform"] == "windows": @@ -65,10 +62,12 @@ if env["builtin_glslang"]: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] # Treat glslang headers as system headers to avoid raising warnings. Not supported on MSVC. + # Include `#thirdparty` to workaround mismatch between location of `SPIRV` in library source + # and in installed public headers. if not env.msvc: - env_glslang.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path]) + env_glslang.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path, "-isystem", Dir("#thirdparty").path]) else: - env_glslang.Prepend(CPPPATH=[thirdparty_dir]) + env_glslang.Prepend(CPPPATH=[thirdparty_dir, "#thirdparty"]) env_glslang.Append(CPPDEFINES=["ENABLE_OPT=0"]) diff --git a/modules/glslang/glslang_resource_limits.h b/modules/glslang/glslang_resource_limits.h new file mode 100644 index 0000000000..05390f95ad --- /dev/null +++ b/modules/glslang/glslang_resource_limits.h @@ -0,0 +1,147 @@ +/*************************************************************************/ +/* glslang_resource_limits.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GLSLANG_RESOURCE_LIMITS_H +#define GLSLANG_RESOURCE_LIMITS_H + +#include <glslang/Include/ResourceLimits.h> + +// Synchronized with upstream glslang/StandAlone/ResourceLimits.cpp which is not +// part of the public API. + +const TBuiltInResource DefaultTBuiltInResource = { + /* .MaxLights = */ 32, + /* .MaxClipPlanes = */ 6, + /* .MaxTextureUnits = */ 32, + /* .MaxTextureCoords = */ 32, + /* .MaxVertexAttribs = */ 64, + /* .MaxVertexUniformComponents = */ 4096, + /* .MaxVaryingFloats = */ 64, + /* .MaxVertexTextureImageUnits = */ 32, + /* .MaxCombinedTextureImageUnits = */ 80, + /* .MaxTextureImageUnits = */ 32, + /* .MaxFragmentUniformComponents = */ 4096, + /* .MaxDrawBuffers = */ 32, + /* .MaxVertexUniformVectors = */ 128, + /* .MaxVaryingVectors = */ 8, + /* .MaxFragmentUniformVectors = */ 16, + /* .MaxVertexOutputVectors = */ 16, + /* .MaxFragmentInputVectors = */ 15, + /* .MinProgramTexelOffset = */ -8, + /* .MaxProgramTexelOffset = */ 7, + /* .MaxClipDistances = */ 8, + /* .MaxComputeWorkGroupCountX = */ 65535, + /* .MaxComputeWorkGroupCountY = */ 65535, + /* .MaxComputeWorkGroupCountZ = */ 65535, + /* .MaxComputeWorkGroupSizeX = */ 1024, + /* .MaxComputeWorkGroupSizeY = */ 1024, + /* .MaxComputeWorkGroupSizeZ = */ 64, + /* .MaxComputeUniformComponents = */ 1024, + /* .MaxComputeTextureImageUnits = */ 16, + /* .MaxComputeImageUniforms = */ 8, + /* .MaxComputeAtomicCounters = */ 8, + /* .MaxComputeAtomicCounterBuffers = */ 1, + /* .MaxVaryingComponents = */ 60, + /* .MaxVertexOutputComponents = */ 64, + /* .MaxGeometryInputComponents = */ 64, + /* .MaxGeometryOutputComponents = */ 128, + /* .MaxFragmentInputComponents = */ 128, + /* .MaxImageUnits = */ 8, + /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8, + /* .MaxCombinedShaderOutputResources = */ 8, + /* .MaxImageSamples = */ 0, + /* .MaxVertexImageUniforms = */ 0, + /* .MaxTessControlImageUniforms = */ 0, + /* .MaxTessEvaluationImageUniforms = */ 0, + /* .MaxGeometryImageUniforms = */ 0, + /* .MaxFragmentImageUniforms = */ 8, + /* .MaxCombinedImageUniforms = */ 8, + /* .MaxGeometryTextureImageUnits = */ 16, + /* .MaxGeometryOutputVertices = */ 256, + /* .MaxGeometryTotalOutputComponents = */ 1024, + /* .MaxGeometryUniformComponents = */ 1024, + /* .MaxGeometryVaryingComponents = */ 64, + /* .MaxTessControlInputComponents = */ 128, + /* .MaxTessControlOutputComponents = */ 128, + /* .MaxTessControlTextureImageUnits = */ 16, + /* .MaxTessControlUniformComponents = */ 1024, + /* .MaxTessControlTotalOutputComponents = */ 4096, + /* .MaxTessEvaluationInputComponents = */ 128, + /* .MaxTessEvaluationOutputComponents = */ 128, + /* .MaxTessEvaluationTextureImageUnits = */ 16, + /* .MaxTessEvaluationUniformComponents = */ 1024, + /* .MaxTessPatchComponents = */ 120, + /* .MaxPatchVertices = */ 32, + /* .MaxTessGenLevel = */ 64, + /* .MaxViewports = */ 16, + /* .MaxVertexAtomicCounters = */ 0, + /* .MaxTessControlAtomicCounters = */ 0, + /* .MaxTessEvaluationAtomicCounters = */ 0, + /* .MaxGeometryAtomicCounters = */ 0, + /* .MaxFragmentAtomicCounters = */ 8, + /* .MaxCombinedAtomicCounters = */ 8, + /* .MaxAtomicCounterBindings = */ 1, + /* .MaxVertexAtomicCounterBuffers = */ 0, + /* .MaxTessControlAtomicCounterBuffers = */ 0, + /* .MaxTessEvaluationAtomicCounterBuffers = */ 0, + /* .MaxGeometryAtomicCounterBuffers = */ 0, + /* .MaxFragmentAtomicCounterBuffers = */ 1, + /* .MaxCombinedAtomicCounterBuffers = */ 1, + /* .MaxAtomicCounterBufferSize = */ 16384, + /* .MaxTransformFeedbackBuffers = */ 4, + /* .MaxTransformFeedbackInterleavedComponents = */ 64, + /* .MaxCullDistances = */ 8, + /* .MaxCombinedClipAndCullDistances = */ 8, + /* .MaxSamples = */ 4, + /* .maxMeshOutputVerticesNV = */ 256, + /* .maxMeshOutputPrimitivesNV = */ 512, + /* .maxMeshWorkGroupSizeX_NV = */ 32, + /* .maxMeshWorkGroupSizeY_NV = */ 1, + /* .maxMeshWorkGroupSizeZ_NV = */ 1, + /* .maxTaskWorkGroupSizeX_NV = */ 32, + /* .maxTaskWorkGroupSizeY_NV = */ 1, + /* .maxTaskWorkGroupSizeZ_NV = */ 1, + /* .maxMeshViewCountNV = */ 4, + /* .maxDualSourceDrawBuffersEXT = */ 1, + + /* .limits = */ { + /* .nonInductiveForLoops = */ 1, + /* .whileLoops = */ 1, + /* .doWhileLoops = */ 1, + /* .generalUniformIndexing = */ 1, + /* .generalAttributeMatrixVectorIndexing = */ 1, + /* .generalVaryingIndexing = */ 1, + /* .generalSamplerIndexing = */ 1, + /* .generalVariableIndexing = */ 1, + /* .generalConstantMatrixVectorIndexing = */ 1, + } +}; + +#endif // GLSLANG_RESOURCE_LIMITS_H diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp index c67d5ff5ab..8e69ba78c7 100644 --- a/modules/glslang/register_types.cpp +++ b/modules/glslang/register_types.cpp @@ -32,10 +32,11 @@ #include "servers/rendering/rendering_device.h" -#include <SPIRV/GlslangToSpv.h> -#include <StandAlone/ResourceLimits.h> +#include "glslang_resource_limits.h" + #include <glslang/Include/Types.h> #include <glslang/Public/ShaderLang.h> +#include <glslang/SPIRV/GlslangToSpv.h> static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage, const String &p_source_code, RenderingDevice::ShaderLanguage p_language, String *r_error, const RenderingDevice::Capabilities *p_capabilities) { Vector<uint8_t> ret; @@ -129,7 +130,7 @@ static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage std::string pre_processed_code; //preprocess - if (!shader.preprocess(&glslang::DefaultTBuiltInResource, DefaultVersion, ENoProfile, false, false, messages, &pre_processed_code, includer)) { + if (!shader.preprocess(&DefaultTBuiltInResource, DefaultVersion, ENoProfile, false, false, messages, &pre_processed_code, includer)) { if (r_error) { (*r_error) = "Failed pre-process:\n"; (*r_error) += shader.getInfoLog(); @@ -144,7 +145,7 @@ static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage shader.setStrings(&cs_strings, 1); //parse - if (!shader.parse(&glslang::DefaultTBuiltInResource, DefaultVersion, false, messages)) { + if (!shader.parse(&DefaultTBuiltInResource, DefaultVersion, false, messages)) { if (r_error) { (*r_error) = "Failed parse:\n"; (*r_error) += shader.getInfoLog(); @@ -190,8 +191,8 @@ static String _get_cache_key_function_glsl(const RenderingDevice::Capabilities * } void preregister_glslang_types() { - // initialize in case it's not initialized. This is done once per thread - // and it's safe to call multiple times + // Initialize in case it's not initialized. This is done once per thread + // and it's safe to call multiple times. glslang::InitializeProcess(); RenderingDevice::shader_set_compile_to_spirv_function(_compile_shader_glsl); RenderingDevice::shader_set_get_cache_key_function(_get_cache_key_function_glsl); diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h index 9fcac3afe2..ac04763569 100644 --- a/modules/mobile_vr/mobile_vr_interface.h +++ b/modules/mobile_vr/mobile_vr_interface.h @@ -35,8 +35,6 @@ #include "servers/xr/xr_positional_tracker.h" /** - @author Bastiaan Olij <mux213@gmail.com> - The mobile interface is a native VR interface that can be used on Android and iOS phones. It contains a basic implementation supporting 3DOF tracking if a gyroscope and accelerometer are present and sets up the proper projection matrices based on the values provided. @@ -160,4 +158,4 @@ public: ~MobileVRInterface(); }; -#endif // !MOBILE_VR_INTERFACE_H +#endif // MOBILE_VR_INTERFACE_H diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs index 75240b0c09..e80b6af68f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs @@ -320,6 +320,9 @@ namespace Godot.Collections internal static extern void godot_icall_Dictionary_KeyValuePairAt(IntPtr ptr, int index, out object key, out object value); [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern void godot_icall_Dictionary_KeyValuePairAt_Generic(IntPtr ptr, int index, out object key, out object value, int valueTypeEncoding, IntPtr valueTypeClass); + + [MethodImpl(MethodImplOptions.InternalCall)] internal static extern void godot_icall_Dictionary_Add(IntPtr ptr, object key, object value); [MethodImpl(MethodImplOptions.InternalCall)] @@ -485,7 +488,7 @@ namespace Godot.Collections private KeyValuePair<TKey, TValue> GetKeyValuePair(int index) { - Dictionary.godot_icall_Dictionary_KeyValuePairAt(GetPtr(), index, out object key, out object value); + Dictionary.godot_icall_Dictionary_KeyValuePairAt_Generic(GetPtr(), index, out object key, out object value, valTypeEncoding, valTypeClass); return new KeyValuePair<TKey, TValue>((TKey)key, (TValue)value); } diff --git a/modules/mono/glue/collections_glue.cpp b/modules/mono/glue/collections_glue.cpp index 56a08a0dd5..8a9f30459c 100644 --- a/modules/mono/glue/collections_glue.cpp +++ b/modules/mono/glue/collections_glue.cpp @@ -241,6 +241,12 @@ void godot_icall_Dictionary_KeyValuePairAt(Dictionary *ptr, int index, MonoObjec *value = GDMonoMarshal::variant_to_mono_object(ptr->get_value_at_index(index)); } +void godot_icall_Dictionary_KeyValuePairAt_Generic(Dictionary *ptr, int index, MonoObject **key, MonoObject **value, uint32_t value_type_encoding, GDMonoClass *value_type_class) { + ManagedType type(value_type_encoding, value_type_class); + *key = GDMonoMarshal::variant_to_mono_object(ptr->get_key_at_index(index)); + *value = GDMonoMarshal::variant_to_mono_object(ptr->get_value_at_index(index), type); +} + void godot_icall_Dictionary_Add(Dictionary *ptr, MonoObject *key, MonoObject *value) { Variant varKey = GDMonoMarshal::mono_object_to_variant(key); Variant *ret = ptr->getptr(varKey); @@ -351,6 +357,7 @@ void godot_register_collections_icalls() { GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Count", godot_icall_Dictionary_Count); GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_KeyValuePairs", godot_icall_Dictionary_KeyValuePairs); GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_KeyValuePairAt", godot_icall_Dictionary_KeyValuePairAt); + GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_KeyValuePairAt_Generic", godot_icall_Dictionary_KeyValuePairAt_Generic); GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Add", godot_icall_Dictionary_Add); GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Clear", godot_icall_Dictionary_Clear); GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Contains", godot_icall_Dictionary_Contains); diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp index 02739f0480..c0cd18e29d 100644 --- a/modules/mono/godotsharp_dirs.cpp +++ b/modules/mono/godotsharp_dirs.cpp @@ -68,7 +68,14 @@ String _get_mono_user_dir() { } else { String settings_path; + // Self-contained mode if a `._sc_` or `_sc_` file is present in executable dir. String exe_dir = OS::get_singleton()->get_executable_path().get_base_dir(); + + // On macOS, look outside .app bundle, since .app bundle is read-only. + if (OS::get_singleton()->has_feature("macos") && exe_dir.ends_with("MacOS") && exe_dir.plus_file("..").simplify_path().ends_with("Contents")) { + exe_dir = exe_dir.plus_file("../../..").simplify_path(); + } + DirAccessRef d = DirAccess::create_for_path(exe_dir); if (d->file_exists("._sc_") || d->file_exists("_sc_")) { diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp index 2b6ae5ef1e..f3da85063a 100644 --- a/modules/navigation/godot_navigation_server.cpp +++ b/modules/navigation/godot_navigation_server.cpp @@ -36,10 +36,6 @@ #include "navigation_mesh_generator.h" #endif -/** - @author AndreaCatania -*/ - /// Creates a struct for each function and a function that once called creates /// an instance of that struct with the submitted parameters. /// Then, that struct is stored in an array; the `sync` function consume that array. diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h index 6cc226b086..c555a358db 100644 --- a/modules/navigation/godot_navigation_server.h +++ b/modules/navigation/godot_navigation_server.h @@ -40,10 +40,6 @@ #include "nav_region.h" #include "rvo_agent.h" -/** - @author AndreaCatania -*/ - /// The commands are functions executed during the `sync` phase. #define MERGE_INTERNAL(A, B) A##B diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp index b33b7933a8..76c31a5f42 100644 --- a/modules/navigation/nav_map.cpp +++ b/modules/navigation/nav_map.cpp @@ -36,10 +36,6 @@ #include <algorithm> -/** - @author AndreaCatania -*/ - #define THREE_POINTS_CROSS_PRODUCT(m_a, m_b, m_c) (((m_c) - (m_a)).cross((m_b) - (m_a))) void NavMap::set_up(Vector3 p_up) { diff --git a/modules/navigation/nav_map.h b/modules/navigation/nav_map.h index cd730fe3ef..1802f4e907 100644 --- a/modules/navigation/nav_map.h +++ b/modules/navigation/nav_map.h @@ -36,11 +36,8 @@ #include "core/math/math_defs.h" #include "core/templates/map.h" #include "nav_utils.h" -#include <KdTree.h> -/** - @author AndreaCatania -*/ +#include <KdTree.h> class NavRegion; class RvoAgent; diff --git a/modules/navigation/nav_region.cpp b/modules/navigation/nav_region.cpp index 7d94e22014..fea0ad519a 100644 --- a/modules/navigation/nav_region.cpp +++ b/modules/navigation/nav_region.cpp @@ -32,10 +32,6 @@ #include "nav_map.h" -/** - @author AndreaCatania -*/ - void NavRegion::set_map(NavMap *p_map) { map = p_map; polygons_dirty = true; diff --git a/modules/navigation/nav_region.h b/modules/navigation/nav_region.h index c344414912..7a6da281c0 100644 --- a/modules/navigation/nav_region.h +++ b/modules/navigation/nav_region.h @@ -35,11 +35,8 @@ #include "nav_rid.h" #include "nav_utils.h" -#include <vector> -/** - @author AndreaCatania -*/ +#include <vector> class NavMap; class NavRegion; diff --git a/modules/navigation/nav_rid.h b/modules/navigation/nav_rid.h index 2283973cac..31e20440d2 100644 --- a/modules/navigation/nav_rid.h +++ b/modules/navigation/nav_rid.h @@ -33,10 +33,6 @@ #include "core/templates/rid.h" -/** - @author AndreaCatania -*/ - class NavRid { RID self; diff --git a/modules/navigation/nav_utils.h b/modules/navigation/nav_utils.h index 2d725f214c..a6f51a4698 100644 --- a/modules/navigation/nav_utils.h +++ b/modules/navigation/nav_utils.h @@ -35,10 +35,6 @@ #include <vector> -/** - @author AndreaCatania -*/ - class NavRegion; namespace gd { diff --git a/modules/navigation/rvo_agent.cpp b/modules/navigation/rvo_agent.cpp index 6c38eaed0f..c967d0bf98 100644 --- a/modules/navigation/rvo_agent.cpp +++ b/modules/navigation/rvo_agent.cpp @@ -32,10 +32,6 @@ #include "nav_map.h" -/** - @author AndreaCatania -*/ - RvoAgent::RvoAgent() { callback.id = ObjectID(); } diff --git a/modules/navigation/rvo_agent.h b/modules/navigation/rvo_agent.h index 2bf824186b..54baab404e 100644 --- a/modules/navigation/rvo_agent.h +++ b/modules/navigation/rvo_agent.h @@ -36,10 +36,6 @@ #include <Agent.h> -/** - @author AndreaCatania -*/ - class NavMap; class RvoAgent : public NavRid { diff --git a/modules/svg/SCsub b/modules/svg/SCsub index c7228a8d0b..bb03147731 100644 --- a/modules/svg/SCsub +++ b/modules/svg/SCsub @@ -9,16 +9,66 @@ env_svg = env_modules.Clone() thirdparty_obj = [] -thirdparty_dir = "#thirdparty/nanosvg/" +thirdparty_dir = "#thirdparty/thorvg/" thirdparty_sources = [ - "nanosvg.cc", + "src/lib/tvgBezier.cpp", + "src/lib/tvgCanvas.cpp", + "src/lib/tvgFill.cpp", + "src/lib/tvgGlCanvas.cpp", + "src/lib/tvgInitializer.cpp", + "src/lib/tvgLinearGradient.cpp", + "src/lib/tvgLoader.cpp", + "src/lib/tvgLzw.cpp", + "src/lib/tvgPaint.cpp", + "src/lib/tvgPicture.cpp", + "src/lib/tvgRadialGradient.cpp", + "src/lib/tvgRender.cpp", + "src/lib/tvgSaver.cpp", + "src/lib/tvgScene.cpp", + "src/lib/tvgShape.cpp", + "src/lib/tvgSwCanvas.cpp", + "src/lib/tvgTaskScheduler.cpp", + "src/loaders/raw/tvgRawLoader.cpp", + "src/loaders/svg/tvgXmlParser.cpp", + "src/loaders/svg/tvgSvgUtil.cpp", + "src/loaders/svg/tvgSvgSceneBuilder.cpp", + "src/loaders/svg/tvgSvgPath.cpp", + "src/loaders/svg/tvgSvgLoader.cpp", + "src/loaders/tvg/tvgTvgBinInterpreter.cpp", + "src/loaders/tvg/tvgTvgLoader.cpp", + "src/loaders/jpg/tvgJpgLoader.cpp", + "src/loaders/jpg/tvgJpgd.cpp", + "src/loaders/external_png/tvgPngLoader.cpp", + "src/lib/sw_engine/tvgSwFill.cpp", + "src/lib/sw_engine/tvgSwImage.cpp", + "src/lib/sw_engine/tvgSwMath.cpp", + "src/lib/sw_engine/tvgSwMemPool.cpp", + "src/lib/sw_engine/tvgSwRaster.cpp", + "src/lib/sw_engine/tvgSwRenderer.cpp", + "src/lib/sw_engine/tvgSwRle.cpp", + "src/lib/sw_engine/tvgSwShape.cpp", + "src/lib/sw_engine/tvgSwStroke.cpp", + "src/savers/tvg/tvgTvgSaver.cpp", ] + thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_svg.Prepend(CPPPATH=[thirdparty_dir]) +env_svg.Prepend(CPPPATH=[thirdparty_dir + "inc"]) env_thirdparty = env_svg.Clone() env_thirdparty.disable_warnings() +env_thirdparty.Prepend( + CPPPATH=[ + thirdparty_dir + "src/lib", + thirdparty_dir + "src/lib/sw_engine", + thirdparty_dir + "src/loaders/raw", + thirdparty_dir + "src/loaders/svg", + thirdparty_dir + "src/loaders/jpg", + thirdparty_dir + "src/loaders/png", + thirdparty_dir + "src/loaders/tvg", + thirdparty_dir + "src/savers/tvg", + ] +) env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources) env.modules_sources += thirdparty_obj diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp index bf43d7a4ad..96b83bf25a 100644 --- a/modules/svg/image_loader_svg.cpp +++ b/modules/svg/image_loader_svg.cpp @@ -30,132 +30,118 @@ #include "image_loader_svg.h" -#include <nanosvg.h> -#include <nanosvgrast.h> - -void SVGRasterizer::rasterize(NSVGimage *p_image, float p_tx, float p_ty, float p_scale, unsigned char *p_dst, int p_w, int p_h, int p_stride) { - nsvgRasterize(rasterizer, p_image, p_tx, p_ty, p_scale, p_dst, p_w, p_h, p_stride); -} - -SVGRasterizer::SVGRasterizer() { - rasterizer = nsvgCreateRasterizer(); -} - -SVGRasterizer::~SVGRasterizer() { - nsvgDeleteRasterizer(rasterizer); -} - -SVGRasterizer ImageLoaderSVG::rasterizer; - -inline void change_nsvg_paint_color(NSVGpaint *p_paint, const uint32_t p_old, const uint32_t p_new) { - if (p_paint->type == NSVG_PAINT_COLOR) { - if (p_paint->color << 8 == p_old << 8) { - p_paint->color = (p_paint->color & 0xFF000000) | (p_new & 0x00FFFFFF); - } - } - - if (p_paint->type == NSVG_PAINT_LINEAR_GRADIENT || p_paint->type == NSVG_PAINT_RADIAL_GRADIENT) { - for (int stop_index = 0; stop_index < p_paint->gradient->nstops; stop_index++) { - if (p_paint->gradient->stops[stop_index].color << 8 == p_old << 8) { - p_paint->gradient->stops[stop_index].color = p_new; +#include "core/os/memory.h" +#include "core/variant/variant.h" + +#include <thorvg.h> + +void ImageLoaderSVG::_replace_color_property(const String &p_prefix, String &r_string) { + // Replace colors in the SVG based on what is configured in `replace_colors`. + // Used to change the colors of editor icons based on the used theme. + // The strings being replaced are typically of the form: + // fill="#5abbef" + // But can also be 3-letter codes, include alpha, be "none" or a named color + // string ("blue"). So we convert to Godot Color to compare with `replace_colors`. + + const int prefix_len = p_prefix.length(); + int pos = r_string.find(p_prefix); + while (pos != -1) { + pos += prefix_len; // Skip prefix. + int end_pos = r_string.find("\"", pos); + ERR_FAIL_COND_MSG(end_pos == -1, vformat("Malformed SVG string after property \"%s\".", p_prefix)); + const String color_code = r_string.substr(pos, end_pos - pos); + if (color_code != "none" && !color_code.begins_with("url(")) { + const Color color = Color(color_code); // Handles both HTML codes and named colors. + if (replace_colors.has(color)) { + r_string = r_string.left(pos) + "#" + replace_colors[color].operator Color().to_html(false) + r_string.substr(end_pos); } } + // Search for other occurrences. + pos = r_string.find(p_prefix, pos); } } -void ImageLoaderSVG::_convert_colors(NSVGimage *p_svg_image) { - for (NSVGshape *shape = p_svg_image->shapes; shape != nullptr; shape = shape->next) { - for (int i = 0; i < replace_colors.old_colors.size(); i++) { - change_nsvg_paint_color(&(shape->stroke), replace_colors.old_colors[i], replace_colors.new_colors[i]); - change_nsvg_paint_color(&(shape->fill), replace_colors.old_colors[i], replace_colors.new_colors[i]); - } - } -} +void ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, String p_string, float p_scale, bool p_upsample, bool p_convert_color) { + ERR_FAIL_COND(Math::is_zero_approx(p_scale)); -void ImageLoaderSVG::set_convert_colors(Dictionary *p_replace_color) { - if (p_replace_color) { - Dictionary replace_color = *p_replace_color; - for (int i = 0; i < replace_color.keys().size(); i++) { - Variant o_c = replace_color.keys()[i]; - Variant n_c = replace_color[replace_color.keys()[i]]; - if (o_c.get_type() == Variant::COLOR && n_c.get_type() == Variant::COLOR) { - Color old_color = o_c; - Color new_color = n_c; - replace_colors.old_colors.push_back(old_color.to_abgr32()); - replace_colors.new_colors.push_back(new_color.to_abgr32()); - } - } - } else { - replace_colors.old_colors.clear(); - replace_colors.new_colors.clear(); + if (p_convert_color) { + _replace_color_property("stop-color=\"", p_string); + _replace_color_property("fill=\"", p_string); + _replace_color_property("stroke=\"", p_string); } -} -Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const Vector<uint8_t> *p_data, float p_scale, bool upsample, bool convert_colors) { - NSVGimage *svg_image; - const uint8_t *src_r = p_data->ptr(); - svg_image = nsvgParse((char *)src_r, "px", 96); - if (svg_image == nullptr) { - ERR_PRINT("SVG Corrupted"); - return ERR_FILE_CORRUPT; - } + std::unique_ptr<tvg::Picture> picture = tvg::Picture::gen(); + PackedByteArray bytes = p_string.to_utf8_buffer(); - if (convert_colors) { - _convert_colors(svg_image); + tvg::Result result = picture->load((const char *)bytes.ptr(), bytes.size(), "svg", true); + if (result != tvg::Result::Success) { + return; } + float fw, fh; + picture->viewbox(nullptr, nullptr, &fw, &fh); - const float upscale = upsample ? 2.0 : 1.0; - - const int w = (int)(svg_image->width * p_scale * upscale); - ERR_FAIL_COND_V_MSG(w > Image::MAX_WIDTH, ERR_PARAMETER_RANGE_ERROR, vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max width.", rtos(p_scale))); - - const int h = (int)(svg_image->height * p_scale * upscale); - ERR_FAIL_COND_V_MSG(h > Image::MAX_HEIGHT, ERR_PARAMETER_RANGE_ERROR, vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max height.", rtos(p_scale))); - - Vector<uint8_t> dst_image; - dst_image.resize(w * h * 4); + uint32_t width = MIN(fw * p_scale, 16 * 1024); + uint32_t height = MIN(fh * p_scale, 16 * 1024); + picture->size(width, height); - uint8_t *dw = dst_image.ptrw(); + std::unique_ptr<tvg::SwCanvas> sw_canvas = tvg::SwCanvas::gen(); + // Note: memalloc here, be sure to memfree before any return. + uint32_t *buffer = (uint32_t *)memalloc(sizeof(uint32_t) * width * height); - rasterizer.rasterize(svg_image, 0, 0, p_scale * upscale, (unsigned char *)dw, w, h, w * 4); - - p_image->create(w, h, false, Image::FORMAT_RGBA8, dst_image); - if (upsample) { - p_image->shrink_x2(); + tvg::Result res = sw_canvas->target(buffer, width, width, height, tvg::SwCanvas::ARGB8888_STRAIGHT); + if (res != tvg::Result::Success) { + memfree(buffer); + ERR_FAIL_MSG("ImageLoaderSVG can't create image."); } - nsvgDelete(svg_image); + res = sw_canvas->push(move(picture)); + if (res != tvg::Result::Success) { + memfree(buffer); + ERR_FAIL_MSG("ImageLoaderSVG can't create image."); + } - return OK; -} + res = sw_canvas->draw(); + if (res != tvg::Result::Success) { + memfree(buffer); + ERR_FAIL_MSG("ImageLoaderSVG can't create image."); + } -Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *p_svg_str, float p_scale, bool upsample, bool convert_colors) { - size_t str_len = strlen(p_svg_str); - Vector<uint8_t> src_data; - src_data.resize(str_len + 1); - uint8_t *src_w = src_data.ptrw(); - memcpy(src_w, p_svg_str, str_len + 1); + res = sw_canvas->sync(); + if (res != tvg::Result::Success) { + memfree(buffer); + ERR_FAIL_MSG("ImageLoaderSVG can't create image."); + } - return _create_image(p_image, &src_data, p_scale, upsample, convert_colors); -} + Vector<uint8_t> image; + image.resize(width * height * sizeof(uint32_t)); + + for (uint32_t y = 0; y < height; y++) { + for (uint32_t x = 0; x < width; x++) { + uint32_t n = buffer[y * width + x]; + const size_t offset = sizeof(uint32_t) * width * y + sizeof(uint32_t) * x; + image.write[offset + 0] = (n >> 16) & 0xff; + image.write[offset + 1] = (n >> 8) & 0xff; + image.write[offset + 2] = n & 0xff; + image.write[offset + 3] = (n >> 24) & 0xff; + } + } -Error ImageLoaderSVG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { - uint64_t size = f->get_length(); - Vector<uint8_t> src_image; - src_image.resize(size + 1); - uint8_t *src_w = src_image.ptrw(); - f->get_buffer(src_w, size); - src_w[size] = '\0'; + res = sw_canvas->clear(true); + memfree(buffer); - return _create_image(p_image, &src_image, p_scale, 1.0); + p_image->create(width, height, false, Image::FORMAT_RGBA8, image); } void ImageLoaderSVG::get_recognized_extensions(List<String> *p_extensions) const { p_extensions->push_back("svg"); - p_extensions->push_back("svgz"); } -ImageLoaderSVG::ImageLoaderSVG() { +Error ImageLoaderSVG::load_image(Ref<Image> p_image, FileAccess *p_fileaccess, bool p_force_linear, float p_scale) { + String svg = p_fileaccess->get_as_utf8_string(); + create_image_from_string(p_image, svg, p_scale, false, false); + ERR_FAIL_COND_V(p_image->is_empty(), FAILED); + if (p_force_linear) { + p_image->srgb_to_linear(); + } + return OK; } - -ImageLoaderSVG::ReplaceColors ImageLoaderSVG::replace_colors; diff --git a/modules/svg/image_loader_svg.h b/modules/svg/image_loader_svg.h index 6052bf9831..d0bd71d92d 100644 --- a/modules/svg/image_loader_svg.h +++ b/modules/svg/image_loader_svg.h @@ -32,42 +32,18 @@ #define IMAGE_LOADER_SVG_H #include "core/io/image_loader.h" -#include "core/string/ustring.h" - -/** - @author Daniel Ramirez <djrmuv@gmail.com> -*/ - -// Forward declare and include thirdparty headers in .cpp. -struct NSVGrasterizer; -struct NSVGimage; - -class SVGRasterizer { - NSVGrasterizer *rasterizer; - -public: - void rasterize(NSVGimage *p_image, float p_tx, float p_ty, float p_scale, unsigned char *p_dst, int p_w, int p_h, int p_stride); - - SVGRasterizer(); - ~SVGRasterizer(); -}; class ImageLoaderSVG : public ImageFormatLoader { - static struct ReplaceColors { - List<uint32_t> old_colors; - List<uint32_t> new_colors; - } replace_colors; - static SVGRasterizer rasterizer; - static void _convert_colors(NSVGimage *p_svg_image); - static Error _create_image(Ref<Image> p_image, const Vector<uint8_t> *p_data, float p_scale, bool upsample, bool convert_colors = false); + Dictionary replace_colors; + void _replace_color_property(const String &p_prefix, String &r_string); public: - static void set_convert_colors(Dictionary *p_replace_color = nullptr); - static Error create_image_from_string(Ref<Image> p_image, const char *p_svg_str, float p_scale, bool upsample, bool convert_colors = false); + // Called by the editor to handle theme icon colors. + void set_replace_colors(Dictionary p_replace_colors) { replace_colors = p_replace_colors; } + void create_image_from_string(Ref<Image> p_image, String p_string, float p_scale, bool p_upsample, bool p_convert_color); - virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale); - virtual void get_recognized_extensions(List<String> *p_extensions) const; - ImageLoaderSVG(); + virtual Error load_image(Ref<Image> p_image, FileAccess *p_fileaccess, bool p_force_linear, float p_scale) override; + virtual void get_recognized_extensions(List<String> *p_extensions) const override; }; -#endif +#endif // IMAGE_LOADER_SVG_H diff --git a/modules/svg/register_types.cpp b/modules/svg/register_types.cpp index 1560af95c3..a4341c6f1e 100644 --- a/modules/svg/register_types.cpp +++ b/modules/svg/register_types.cpp @@ -32,13 +32,23 @@ #include "image_loader_svg.h" +#include <thorvg.h> + static ImageLoaderSVG *image_loader_svg = nullptr; void register_svg_types() { + tvg::CanvasEngine tvgEngine = tvg::CanvasEngine::Sw; + if (tvg::Initializer::init(tvgEngine, 0) != tvg::Result::Success) { + return; + } image_loader_svg = memnew(ImageLoaderSVG); ImageLoader::add_image_format_loader(image_loader_svg); } void unregister_svg_types() { + if (!image_loader_svg) { + return; + } memdelete(image_loader_svg); + tvg::Initializer::term(tvg::CanvasEngine::Sw); } diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index f9997a437f..6002dc80da 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -3029,6 +3029,14 @@ TextServer::Direction TextServerAdvanced::shaped_text_get_direction(RID p_shaped return sd->direction; } +TextServer::Direction TextServerAdvanced::shaped_text_get_inferred_direction(RID p_shaped) const { + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V(!sd, TextServer::DIRECTION_LTR); + + MutexLock lock(sd->mutex); + return sd->para_direction; +} + void TextServerAdvanced::shaped_text_set_custom_punctuation(RID p_shaped, const String &p_punct) { _THREAD_SAFE_METHOD_ ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); @@ -3582,7 +3590,11 @@ float TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, float p_width, float justification_width; if ((p_jst_flags & JUSTIFICATION_CONSTRAIN_ELLIPSIS) == JUSTIFICATION_CONSTRAIN_ELLIPSIS) { if (sd->overrun_trim_data.trim_pos >= 0) { - start_pos = sd->overrun_trim_data.trim_pos; + if (sd->para_direction == DIRECTION_RTL) { + start_pos = sd->overrun_trim_data.trim_pos; + } else { + end_pos = sd->overrun_trim_data.trim_pos; + } justification_width = sd->width_trimmed; } else { return sd->width; @@ -3592,6 +3604,7 @@ float TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, float p_width, } if ((p_jst_flags & JUSTIFICATION_TRIM_EDGE_SPACES) == JUSTIFICATION_TRIM_EDGE_SPACES) { + // Trim spaces. while ((start_pos < end_pos) && ((sd->glyphs[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { justification_width -= sd->glyphs[start_pos].advance * sd->glyphs[start_pos].repeat; sd->glyphs.write[start_pos].advance = 0; @@ -3602,6 +3615,14 @@ float TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, float p_width, sd->glyphs.write[end_pos].advance = 0; end_pos -= sd->glyphs[end_pos].count; } + } else { + // Skip breaks, but do not reset size. + while ((start_pos < end_pos) && ((sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { + start_pos += sd->glyphs[start_pos].count; + } + while ((start_pos < end_pos) && ((sd->glyphs[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (sd->glyphs[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { + end_pos -= sd->glyphs[end_pos].count; + } } int space_count = 0; @@ -3610,7 +3631,10 @@ float TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, float p_width, const Glyph &gl = sd->glyphs[i]; if (gl.count > 0) { if ((gl.flags & GRAPHEME_IS_ELONGATION) == GRAPHEME_IS_ELONGATION) { - elongation_count++; + if ((i > 0) && ((sd->glyphs[i - 1].flags & GRAPHEME_IS_ELONGATION) != GRAPHEME_IS_ELONGATION)) { + // Expand once per elongation sequence. + elongation_count++; + } } if ((gl.flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE) { space_count++; @@ -3624,12 +3648,17 @@ float TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, float p_width, Glyph &gl = sd->glyphs.write[i]; if (gl.count > 0) { if (((gl.flags & GRAPHEME_IS_ELONGATION) == GRAPHEME_IS_ELONGATION) && (gl.advance > 0)) { - int count = delta_width_per_kashida / gl.advance; - int prev_count = gl.repeat; - if ((gl.flags & GRAPHEME_IS_VIRTUAL) == GRAPHEME_IS_VIRTUAL) { - gl.repeat = MAX(count, 0); + if ((i > 0) && ((sd->glyphs[i - 1].flags & GRAPHEME_IS_ELONGATION) != GRAPHEME_IS_ELONGATION)) { + // Expand once per elongation sequence. + int count = delta_width_per_kashida / gl.advance; + int prev_count = gl.repeat; + if ((gl.flags & GRAPHEME_IS_VIRTUAL) == GRAPHEME_IS_VIRTUAL) { + gl.repeat = MAX(count, 0); + } else { + gl.repeat = MAX(count + 1, 1); + } + justification_width += (gl.repeat - prev_count) * gl.advance; } - justification_width += (gl.repeat - prev_count) * gl.advance; } } } @@ -3671,7 +3700,7 @@ float TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, float p_width, sd->width = justification_width; } - return sd->width; + return justification_width; } float TextServerAdvanced::shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) { @@ -3759,23 +3788,56 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, fl return; } + Vector<ShapedTextDataAdvanced::Span> &spans = sd->spans; + if (sd->parent != RID()) { + ShapedTextDataAdvanced *parent_sd = shaped_owner.get_or_null(sd->parent); + ERR_FAIL_COND(!parent_sd->valid); + spans = parent_sd->spans; + } + + if (spans.size() == 0) { + return; + } + int sd_size = sd->glyphs.size(); - RID last_gl_font_rid = sd_glyphs[sd_size - 1].font_rid; int last_gl_font_size = sd_glyphs[sd_size - 1].font_size; - int32_t dot_gl_idx = font_get_glyph_index(last_gl_font_rid, last_gl_font_size, '.'); - Vector2 dot_adv = font_get_glyph_advance(last_gl_font_rid, last_gl_font_size, dot_gl_idx); - int32_t whitespace_gl_idx = font_get_glyph_index(last_gl_font_rid, last_gl_font_size, ' '); - Vector2 whitespace_adv = font_get_glyph_advance(last_gl_font_rid, last_gl_font_size, whitespace_gl_idx); + + // Find usable fonts, if fonts from the last glyph do not have required chars. + RID dot_gl_font_rid = sd_glyphs[sd_size - 1].font_rid; + if (!font_has_char(dot_gl_font_rid, '.')) { + const Vector<RID> &fonts = spans[spans.size() - 1].fonts; + for (const RID &font : fonts) { + if (font_has_char(font, '.')) { + dot_gl_font_rid = font; + break; + } + } + } + RID whitespace_gl_font_rid = sd_glyphs[sd_size - 1].font_rid; + if (!font_has_char(whitespace_gl_font_rid, '.')) { + const Vector<RID> &fonts = spans[spans.size() - 1].fonts; + for (const RID &font : fonts) { + if (font_has_char(font, ' ')) { + whitespace_gl_font_rid = font; + break; + } + } + } + + int32_t dot_gl_idx = dot_gl_font_rid.is_valid() ? font_get_glyph_index(dot_gl_font_rid, last_gl_font_size, '.') : -10; + Vector2 dot_adv = dot_gl_font_rid.is_valid() ? font_get_glyph_advance(dot_gl_font_rid, last_gl_font_size, dot_gl_idx) : Vector2(); + int32_t whitespace_gl_idx = whitespace_gl_font_rid.is_valid() ? font_get_glyph_index(whitespace_gl_font_rid, last_gl_font_size, ' ') : -10; + Vector2 whitespace_adv = whitespace_gl_font_rid.is_valid() ? font_get_glyph_advance(whitespace_gl_font_rid, last_gl_font_size, whitespace_gl_idx) : Vector2(); int ellipsis_width = 0; - if (add_ellipsis) { - ellipsis_width = 3 * dot_adv.x + font_get_spacing(last_gl_font_rid, last_gl_font_size, SPACING_GLYPH) + (cut_per_word ? whitespace_adv.x : 0); + if (add_ellipsis && whitespace_gl_font_rid.is_valid()) { + ellipsis_width = 3 * dot_adv.x + font_get_spacing(whitespace_gl_font_rid, last_gl_font_size, SPACING_GLYPH) + (cut_per_word ? whitespace_adv.x : 0); } int ell_min_characters = 6; float width = sd->width; - bool is_rtl = sd->direction == DIRECTION_RTL || (sd->direction == DIRECTION_AUTO && sd->para_direction == DIRECTION_RTL); + bool is_rtl = sd->para_direction == DIRECTION_RTL; int trim_pos = (is_rtl) ? sd_size : 0; int ellipsis_pos = (enforce_ellipsis) ? 0 : -1; @@ -3833,23 +3895,25 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, fl gl.count = 1; gl.advance = whitespace_adv.x; gl.index = whitespace_gl_idx; - gl.font_rid = last_gl_font_rid; + gl.font_rid = whitespace_gl_font_rid; gl.font_size = last_gl_font_size; gl.flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT | GRAPHEME_IS_VIRTUAL | (is_rtl ? GRAPHEME_IS_RTL : 0); sd->overrun_trim_data.ellipsis_glyph_buf.append(gl); } // Add ellipsis dots. - Glyph gl; - gl.count = 1; - gl.repeat = 3; - gl.advance = dot_adv.x; - gl.index = dot_gl_idx; - gl.font_rid = last_gl_font_rid; - gl.font_size = last_gl_font_size; - gl.flags = GRAPHEME_IS_PUNCTUATION | GRAPHEME_IS_VIRTUAL | (is_rtl ? GRAPHEME_IS_RTL : 0); - - sd->overrun_trim_data.ellipsis_glyph_buf.append(gl); + if (dot_gl_idx != 0) { + Glyph gl; + gl.count = 1; + gl.repeat = 3; + gl.advance = dot_adv.x; + gl.index = dot_gl_idx; + gl.font_rid = dot_gl_font_rid; + gl.font_size = last_gl_font_size; + gl.flags = GRAPHEME_IS_PUNCTUATION | GRAPHEME_IS_VIRTUAL | (is_rtl ? GRAPHEME_IS_RTL : 0); + + sd->overrun_trim_data.ellipsis_glyph_buf.append(gl); + } } sd->text_trimmed = true; @@ -3920,21 +3984,19 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) { for (int j = r_start; j < r_end; j++) { char32_t c = sd->text[j - sd->start]; if (is_whitespace(c)) { - breaks[j] = false; + breaks[j + 1] = false; } if (is_linebreak(c)) { - breaks[j] = true; + breaks[j + 1] = true; } } } else { while (ubrk_next(bi) != UBRK_DONE) { - int pos = _convert_pos(sd, ubrk_current(bi)) + r_start - 1; - if (pos != r_end) { - if ((ubrk_getRuleStatus(bi) >= UBRK_LINE_HARD) && (ubrk_getRuleStatus(bi) < UBRK_LINE_HARD_LIMIT)) { - breaks[pos] = true; - } else if ((ubrk_getRuleStatus(bi) >= UBRK_LINE_SOFT) && (ubrk_getRuleStatus(bi) < UBRK_LINE_SOFT_LIMIT)) { - breaks[pos] = false; - } + int pos = _convert_pos(sd, ubrk_current(bi)) + r_start; + if ((ubrk_getRuleStatus(bi) >= UBRK_LINE_HARD) && (ubrk_getRuleStatus(bi) < UBRK_LINE_HARD_LIMIT)) { + breaks[pos] = true; + } else if ((ubrk_getRuleStatus(bi) >= UBRK_LINE_SOFT) && (ubrk_getRuleStatus(bi) < UBRK_LINE_SOFT_LIMIT)) { + breaks[pos] = false; } } } @@ -3978,34 +4040,46 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) { if (is_underscore(c)) { sd_glyphs[i].flags |= GRAPHEME_IS_UNDERSCORE; } - if (breaks.has(sd->glyphs[i].start)) { - if (breaks[sd->glyphs[i].start]) { + if (breaks.has(sd_glyphs[i].end)) { + if (breaks[sd_glyphs[i].end] && (is_linebreak(c))) { sd_glyphs[i].flags |= GRAPHEME_IS_BREAK_HARD; + } else if (is_whitespace(c)) { + sd_glyphs[i].flags |= GRAPHEME_IS_BREAK_SOFT; } else { - if (is_whitespace(c)) { - sd_glyphs[i].flags |= GRAPHEME_IS_BREAK_SOFT; + int count = sd_glyphs[i].count; + // Do not add extra space at the end of the line. + if (sd_glyphs[i].end == sd->end) { + continue; + } + // Do not add extra space after existing space. + if (sd_glyphs[i].flags & GRAPHEME_IS_RTL) { + if ((i + count < sd_size - 1) && ((sd_glyphs[i + count].flags & (GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT)) == (GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT))) { + continue; + } } else { - Glyph gl; - gl.start = sd_glyphs[i].start; - gl.end = sd_glyphs[i].end; - gl.count = 1; - gl.font_rid = sd_glyphs[i].font_rid; - gl.font_size = sd_glyphs[i].font_size; - gl.flags = GRAPHEME_IS_BREAK_SOFT | GRAPHEME_IS_VIRTUAL; - if (sd->glyphs[i].flags & GRAPHEME_IS_RTL) { - gl.flags |= GRAPHEME_IS_RTL; - sd->glyphs.insert(i, gl); // Insert before. - } else { - sd->glyphs.insert(i + sd_glyphs[i].count, gl); // Insert after. + if ((i > 0) && ((sd_glyphs[i - 1].flags & (GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT)) == (GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT))) { + continue; } - - // Update write pointer and size. - sd_size = sd->glyphs.size(); - sd_glyphs = sd->glyphs.ptrw(); - - i += sd_glyphs[i].count; - continue; } + Glyph gl; + gl.start = sd_glyphs[i].start; + gl.end = sd_glyphs[i].end; + gl.count = 1; + gl.font_rid = sd_glyphs[i].font_rid; + gl.font_size = sd_glyphs[i].font_size; + gl.flags = GRAPHEME_IS_BREAK_SOFT | GRAPHEME_IS_VIRTUAL | GRAPHEME_IS_SPACE; + if (sd_glyphs[i].flags & GRAPHEME_IS_RTL) { + gl.flags |= GRAPHEME_IS_RTL; + sd->glyphs.insert(i, gl); // Insert before. + } else { + sd->glyphs.insert(i + count, gl); // Insert after. + } + i += count; + + // Update write pointer and size. + sd_size = sd->glyphs.size(); + sd_glyphs = sd->glyphs.ptrw(); + continue; } } @@ -4151,53 +4225,80 @@ bool TextServerAdvanced::shaped_text_update_justification_ops(RID p_shaped) { sd->sort_valid = false; sd->glyphs_logical.clear(); - int sd_size = sd->glyphs.size(); + Glyph *sd_glyphs = sd->glyphs.ptrw(); + int sd_size = sd->glyphs.size(); if (jstops.size() > 0) { for (int i = 0; i < sd_size; i++) { - if (sd->glyphs[i].count > 0) { - if (jstops.has(sd->glyphs[i].start)) { - char32_t c = sd->text[sd->glyphs[i].start - sd->start]; + if (sd_glyphs[i].count > 0) { + char32_t c = sd->text[sd_glyphs[i].start - sd->start]; + if (c == 0x0640) { + sd_glyphs[i].flags |= GRAPHEME_IS_ELONGATION; + } + if (jstops.has(sd_glyphs[i].start)) { if (c == 0xfffc) { continue; } - if (jstops[sd->glyphs[i].start]) { - if (c == 0x0640) { - sd->glyphs.write[i].flags |= GRAPHEME_IS_ELONGATION; - } else { - if (sd->glyphs[i].font_rid != RID()) { + if (jstops[sd_glyphs[i].start]) { + if (c != 0x0640) { + if (sd_glyphs[i].font_rid != RID()) { Glyph gl = _shape_single_glyph(sd, 0x0640, HB_SCRIPT_ARABIC, HB_DIRECTION_RTL, sd->glyphs[i].font_rid, sd->glyphs[i].font_size); - if ((gl.flags & GRAPHEME_IS_VALID) == GRAPHEME_IS_VALID) { - gl.start = sd->glyphs[i].start; - gl.end = sd->glyphs[i].end; + if ((sd_glyphs[i].flags & GRAPHEME_IS_VALID) == GRAPHEME_IS_VALID) { + gl.start = sd_glyphs[i].start; + gl.end = sd_glyphs[i].end; gl.repeat = 0; gl.count = 1; if (sd->orientation == ORIENTATION_HORIZONTAL) { - gl.y_off = sd->glyphs[i].y_off; + gl.y_off = sd_glyphs[i].y_off; } else { - gl.x_off = sd->glyphs[i].x_off; + gl.x_off = sd_glyphs[i].x_off; } gl.flags |= GRAPHEME_IS_ELONGATION | GRAPHEME_IS_VIRTUAL; sd->glyphs.insert(i, gl); i++; + + // Update write pointer and size. + sd_size = sd->glyphs.size(); + sd_glyphs = sd->glyphs.ptrw(); + continue; } } } - } else if (!is_whitespace(c)) { + } else if ((sd_glyphs[i].flags & GRAPHEME_IS_SPACE) != GRAPHEME_IS_SPACE) { + int count = sd_glyphs[i].count; + // Do not add extra spaces at the end of the line. + if (sd_glyphs[i].end == sd->end) { + continue; + } + // Do not add extra space after existing space. + if (sd_glyphs[i].flags & GRAPHEME_IS_RTL) { + if ((i + count < sd_size - 1) && ((sd_glyphs[i + count].flags & (GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT)) == (GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT))) { + continue; + } + } else { + if ((i > 0) && ((sd_glyphs[i - 1].flags & (GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT)) == (GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT))) { + continue; + } + } + // Inject virtual space for alignment. Glyph gl; - gl.start = sd->glyphs[i].start; - gl.end = sd->glyphs[i].end; + gl.start = sd_glyphs[i].start; + gl.end = sd_glyphs[i].end; gl.count = 1; - gl.font_rid = sd->glyphs[i].font_rid; - gl.font_size = sd->glyphs[i].font_size; + gl.font_rid = sd_glyphs[i].font_rid; + gl.font_size = sd_glyphs[i].font_size; gl.flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_VIRTUAL; - if (sd->glyphs[i].flags & GRAPHEME_IS_RTL) { + if (sd_glyphs[i].flags & GRAPHEME_IS_RTL) { gl.flags |= GRAPHEME_IS_RTL; sd->glyphs.insert(i, gl); // Insert before. } else { - sd->glyphs.insert(i + sd->glyphs[i].count, gl); // Insert after. + sd->glyphs.insert(i + count, gl); // Insert after. } - i += sd->glyphs[i].count; + i += count; + + // Update write pointer and size. + sd_size = sd->glyphs.size(); + sd_glyphs = sd->glyphs.ptrw(); continue; } } diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 6ff9817dcf..d088219d91 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -466,6 +466,7 @@ public: virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) override; virtual Direction shaped_text_get_direction(RID p_shaped) const override; + virtual Direction shaped_text_get_inferred_direction(RID p_shaped) const override; virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) override; diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index f28d174c5c..c7a7c4aa70 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -2128,6 +2128,10 @@ TextServer::Direction TextServerFallback::shaped_text_get_direction(RID p_shaped return TextServer::DIRECTION_LTR; } +TextServer::Direction TextServerFallback::shaped_text_get_inferred_direction(RID p_shaped) const { + return TextServer::DIRECTION_LTR; +} + void TextServerFallback::shaped_text_set_custom_punctuation(RID p_shaped, const String &p_punct) { _THREAD_SAFE_METHOD_ ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); @@ -2631,17 +2635,38 @@ float TextServerFallback::shaped_text_fit_to_width(RID p_shaped, float p_width, } } + float justification_width; + if ((p_jst_flags & JUSTIFICATION_CONSTRAIN_ELLIPSIS) == JUSTIFICATION_CONSTRAIN_ELLIPSIS) { + if (sd->overrun_trim_data.trim_pos >= 0) { + end_pos = sd->overrun_trim_data.trim_pos; + justification_width = sd->width_trimmed; + } else { + return sd->width; + } + } else { + justification_width = sd->width; + } + if ((p_jst_flags & JUSTIFICATION_TRIM_EDGE_SPACES) == JUSTIFICATION_TRIM_EDGE_SPACES) { + // Trim spaces. while ((start_pos < end_pos) && ((sd->glyphs[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { - sd->width -= sd->glyphs[start_pos].advance * sd->glyphs[start_pos].repeat; + justification_width -= sd->glyphs[start_pos].advance * sd->glyphs[start_pos].repeat; sd->glyphs.write[start_pos].advance = 0; start_pos += sd->glyphs[start_pos].count; } while ((start_pos < end_pos) && ((sd->glyphs[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (sd->glyphs[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (sd->glyphs[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { - sd->width -= sd->glyphs[end_pos].advance * sd->glyphs[end_pos].repeat; + justification_width -= sd->glyphs[end_pos].advance * sd->glyphs[end_pos].repeat; sd->glyphs.write[end_pos].advance = 0; end_pos -= sd->glyphs[end_pos].count; } + } else { + // Skip breaks, but do not reset size. + while ((start_pos < end_pos) && ((sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD)) { + start_pos += sd->glyphs[start_pos].count; + } + while ((start_pos < end_pos) && ((sd->glyphs[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD)) { + end_pos -= sd->glyphs[end_pos].count; + } } int space_count = 0; @@ -2655,20 +2680,28 @@ float TextServerFallback::shaped_text_fit_to_width(RID p_shaped, float p_width, } if ((space_count > 0) && ((p_jst_flags & JUSTIFICATION_WORD_BOUND) == JUSTIFICATION_WORD_BOUND)) { - float delta_width_per_space = (p_width - sd->width) / space_count; + float delta_width_per_space = (p_width - justification_width) / space_count; for (int i = start_pos; i <= end_pos; i++) { Glyph &gl = sd->glyphs.write[i]; if (gl.count > 0) { if ((gl.flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE) { float old_adv = gl.advance; gl.advance = MAX(gl.advance + delta_width_per_space, Math::round(0.1 * gl.font_size)); - sd->width += (gl.advance - old_adv); + justification_width += (gl.advance - old_adv); } } } } - return sd->width; + if (Math::floor(p_width) < Math::floor(justification_width)) { + sd->fit_width_minimum_reached = true; + } + + if ((p_jst_flags & JUSTIFICATION_CONSTRAIN_ELLIPSIS) != JUSTIFICATION_CONSTRAIN_ELLIPSIS) { + sd->width = justification_width; + } + + return justification_width; } float TextServerFallback::shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) { @@ -2769,6 +2802,7 @@ bool TextServerFallback::shaped_text_update_breaks(RID p_shaped) { sd_glyphs[i].flags |= GRAPHEME_IS_BREAK_SOFT; } if (is_linebreak(c)) { + sd_glyphs[i].flags |= GRAPHEME_IS_SPACE; sd_glyphs[i].flags |= GRAPHEME_IS_BREAK_HARD; } if (c == 0x0009 || c == 0x000b) { @@ -2827,17 +2861,50 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, fl return; } + Vector<ShapedTextData::Span> &spans = sd->spans; + if (sd->parent != RID()) { + ShapedTextData *parent_sd = shaped_owner.get_or_null(sd->parent); + ERR_FAIL_COND(!parent_sd->valid); + spans = parent_sd->spans; + } + + if (spans.size() == 0) { + return; + } + int sd_size = sd->glyphs.size(); - RID last_gl_font_rid = sd_glyphs[sd_size - 1].font_rid; int last_gl_font_size = sd_glyphs[sd_size - 1].font_size; - int32_t dot_gl_idx = font_get_glyph_index(last_gl_font_rid, '.', 0); - Vector2 dot_adv = font_get_glyph_advance(last_gl_font_rid, last_gl_font_size, dot_gl_idx); - int32_t whitespace_gl_idx = font_get_glyph_index(last_gl_font_rid, ' ', 0); - Vector2 whitespace_adv = font_get_glyph_advance(last_gl_font_rid, last_gl_font_size, whitespace_gl_idx); + + // Find usable fonts, if fonts from the last glyph do not have required chars. + RID dot_gl_font_rid = sd_glyphs[sd_size - 1].font_rid; + if (!font_has_char(dot_gl_font_rid, '.')) { + const Vector<RID> &fonts = spans[spans.size() - 1].fonts; + for (const RID &font : fonts) { + if (font_has_char(font, '.')) { + dot_gl_font_rid = font; + break; + } + } + } + RID whitespace_gl_font_rid = sd_glyphs[sd_size - 1].font_rid; + if (!font_has_char(whitespace_gl_font_rid, '.')) { + const Vector<RID> &fonts = spans[spans.size() - 1].fonts; + for (const RID &font : fonts) { + if (font_has_char(font, ' ')) { + whitespace_gl_font_rid = font; + break; + } + } + } + + int32_t dot_gl_idx = dot_gl_font_rid.is_valid() ? font_get_glyph_index(dot_gl_font_rid, last_gl_font_size, '.') : -10; + Vector2 dot_adv = dot_gl_font_rid.is_valid() ? font_get_glyph_advance(dot_gl_font_rid, last_gl_font_size, dot_gl_idx) : Vector2(); + int32_t whitespace_gl_idx = whitespace_gl_font_rid.is_valid() ? font_get_glyph_index(whitespace_gl_font_rid, last_gl_font_size, ' ') : -10; + Vector2 whitespace_adv = whitespace_gl_font_rid.is_valid() ? font_get_glyph_advance(whitespace_gl_font_rid, last_gl_font_size, whitespace_gl_idx) : Vector2(); int ellipsis_width = 0; - if (add_ellipsis) { - ellipsis_width = 3 * dot_adv.x + font_get_spacing(last_gl_font_rid, last_gl_font_size, TextServer::SPACING_GLYPH) + (cut_per_word ? whitespace_adv.x : 0); + if (add_ellipsis && whitespace_gl_font_rid.is_valid()) { + ellipsis_width = 3 * dot_adv.x + font_get_spacing(whitespace_gl_font_rid, last_gl_font_size, SPACING_GLYPH) + (cut_per_word ? whitespace_adv.x : 0); } int ell_min_characters = 6; @@ -2891,23 +2958,25 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, fl gl.count = 1; gl.advance = whitespace_adv.x; gl.index = whitespace_gl_idx; - gl.font_rid = last_gl_font_rid; + gl.font_rid = whitespace_gl_font_rid; gl.font_size = last_gl_font_size; gl.flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT | GRAPHEME_IS_VIRTUAL; sd->overrun_trim_data.ellipsis_glyph_buf.append(gl); } // Add ellipsis dots. - Glyph gl; - gl.count = 1; - gl.repeat = 3; - gl.advance = dot_adv.x; - gl.index = dot_gl_idx; - gl.font_rid = last_gl_font_rid; - gl.font_size = last_gl_font_size; - gl.flags = GRAPHEME_IS_PUNCTUATION | GRAPHEME_IS_VIRTUAL; + if (dot_gl_idx != 0) { + Glyph gl; + gl.count = 1; + gl.repeat = 3; + gl.advance = dot_adv.x; + gl.index = dot_gl_idx; + gl.font_rid = dot_gl_font_rid; + gl.font_size = last_gl_font_size; + gl.flags = GRAPHEME_IS_PUNCTUATION | GRAPHEME_IS_VIRTUAL; - sd->overrun_trim_data.ellipsis_glyph_buf.append(gl); + sd->overrun_trim_data.ellipsis_glyph_buf.append(gl); + } } sd->text_trimmed = true; @@ -3023,13 +3092,13 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) { if (gl.font_rid.is_valid()) { if (sd->text[j - sd->start] != 0 && !is_linebreak(sd->text[j - sd->start])) { if (sd->orientation == ORIENTATION_HORIZONTAL) { - gl.advance = font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x; + gl.advance = Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x); gl.x_off = 0; gl.y_off = 0; sd->ascent = MAX(sd->ascent, font_get_ascent(gl.font_rid, gl.font_size)); sd->descent = MAX(sd->descent, font_get_descent(gl.font_rid, gl.font_size)); } else { - gl.advance = font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).y; + gl.advance = Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).y); gl.x_off = -Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5); gl.y_off = font_get_ascent(gl.font_rid, gl.font_size); sd->ascent = MAX(sd->ascent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5)); diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index 9d1be50b04..e8619e0825 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -375,6 +375,7 @@ public: virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) override; virtual Direction shaped_text_get_direction(RID p_shaped) const override; + virtual Direction shaped_text_get_inferred_direction(RID p_shaped) const override; virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) override; diff --git a/modules/tga/image_loader_tga.h b/modules/tga/image_loader_tga.h index feaff5925f..282a2a1662 100644 --- a/modules/tga/image_loader_tga.h +++ b/modules/tga/image_loader_tga.h @@ -33,9 +33,6 @@ #include "core/io/image_loader.h" -/** - @author SaracenOne -*/ class ImageLoaderTGA : public ImageFormatLoader { enum tga_type_e { TGA_TYPE_NO_DATA = 0, @@ -81,4 +78,4 @@ public: ImageLoaderTGA(); }; -#endif +#endif // IMAGE_LOADER_TGA_H diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp index bc40f4f9b4..6676d08735 100644 --- a/modules/visual_script/editor/visual_script_editor.cpp +++ b/modules/visual_script/editor/visual_script_editor.cpp @@ -1973,7 +1973,7 @@ void VisualScriptEditor::input(const Ref<InputEvent> &p_event) { // GUI input for VS Editor Plugin Ref<InputEventMouseButton> key = p_event; - if (key.is_valid() && !key->is_pressed()) { + if (key.is_valid() && key->is_pressed()) { mouse_up_position = get_screen_position() + get_local_mouse_position(); } } @@ -1982,10 +1982,28 @@ void VisualScriptEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> key = p_event; if (key.is_valid() && key->is_pressed() && key->get_button_mask() == MouseButton::RIGHT) { - saved_position = graph->get_local_mouse_position(); + bool is_empty_selection = true; - Point2 gpos = get_screen_position() + get_local_mouse_position(); - _generic_search(script->get_instance_base_type(), gpos); + for (int i = 0; i < graph->get_child_count(); i++) { + GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); + if (gn && gn->is_selected()) { + is_empty_selection = false; + break; + } + } + if (is_empty_selection && clipboard->nodes.is_empty()) { + _generic_search(script->get_instance_base_type(), mouse_up_position); + } else { + popup_menu->set_item_disabled(int(EDIT_CUT_NODES), is_empty_selection); + popup_menu->set_item_disabled(int(EDIT_COPY_NODES), is_empty_selection); + popup_menu->set_item_disabled(int(EDIT_PASTE_NODES), clipboard->nodes.is_empty()); + popup_menu->set_item_disabled(int(EDIT_DELETE_NODES), is_empty_selection); + popup_menu->set_item_disabled(int(EDIT_DUPLICATE_NODES), is_empty_selection); + popup_menu->set_item_disabled(int(EDIT_CLEAR_COPY_BUFFER), clipboard->nodes.is_empty()); + + popup_menu->set_position(mouse_up_position); + popup_menu->popup(); + } } } @@ -2637,6 +2655,15 @@ String VisualScriptEditor::get_name() { } Ref<Texture2D> VisualScriptEditor::get_theme_icon() { + String icon_name = "VisualScript"; + if (script->is_built_in()) { + icon_name += "Internal"; + } + + if (Control::has_theme_icon(icon_name, "EditorIcons")) { + return get_parent_control()->get_theme_icon(icon_name, "EditorIcons"); + } + return Control::get_theme_icon(SNAME("VisualScript"), SNAME("EditorIcons")); } @@ -3753,6 +3780,11 @@ void VisualScriptEditor::_toggle_scripts_pressed() { void VisualScriptEditor::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + graph->set_panning_scheme((GraphEdit::PanningScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int()); + } break; + case NOTIFICATION_READY: { variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_members)); variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_graph), varray(-1), CONNECT_DEFERRED); @@ -3868,6 +3900,9 @@ void VisualScriptEditor::_comment_node_resized(const Vector2 &p_new_size, int p_ void VisualScriptEditor::_menu_option(int p_what) { switch (p_what) { + case EDIT_ADD_NODE: { + _generic_search(script->get_instance_base_type(), mouse_up_position); + } break; case EDIT_DELETE_NODES: { _on_nodes_delete(); } break; @@ -3908,6 +3943,9 @@ void VisualScriptEditor::_menu_option(int p_what) { case EDIT_PASTE_NODES: { _on_nodes_paste(); } break; + case EDIT_DUPLICATE_NODES: { + _on_nodes_duplicate(); + } break; case EDIT_CREATE_FUNCTION: { // Create Function. Map<int, Ref<VisualScriptNode>> nodes; @@ -4135,6 +4173,12 @@ void VisualScriptEditor::_menu_option(int p_what) { case REFRESH_GRAPH: { _update_graph(); } break; + case EDIT_CLEAR_COPY_BUFFER: { + clipboard->nodes.clear(); + clipboard->nodes_positions.clear(); + clipboard->data_connections.clear(); + clipboard->sequence_connections.clear(); + } break; } } @@ -4322,9 +4366,6 @@ VisualScriptEditor::VisualScriptEditor() { if (!clipboard) { clipboard = memnew(Clipboard); } - updating_graph = false; - saved_pos_dirty = false; - saved_position = Vector2(0, 0); edit_menu = memnew(MenuButton); edit_menu->set_shortcut_context(this); @@ -4556,6 +4597,18 @@ VisualScriptEditor::VisualScriptEditor() { new_virtual_method_select = memnew(VisualScriptPropertySelector); add_child(new_virtual_method_select); new_virtual_method_select->connect("selected", callable_mp(this, &VisualScriptEditor::_selected_new_virtual_method)); + + popup_menu = memnew(PopupMenu); + add_child(popup_menu); + popup_menu->add_item(TTR("Add Node"), EDIT_ADD_NODE); + popup_menu->add_separator(); + popup_menu->add_item(TTR("Cut"), EDIT_CUT_NODES); + popup_menu->add_item(TTR("Copy"), EDIT_COPY_NODES); + popup_menu->add_item(TTR("Paste"), EDIT_PASTE_NODES); + popup_menu->add_item(TTR("Delete"), EDIT_DELETE_NODES); + popup_menu->add_item(TTR("Duplicate"), EDIT_DUPLICATE_NODES); + popup_menu->add_item(TTR("Clear Copy Buffer"), EDIT_CLEAR_COPY_BUFFER); + popup_menu->connect("id_pressed", callable_mp(this, &VisualScriptEditor::_menu_option)); } VisualScriptEditor::~VisualScriptEditor() { diff --git a/modules/visual_script/editor/visual_script_editor.h b/modules/visual_script/editor/visual_script_editor.h index b232b05391..90e4fb9d56 100644 --- a/modules/visual_script/editor/visual_script_editor.h +++ b/modules/visual_script/editor/visual_script_editor.h @@ -54,13 +54,18 @@ class VisualScriptEditor : public ScriptEditorBase { }; enum { - EDIT_DELETE_NODES, - EDIT_TOGGLE_BREAKPOINT, - EDIT_FIND_NODE_TYPE, - EDIT_COPY_NODES, + EDIT_ADD_NODE, + EDIT_SEPARATOR, // popup menu separator - ignored EDIT_CUT_NODES, + EDIT_COPY_NODES, EDIT_PASTE_NODES, + EDIT_DELETE_NODES, + EDIT_DUPLICATE_NODES, + EDIT_CLEAR_COPY_BUFFER, + EDIT_CREATE_FUNCTION, + EDIT_TOGGLE_BREAKPOINT, + EDIT_FIND_NODE_TYPE, REFRESH_GRAPH, }; @@ -123,7 +128,7 @@ class VisualScriptEditor : public ScriptEditorBase { Label *select_func_text; - bool updating_graph; + bool updating_graph = false; void _show_hint(const String &p_hint); void _hide_timer(); @@ -162,7 +167,8 @@ class VisualScriptEditor : public ScriptEditorBase { static Clipboard *clipboard; - PopupMenu *member_popup; + PopupMenu *popup_menu = nullptr; + PopupMenu *member_popup = nullptr; MemberType member_type; String member_name; @@ -172,8 +178,7 @@ class VisualScriptEditor : public ScriptEditorBase { Vector2 port_action_pos; int port_action_new_node; - bool saved_pos_dirty; - Vector2 saved_position; + bool saved_pos_dirty = false; Vector2 mouse_up_position; diff --git a/modules/visual_script/icons/VisualScriptInternal.svg b/modules/visual_script/icons/VisualScriptInternal.svg new file mode 100644 index 0000000000..ea83047a29 --- /dev/null +++ b/modules/visual_script/icons/VisualScriptInternal.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="3" cy="3.000024" fill="#6e6e6e" r="0"/><path d="m11 10a2 2 0 0 0 -1.7324 1 2 2 0 0 0 0 2 2 2 0 0 0 1.7324 1h-2v2h2a2 2 0 0 0 1.7324-1 2 2 0 0 0 0-2 2 2 0 0 0 -1.7324-1h2v-2z" fill="#e0e0e0"/><path d="m3 10v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4z" fill="#e0e0e0"/><path d="m7 1-.56445 2.2578a5 5 0 0 0 -.68945.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941a5 5 0 0 0 -.28516.68555l-2.2539.5625v2h5.2715a2 2 0 0 1 -.27148-1 2 2 0 0 1 2-2 2 2 0 0 1 2 2 2 2 0 0 1 -.26953 1h5.2695v-2l-2.2578-.56445a5 5 0 0 0 -.2793-.6875l1.1934-1.9902-1.4141-1.4141-1.9941 1.1953a5 5 0 0 0 -.68555-.28516l-.5625-2.2539h-2z" fill="none" stroke="#e0e0e0"/></svg> diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp index b39f984a80..2abbd19e12 100644 --- a/modules/visual_script/visual_script_expression.cpp +++ b/modules/visual_script/visual_script_expression.cpp @@ -176,7 +176,7 @@ PropertyInfo VisualScriptExpression::get_output_value_port_info(int p_idx) const } String VisualScriptExpression::get_caption() const { - return "Expression"; + return TTR("Expression"); } String VisualScriptExpression::get_text() const { diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp index f8b03f2eea..fd1861abc4 100644 --- a/modules/visual_script/visual_script_flow_control.cpp +++ b/modules/visual_script/visual_script_flow_control.cpp @@ -70,7 +70,7 @@ PropertyInfo VisualScriptReturn::get_output_value_port_info(int p_idx) const { } String VisualScriptReturn::get_caption() const { - return "Return"; + return TTR("Return"); } String VisualScriptReturn::get_text() const { @@ -201,11 +201,11 @@ PropertyInfo VisualScriptCondition::get_output_value_port_info(int p_idx) const } String VisualScriptCondition::get_caption() const { - return "Condition"; + return TTR("Condition"); } String VisualScriptCondition::get_text() const { - return "if (cond) is: "; + return TTR("if (cond) is:"); } void VisualScriptCondition::_bind_methods() { @@ -281,11 +281,11 @@ PropertyInfo VisualScriptWhile::get_output_value_port_info(int p_idx) const { } String VisualScriptWhile::get_caption() const { - return "While"; + return TTR("While"); } String VisualScriptWhile::get_text() const { - return "while (cond): "; + return TTR("while (cond):"); } void VisualScriptWhile::_bind_methods() { @@ -364,11 +364,11 @@ PropertyInfo VisualScriptIterator::get_output_value_port_info(int p_idx) const { } String VisualScriptIterator::get_caption() const { - return "Iterator"; + return TTR("Iterator"); } String VisualScriptIterator::get_text() const { - return "for (elem) in (input): "; + return TTR("for (elem) in (input):"); } void VisualScriptIterator::_bind_methods() { @@ -478,11 +478,11 @@ PropertyInfo VisualScriptSequence::get_output_value_port_info(int p_idx) const { } String VisualScriptSequence::get_caption() const { - return "Sequence"; + return TTR("Sequence"); } String VisualScriptSequence::get_text() const { - return "in order: "; + return TTR("in order:"); } void VisualScriptSequence::set_steps(int p_steps) { @@ -587,11 +587,11 @@ PropertyInfo VisualScriptSwitch::get_output_value_port_info(int p_idx) const { } String VisualScriptSwitch::get_caption() const { - return "Switch"; + return TTR("Switch"); } String VisualScriptSwitch::get_text() const { - return "'input' is:"; + return TTR("'input' is:"); } class VisualScriptNodeInstanceSwitch : public VisualScriptNodeInstance { @@ -720,14 +720,14 @@ PropertyInfo VisualScriptTypeCast::get_output_value_port_info(int p_idx) const { } String VisualScriptTypeCast::get_caption() const { - return "Type Cast"; + return TTR("Type Cast"); } String VisualScriptTypeCast::get_text() const { if (!script.is_empty()) { - return "Is " + script.get_file() + "?"; + return vformat(TTR("Is %s?"), script.get_file()); } else { - return "Is " + base_type + "?"; + return vformat(TTR("Is %s?"), base_type); } } diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp index 056e1eb6a3..cc18d48dd8 100644 --- a/modules/visual_script/visual_script_func_nodes.cpp +++ b/modules/visual_script/visual_script_func_nodes.cpp @@ -261,13 +261,13 @@ String VisualScriptFunctionCall::get_text() const { String text; if (call_mode == CALL_MODE_BASIC_TYPE) { - text = String("On ") + Variant::get_type_name(basic_type); + text = vformat(TTR("On %s"), Variant::get_type_name(basic_type)); } else if (call_mode == CALL_MODE_INSTANCE) { - text = String("On ") + base_type; + text = vformat(TTR("On %s"), base_type); } else if (call_mode == CALL_MODE_NODE_PATH) { text = "[" + String(base_path.simplified()) + "]"; } else if (call_mode == CALL_MODE_SELF) { - text = "On Self"; + text = TTR("On Self"); } else if (call_mode == CALL_MODE_SINGLETON) { text = String(singleton) + ":" + String(function) + "()"; } @@ -1033,15 +1033,25 @@ PropertyInfo VisualScriptPropertySet::get_output_value_port_info(int p_idx) cons String VisualScriptPropertySet::get_caption() const { static const char *opname[ASSIGN_OP_MAX] = { - "Set", "Add", "Subtract", "Multiply", "Divide", "Mod", "ShiftLeft", "ShiftRight", "BitAnd", "BitOr", "BitXor" + TTRC("Set %s"), + TTRC("Add %s"), + TTRC("Subtract %s"), + TTRC("Multiply %s"), + TTRC("Divide %s"), + TTRC("Mod %s"), + TTRC("ShiftLeft %s"), + TTRC("ShiftRight %s"), + TTRC("BitAnd %s"), + TTRC("BitOr %s"), + TTRC("BitXor %s") }; - String prop = String(opname[assign_op]) + " " + property; + String prop = property; if (index != StringName()) { prop += "." + String(index); } - return prop; + return vformat(TTRGET(opname[assign_op]), prop); } String VisualScriptPropertySet::get_text() const { @@ -1049,13 +1059,13 @@ String VisualScriptPropertySet::get_text() const { return ""; } if (call_mode == CALL_MODE_BASIC_TYPE) { - return String("On ") + Variant::get_type_name(basic_type); + return vformat(TTR("On %s"), Variant::get_type_name(basic_type)); } else if (call_mode == CALL_MODE_INSTANCE) { - return String("On ") + base_type; + return vformat(TTR("On %s"), base_type); } else if (call_mode == CALL_MODE_NODE_PATH) { return " [" + String(base_path.simplified()) + "]"; } else { - return "On Self"; + return TTR("On Self"); } } @@ -1761,23 +1771,23 @@ PropertyInfo VisualScriptPropertyGet::get_output_value_port_info(int p_idx) cons } String VisualScriptPropertyGet::get_caption() const { - String prop = String("Get ") + property; + String prop = property; if (index != StringName()) { prop += "." + String(index); } - return prop; + return vformat(TTR("Get %s"), prop); } String VisualScriptPropertyGet::get_text() const { if (call_mode == CALL_MODE_BASIC_TYPE) { - return String("On ") + Variant::get_type_name(basic_type); + return vformat(TTR("On %s"), Variant::get_type_name(basic_type)); } else if (call_mode == CALL_MODE_INSTANCE) { - return String("On ") + base_type; + return vformat(TTR("On %s"), base_type); } else if (call_mode == CALL_MODE_NODE_PATH) { return " [" + String(base_path.simplified()) + "]"; } else { - return "On Self"; + return TTR("On Self"); } } @@ -2293,7 +2303,7 @@ PropertyInfo VisualScriptEmitSignal::get_output_value_port_info(int p_idx) const } String VisualScriptEmitSignal::get_caption() const { - return "Emit " + String(name); + return vformat(TTR("Emit %s"), name); } void VisualScriptEmitSignal::set_signal(const StringName &p_type) { diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index fccdab1a64..f3594e5164 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -204,7 +204,7 @@ PropertyInfo VisualScriptFunction::get_output_value_port_info(int p_idx) const { } String VisualScriptFunction::get_caption() const { - return "Function"; + return TTR("Function"); } String VisualScriptFunction::get_text() const { @@ -767,7 +767,7 @@ PropertyInfo VisualScriptComposeArray::get_output_value_port_info(int p_idx) con } String VisualScriptComposeArray::get_caption() const { - return "Compose Array"; + return TTR("Compose Array"); } String VisualScriptComposeArray::get_text() const { @@ -1186,11 +1186,11 @@ PropertyInfo VisualScriptSelect::get_output_value_port_info(int p_idx) const { } String VisualScriptSelect::get_caption() const { - return "Select"; + return TTR("Select"); } String VisualScriptSelect::get_text() const { - return "a if cond, else b"; + return TTR("a if cond, else b"); } void VisualScriptSelect::set_typed(Variant::Type p_op) { @@ -1284,7 +1284,7 @@ PropertyInfo VisualScriptVariableGet::get_output_value_port_info(int p_idx) cons } String VisualScriptVariableGet::get_caption() const { - return "Get " + variable; + return vformat(TTR("Get %s"), variable); } void VisualScriptVariableGet::set_variable(StringName p_variable) { @@ -1394,7 +1394,7 @@ PropertyInfo VisualScriptVariableSet::get_output_value_port_info(int p_idx) cons } String VisualScriptVariableSet::get_caption() const { - return "Set " + variable; + return vformat(TTR("Set %s"), variable); } void VisualScriptVariableSet::set_variable(StringName p_variable) { @@ -1501,7 +1501,7 @@ PropertyInfo VisualScriptConstant::get_output_value_port_info(int p_idx) const { } String VisualScriptConstant::get_caption() const { - return "Constant"; + return TTR("Constant"); } void VisualScriptConstant::set_constant_type(Variant::Type p_type) { @@ -1628,7 +1628,7 @@ PropertyInfo VisualScriptPreload::get_output_value_port_info(int p_idx) const { } String VisualScriptPreload::get_caption() const { - return "Preload"; + return TTR("Preload"); } void VisualScriptPreload::set_preload(const Ref<Resource> &p_preload) { @@ -1708,7 +1708,7 @@ PropertyInfo VisualScriptIndexGet::get_output_value_port_info(int p_idx) const { } String VisualScriptIndexGet::get_caption() const { - return "Get Index"; + return TTR("Get Index"); } class VisualScriptNodeInstanceIndexGet : public VisualScriptNodeInstance { @@ -1775,7 +1775,7 @@ PropertyInfo VisualScriptIndexSet::get_output_value_port_info(int p_idx) const { } String VisualScriptIndexSet::get_caption() const { - return "Set Index"; + return TTR("Set Index"); } class VisualScriptNodeInstanceIndexSet : public VisualScriptNodeInstance { @@ -1839,7 +1839,7 @@ PropertyInfo VisualScriptGlobalConstant::get_output_value_port_info(int p_idx) c } String VisualScriptGlobalConstant::get_caption() const { - return "Global Constant"; + return TTR("Global Constant"); } void VisualScriptGlobalConstant::set_global_constant(int p_which) { @@ -1925,7 +1925,7 @@ PropertyInfo VisualScriptClassConstant::get_output_value_port_info(int p_idx) co } String VisualScriptClassConstant::get_caption() const { - return "Class Constant"; + return TTR("Class Constant"); } void VisualScriptClassConstant::set_class_constant(const StringName &p_which) { @@ -2050,7 +2050,7 @@ PropertyInfo VisualScriptBasicTypeConstant::get_output_value_port_info(int p_idx } String VisualScriptBasicTypeConstant::get_caption() const { - return "Basic Constant"; + return TTR("Basic Constant"); } String VisualScriptBasicTypeConstant::get_text() const { @@ -2215,7 +2215,7 @@ PropertyInfo VisualScriptMathConstant::get_output_value_port_info(int p_idx) con } String VisualScriptMathConstant::get_caption() const { - return "Math Constant"; + return TTR("Math Constant"); } void VisualScriptMathConstant::set_math_constant(MathConstant p_which) { @@ -2307,7 +2307,7 @@ PropertyInfo VisualScriptEngineSingleton::get_output_value_port_info(int p_idx) } String VisualScriptEngineSingleton::get_caption() const { - return "Get Engine Singleton"; + return TTR("Get Engine Singleton"); } void VisualScriptEngineSingleton::set_singleton(const String &p_string) { @@ -2417,7 +2417,7 @@ PropertyInfo VisualScriptSceneNode::get_output_value_port_info(int p_idx) const } String VisualScriptSceneNode::get_caption() const { - return "Get Scene Node"; + return TTR("Get Scene Node"); } void VisualScriptSceneNode::set_node_path(const NodePath &p_path) { @@ -2608,7 +2608,7 @@ PropertyInfo VisualScriptSceneTree::get_output_value_port_info(int p_idx) const } String VisualScriptSceneTree::get_caption() const { - return "Get Scene Tree"; + return TTR("Get Scene Tree"); } class VisualScriptNodeInstanceSceneTree : public VisualScriptNodeInstance { @@ -2695,7 +2695,7 @@ PropertyInfo VisualScriptResourcePath::get_output_value_port_info(int p_idx) con } String VisualScriptResourcePath::get_caption() const { - return "Resource Path"; + return TTR("Resource Path"); } void VisualScriptResourcePath::set_resource_path(const String &p_path) { @@ -2777,7 +2777,7 @@ PropertyInfo VisualScriptSelf::get_output_value_port_info(int p_idx) const { } String VisualScriptSelf::get_caption() const { - return "Get Self"; + return TTR("Get Self"); } class VisualScriptNodeInstanceSelf : public VisualScriptNodeInstance { @@ -2947,7 +2947,7 @@ String VisualScriptCustomNode::get_caption() const { if (GDVIRTUAL_CALL(_get_caption, ret)) { return ret; } - return "CustomNode"; + return TTR("CustomNode"); } String VisualScriptCustomNode::get_text() const { @@ -3141,7 +3141,7 @@ PropertyInfo VisualScriptSubCall::get_output_value_port_info(int p_idx) const { } String VisualScriptSubCall::get_caption() const { - return "SubCall"; + return TTR("SubCall"); } String VisualScriptSubCall::get_text() const { @@ -3352,7 +3352,7 @@ PropertyInfo VisualScriptConstructor::get_output_value_port_info(int p_idx) cons } String VisualScriptConstructor::get_caption() const { - return "Construct " + Variant::get_type_name(type); + return vformat(TTR("Construct %s"), Variant::get_type_name(type)); } String VisualScriptConstructor::get_category() const { @@ -3469,7 +3469,7 @@ PropertyInfo VisualScriptLocalVar::get_output_value_port_info(int p_idx) const { } String VisualScriptLocalVar::get_caption() const { - return "Get Local Var"; + return TTR("Get Local Var"); } String VisualScriptLocalVar::get_category() const { @@ -3572,7 +3572,7 @@ PropertyInfo VisualScriptLocalVarSet::get_output_value_port_info(int p_idx) cons } String VisualScriptLocalVarSet::get_caption() const { - return "Set Local Var"; + return TTR("Set Local Var"); } String VisualScriptLocalVarSet::get_text() const { @@ -3696,7 +3696,7 @@ PropertyInfo VisualScriptInputAction::get_output_value_port_info(int p_idx) cons } String VisualScriptInputAction::get_caption() const { - return "Action " + name; + return vformat(TTR("Action %s"), name); } String VisualScriptInputAction::get_category() const { @@ -3850,7 +3850,7 @@ PropertyInfo VisualScriptDeconstruct::get_output_value_port_info(int p_idx) cons } String VisualScriptDeconstruct::get_caption() const { - return "Deconstruct " + Variant::get_type_name(type); + return vformat(TTR("Deconstruct %s"), Variant::get_type_name(type)); } String VisualScriptDeconstruct::get_category() const { diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp index d4f3fdd082..fbd5ad35ab 100644 --- a/modules/visual_script/visual_script_yield_nodes.cpp +++ b/modules/visual_script/visual_script_yield_nodes.cpp @@ -68,7 +68,7 @@ PropertyInfo VisualScriptYield::get_output_value_port_info(int p_idx) const { } String VisualScriptYield::get_caption() const { - return yield_mode == YIELD_RETURN ? "Yield" : "Wait"; + return yield_mode == YIELD_RETURN ? TTR("Yield") : TTR("Wait"); } String VisualScriptYield::get_text() const { @@ -77,13 +77,13 @@ String VisualScriptYield::get_text() const { return ""; break; case YIELD_FRAME: - return "Next Frame"; + return TTR("Next Frame"); break; case YIELD_PHYSICS_FRAME: - return "Next Physics Frame"; + return TTR("Next Physics Frame"); break; case YIELD_WAIT: - return rtos(wait_time) + " sec(s)"; + return vformat(TTR("%s sec(s)"), rtos(wait_time)); break; } @@ -336,12 +336,12 @@ PropertyInfo VisualScriptYieldSignal::get_output_value_port_info(int p_idx) cons String VisualScriptYieldSignal::get_caption() const { static const char *cname[3] = { - "WaitSignal", - "WaitNodeSignal", - "WaitInstanceSigna;", + TTRC("WaitSignal"), + TTRC("WaitNodeSignal"), + TTRC("WaitInstanceSignal"), }; - return cname[call_mode]; + return TTRGET(cname[call_mode]); } String VisualScriptYieldSignal::get_text() const { diff --git a/modules/webxr/webxr_interface.h b/modules/webxr/webxr_interface.h index 291d53044f..801643bfa6 100644 --- a/modules/webxr/webxr_interface.h +++ b/modules/webxr/webxr_interface.h @@ -35,8 +35,6 @@ #include "servers/xr/xr_positional_tracker.h" /** - @author David Snopek <david.snopek@snopekgames.com> - The WebXR interface is a VR/AR interface that can be used on the web. */ diff --git a/modules/webxr/webxr_interface_js.h b/modules/webxr/webxr_interface_js.h index 3eec451d50..8eddfbe484 100644 --- a/modules/webxr/webxr_interface_js.h +++ b/modules/webxr/webxr_interface_js.h @@ -36,8 +36,6 @@ #include "webxr_interface.h" /** - @author David Snopek <david.snopek@snopekgames.com> - The WebXR interface is a VR/AR interface that can be used on the web. */ diff --git a/platform/android/android_input_handler.cpp b/platform/android/android_input_handler.cpp index 7efdc620df..246ec6b198 100644 --- a/platform/android/android_input_handler.cpp +++ b/platform/android/android_input_handler.cpp @@ -39,10 +39,7 @@ void AndroidInputHandler::process_joy_event(AndroidInputHandler::JoypadEvent p_e Input::get_singleton()->joy_button(p_event.device, (JoyButton)p_event.index, p_event.pressed); break; case JOY_EVENT_AXIS: - Input::JoyAxisValue value; - value.min = -1; - value.value = p_event.value; - Input::get_singleton()->joy_axis(p_event.device, (JoyAxis)p_event.index, value); + Input::get_singleton()->joy_axis(p_event.device, (JoyAxis)p_event.index, p_event.value); break; case JOY_EVENT_HAT: Input::get_singleton()->joy_hat(p_event.device, p_event.hat); diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index cbecde787f..aa44183329 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -2666,6 +2666,13 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP debug_password = EditorSettings::get_singleton()->get("export/android/debug_keystore_pass"); debug_user = EditorSettings::get_singleton()->get("export/android/debug_keystore_user"); } + if (debug_keystore.is_relative_path()) { + debug_keystore = OS::get_singleton()->get_resource_dir().plus_file(debug_keystore).simplify_path(); + } + if (!FileAccess::exists(debug_keystore)) { + EditorNode::add_io_error(TTR("Could not find keystore, unable to export.")); + return ERR_FILE_CANT_OPEN; + } cmdline.push_back("-Pdebug_keystore_file=" + debug_keystore); // argument to specify the debug keystore file. cmdline.push_back("-Pdebug_keystore_alias=" + debug_user); // argument to specify the debug keystore alias. @@ -2675,6 +2682,9 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP String release_keystore = p_preset->get("keystore/release"); String release_username = p_preset->get("keystore/release_user"); String release_password = p_preset->get("keystore/release_password"); + if (release_keystore.is_relative_path()) { + release_keystore = OS::get_singleton()->get_resource_dir().plus_file(release_keystore).simplify_path(); + } if (!FileAccess::exists(release_keystore)) { EditorNode::add_io_error(TTR("Could not find keystore, unable to export.")); return ERR_FILE_CANT_OPEN; diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java index 9ea787ac86..e5b4f41153 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java @@ -45,8 +45,8 @@ import java.util.List; /** * This class includes utility functions for Android permissions related operations. - * @author Cagdas Caglak <cagdascaglak@gmail.com> */ + public final class PermissionsUtil { private static final String TAG = PermissionsUtil.class.getSimpleName(); diff --git a/platform/iphone/joypad_iphone.mm b/platform/iphone/joypad_iphone.mm index 2630b42da0..f45f4da5a8 100644 --- a/platform/iphone/joypad_iphone.mm +++ b/platform/iphone/joypad_iphone.mm @@ -287,24 +287,22 @@ void JoypadIPhone::start_processing() { gamepad.dpad.right.isPressed); }; - Input::JoyAxisValue jx; - jx.min = -1; if (element == gamepad.leftThumbstick) { - jx.value = gamepad.leftThumbstick.xAxis.value; - Input::get_singleton()->joy_axis(joy_id, JoyAxis::LEFT_X, jx); - jx.value = -gamepad.leftThumbstick.yAxis.value; - Input::get_singleton()->joy_axis(joy_id, JoyAxis::LEFT_Y, jx); + float value = gamepad.leftThumbstick.xAxis.value; + Input::get_singleton()->joy_axis(joy_id, JoyAxis::LEFT_X, value); + value = -gamepad.leftThumbstick.yAxis.value; + Input::get_singleton()->joy_axis(joy_id, JoyAxis::LEFT_Y, value); } else if (element == gamepad.rightThumbstick) { - jx.value = gamepad.rightThumbstick.xAxis.value; - Input::get_singleton()->joy_axis(joy_id, JoyAxis::RIGHT_X, jx); - jx.value = -gamepad.rightThumbstick.yAxis.value; - Input::get_singleton()->joy_axis(joy_id, JoyAxis::RIGHT_Y, jx); + float value = gamepad.rightThumbstick.xAxis.value; + Input::get_singleton()->joy_axis(joy_id, JoyAxis::RIGHT_X, value); + value = -gamepad.rightThumbstick.yAxis.value; + Input::get_singleton()->joy_axis(joy_id, JoyAxis::RIGHT_Y, value); } else if (element == gamepad.leftTrigger) { - jx.value = gamepad.leftTrigger.value; - Input::get_singleton()->joy_axis(joy_id, JoyAxis::TRIGGER_LEFT, jx); + float value = gamepad.leftTrigger.value; + Input::get_singleton()->joy_axis(joy_id, JoyAxis::TRIGGER_LEFT, value); } else if (element == gamepad.rightTrigger) { - jx.value = gamepad.rightTrigger.value; - Input::get_singleton()->joy_axis(joy_id, JoyAxis::TRIGGER_RIGHT, jx); + float value = gamepad.rightTrigger.value; + Input::get_singleton()->joy_axis(joy_id, JoyAxis::TRIGGER_RIGHT, value); }; }; } else if (controller.microGamepad != nil) { diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp index f98e0c4c5f..b9f691ea43 100644 --- a/platform/javascript/display_server_javascript.cpp +++ b/platform/javascript/display_server_javascript.cpp @@ -558,24 +558,16 @@ void DisplayServerJavaScript::process_joypads() { continue; } for (int b = 0; b < s_btns_num; b++) { - float value = s_btns[b]; // Buttons 6 and 7 in the standard mapping need to be // axis to be handled as JoyAxis::TRIGGER by Godot. if (s_standard && (b == 6 || b == 7)) { - Input::JoyAxisValue joy_axis; - joy_axis.min = 0; - joy_axis.value = value; - JoyAxis a = b == 6 ? JoyAxis::TRIGGER_LEFT : JoyAxis::TRIGGER_RIGHT; - input->joy_axis(idx, a, joy_axis); + input->joy_axis(idx, (JoyAxis)b, s_btns[b]); } else { - input->joy_button(idx, (JoyButton)b, value); + input->joy_button(idx, (JoyButton)b, s_btns[b]); } } for (int a = 0; a < s_axes_num; a++) { - Input::JoyAxisValue joy_axis; - joy_axis.min = -1; - joy_axis.value = s_axes[a]; - input->joy_axis(idx, (JoyAxis)a, joy_axis); + input->joy_axis(idx, (JoyAxis)a, s_axes[a]); } } } diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 747b5beeda..c4f7a3a646 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -3416,7 +3416,7 @@ void DisplayServerX11::process_events() { if (mouse_mode_grab) { for (const KeyValue<WindowID, WindowData> &E : windows) { - //dear X11, I try, I really try, but you never work, you do whathever you want. + //dear X11, I try, I really try, but you never work, you do whatever you want. if (mouse_mode == MOUSE_MODE_CAPTURED) { // Show the cursor if we're in captured mode so it doesn't look weird. XUndefineCursor(x11_display, E.value.x11_window); diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index b5fd3664d3..1dcedabb1a 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -31,8 +31,6 @@ #ifndef DISPLAY_SERVER_X11_H #define DISPLAY_SERVER_X11_H -#include "drivers/gles3/rasterizer_platforms.h" - #ifdef X11_ENABLED #include "servers/display_server.h" diff --git a/platform/linuxbsd/gl_manager_x11.h b/platform/linuxbsd/gl_manager_x11.h index c83b96395b..0bb0a446ab 100644 --- a/platform/linuxbsd/gl_manager_x11.h +++ b/platform/linuxbsd/gl_manager_x11.h @@ -33,8 +33,6 @@ #ifdef X11_ENABLED -#include "drivers/gles3/rasterizer_platforms.h" - #ifdef GLES3_ENABLED #include "core/os/os.h" diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp index 37606de3bc..5eda42fea6 100644 --- a/platform/linuxbsd/joypad_linux.cpp +++ b/platform/linuxbsd/joypad_linux.cpp @@ -61,13 +61,9 @@ JoypadLinux::Joypad::~Joypad() { void JoypadLinux::Joypad::reset() { dpad = HatMask::CENTER; fd = -1; - - Input::JoyAxisValue jx; - jx.min = -1; - jx.value = 0.0f; for (int i = 0; i < MAX_ABS; i++) { abs_map[i] = -1; - curr_axis[i] = jx; + curr_axis[i] = 0; } } @@ -429,23 +425,11 @@ void JoypadLinux::joypad_vibration_stop(int p_id, uint64_t p_timestamp) { joy.ff_effect_timestamp = p_timestamp; } -Input::JoyAxisValue JoypadLinux::axis_correct(const input_absinfo *p_abs, int p_value) const { +float JoypadLinux::axis_correct(const input_absinfo *p_abs, int p_value) const { int min = p_abs->minimum; int max = p_abs->maximum; - Input::JoyAxisValue jx; - - if (min < 0) { - jx.min = -1; - if (p_value < 0) { - jx.value = (float)-p_value / min; - } else { - jx.value = (float)p_value / max; - } - } else if (min == 0) { - jx.min = 0; - jx.value = 0.0f + (float)p_value / max; - } - return jx; + // Convert to a value between -1.0f and 1.0f. + return 2.0f * (p_value - min) / (max - min) - 1.0f; } void JoypadLinux::process_joypads() { @@ -514,7 +498,7 @@ void JoypadLinux::process_joypads() { return; } if (joy->abs_map[ev.code] != -1 && joy->abs_info[ev.code]) { - Input::JoyAxisValue value = axis_correct(joy->abs_info[ev.code], ev.value); + float value = axis_correct(joy->abs_info[ev.code], ev.value); joy->curr_axis[joy->abs_map[ev.code]] = value; } break; diff --git a/platform/linuxbsd/joypad_linux.h b/platform/linuxbsd/joypad_linux.h index 42797afdfa..9177465547 100644 --- a/platform/linuxbsd/joypad_linux.h +++ b/platform/linuxbsd/joypad_linux.h @@ -28,7 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -//author: Andreas Haas <hondres, liugam3@gmail.com> #ifndef JOYPAD_LINUX_H #define JOYPAD_LINUX_H @@ -53,7 +52,7 @@ private: }; struct Joypad { - Input::JoyAxisValue curr_axis[MAX_ABS]; + float curr_axis[MAX_ABS]; int key_map[MAX_KEY]; int abs_map[MAX_ABS]; HatMask dpad = HatMask::CENTER; @@ -97,8 +96,9 @@ private: void joypad_vibration_start(int p_id, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp); void joypad_vibration_stop(int p_id, uint64_t p_timestamp); - Input::JoyAxisValue axis_correct(const input_absinfo *p_abs, int p_value) const; + float axis_correct(const input_absinfo *p_abs, int p_value) const; }; -#endif +#endif // JOYDEV_ENABLED + #endif // JOYPAD_LINUX_H diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index 2465334f84..27d302a984 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -3575,6 +3575,7 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, V [wd.window_object setDelegate:wd.window_delegate]; [wd.window_object setAcceptsMouseMovedEvents:YES]; [wd.window_object setRestorable:NO]; + [wd.window_object setColorSpace:[NSColorSpace sRGBColorSpace]]; if ([wd.window_object respondsToSelector:@selector(setTabbingMode:)]) { [wd.window_object setTabbingMode:NSWindowTabbingModeDisallowed]; diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp index 2152b34aff..c2356f12cd 100644 --- a/platform/osx/joypad_osx.cpp +++ b/platform/osx/joypad_osx.cpp @@ -449,20 +449,9 @@ void JoypadOSX::poll_joypads() const { } } -static const Input::JoyAxisValue axis_correct(int p_value, int p_min, int p_max) { - Input::JoyAxisValue jx; - if (p_min < 0) { - jx.min = -1; - if (p_value < 0) { - jx.value = (float)-p_value / p_min; - } else - jx.value = (float)p_value / p_max; - } - if (p_min == 0) { - jx.min = 0; - jx.value = 0.0f + (float)p_value / p_max; - } - return jx; +static float axis_correct(int p_value, int p_min, int p_max) { + // Convert to a value between -1.0f and 1.0f. + return 2.0f * (p_value - p_min) / (p_max - p_min) - 1.0f; } void JoypadOSX::process_joypads() { diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 7d07b0076b..821036de9c 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -82,9 +82,9 @@ @implementation GodotApplicationDelegate - (void)forceUnbundledWindowActivationHackStep1 { - // Step1: Switch focus to macOS Dock. + // Step 1: Switch focus to macOS SystemUIServer process. // Required to perform step 2, TransformProcessType will fail if app is already the in focus. - for (NSRunningApplication *app in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"]) { + for (NSRunningApplication *app in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.systemuiserver"]) { [app activateWithOptions:NSApplicationActivateIgnoringOtherApps]; break; } @@ -107,8 +107,8 @@ - (void)applicationDidFinishLaunching:(NSNotification *)notice { NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; - if (nsappname == nil) { - // If executable is not a bundled, macOS WindowServer won't register and activate app window correctly (menu and title bar are grayed out and input ignored). + if (nsappname == nil || isatty(STDOUT_FILENO) || isatty(STDIN_FILENO) || isatty(STDERR_FILENO)) { + // If the executable is started from terminal or is not bundled, macOS WindowServer won't register and activate app window correctly (menu and title bar are grayed out and input ignored). [self performSelector:@selector(forceUnbundledWindowActivationHackStep1) withObject:nil afterDelay:0.02]; } } diff --git a/platform/uwp/joypad_uwp.cpp b/platform/uwp/joypad_uwp.cpp index ef44f0b14d..e48016919b 100644 --- a/platform/uwp/joypad_uwp.cpp +++ b/platform/uwp/joypad_uwp.cpp @@ -134,13 +134,12 @@ void JoypadUWP::OnGamepadRemoved(Platform::Object ^ sender, Windows::Gaming::Inp input->joy_connection_changed(idx, false, "Xbox Controller"); } -InputDefault::JoyAxisValue JoypadUWP::axis_correct(double p_val, bool p_negate, bool p_trigger) const { - InputDefault::JoyAxisValue jx; - - jx.min = p_trigger ? 0 : -1; - jx.value = (float)(p_negate ? -p_val : p_val); - - return jx; +float JoypadUWP::axis_correct(double p_val, bool p_negate, bool p_trigger) const { + if (p_trigger) { + // Convert to a value between -1.0f and 1.0f. + return 2.0f * p_val - 1.0f; + } + return (float)(p_negate ? -p_val : p_val); } void JoypadUWP::joypad_vibration_start(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp) { diff --git a/platform/uwp/joypad_uwp.h b/platform/uwp/joypad_uwp.h index 1d68996358..29f5109056 100644 --- a/platform/uwp/joypad_uwp.h +++ b/platform/uwp/joypad_uwp.h @@ -73,7 +73,7 @@ private: void OnGamepadAdded(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value); void OnGamepadRemoved(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value); - InputDefault::JoyAxisValue axis_correct(double p_val, bool p_negate = false, bool p_trigger = false) const; + float axis_correct(double p_val, bool p_negate = false, bool p_trigger = false) const; void joypad_vibration_start(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp); void joypad_vibration_stop(int p_device, uint64_t p_timestamp); }; diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 091bed36ea..9160371b5f 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -2819,6 +2819,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA case WM_DEVICECHANGE: { joypad->probe_joypads(); } break; + case WM_DESTROY: { + Input::get_singleton()->flush_buffered_events(); + } break; case WM_SETCURSOR: { if (LOWORD(lParam) == HTCLIENT) { if (windows[window_id].window_has_focus && (mouse_mode == MOUSE_MODE_HIDDEN || mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN)) { diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp index 8b6081d606..b0dd86a4b7 100644 --- a/platform/windows/joypad_windows.cpp +++ b/platform/windows/joypad_windows.cpp @@ -448,33 +448,27 @@ void JoypadWindows::post_hat(int p_device, DWORD p_dpad) { input->joy_hat(p_device, dpad_val); }; -Input::JoyAxisValue JoypadWindows::axis_correct(int p_val, bool p_xinput, bool p_trigger, bool p_negate) const { - Input::JoyAxisValue jx; +float JoypadWindows::axis_correct(int p_val, bool p_xinput, bool p_trigger, bool p_negate) const { if (Math::abs(p_val) < MIN_JOY_AXIS) { - jx.min = p_trigger ? 0 : -1; - jx.value = 0.0f; - return jx; + return p_trigger ? -1.0f : 0.0f; } - if (p_xinput) { - if (p_trigger) { - jx.min = 0; - jx.value = (float)p_val / MAX_TRIGGER; - return jx; - } - jx.min = -1; - if (p_val < 0) { - jx.value = (float)p_val / MAX_JOY_AXIS; - } else { - jx.value = (float)p_val / (MAX_JOY_AXIS - 1); - } - if (p_negate) { - jx.value = -jx.value; - } - return jx; + if (!p_xinput) { + return (float)p_val / MAX_JOY_AXIS; + } + if (p_trigger) { + // Convert to a value between -1.0f and 1.0f. + return 2.0f * p_val / MAX_TRIGGER - 1.0f; + } + float value; + if (p_val < 0) { + value = (float)p_val / MAX_JOY_AXIS; + } else { + value = (float)p_val / (MAX_JOY_AXIS - 1); + } + if (p_negate) { + value = -value; } - jx.min = -1; - jx.value = (float)p_val / MAX_JOY_AXIS; - return jx; + return value; } void JoypadWindows::joypad_vibration_start_xinput(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp) { diff --git a/platform/windows/joypad_windows.h b/platform/windows/joypad_windows.h index 4faefe932f..0e3d03fa52 100644 --- a/platform/windows/joypad_windows.h +++ b/platform/windows/joypad_windows.h @@ -132,7 +132,7 @@ private: void joypad_vibration_start_xinput(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp); void joypad_vibration_stop_xinput(int p_device, uint64_t p_timestamp); - Input::JoyAxisValue axis_correct(int p_val, bool p_xinput = false, bool p_trigger = false, bool p_negate = false) const; + float axis_correct(int p_val, bool p_xinput = false, bool p_trigger = false, bool p_negate = false) const; XInputGetState_t xinput_get_state; XInputSetState_t xinput_set_state; }; diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 9bc3226851..2923b287be 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -164,15 +164,15 @@ void CollisionPolygon2D::_notification(int p_what) { dcol.a = 1.0; Vector2 line_to(0, 20); draw_line(Vector2(), line_to, dcol, 3); - Vector<Vector2> pts; real_t tsize = 8; - pts.push_back(line_to + (Vector2(0, tsize))); - pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0))); - pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0))); - Vector<Color> cols; - for (int i = 0; i < 3; i++) { - cols.push_back(dcol); - } + + Vector<Vector2> pts = { + line_to + Vector2(0, tsize), + line_to + Vector2(Math_SQRT12 * tsize, 0), + line_to + Vector2(-Math_SQRT12 * tsize, 0) + }; + + Vector<Color> cols{ dcol, dcol, dcol }; draw_primitive(pts, cols, Vector<Vector2>()); //small arrow } diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index 18426c088d..a0520ca28f 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -121,15 +121,15 @@ void CollisionShape2D::_notification(int p_what) { } Vector2 line_to(0, 20); draw_line(Vector2(), line_to, draw_col, 2); - Vector<Vector2> pts; real_t tsize = 8; - pts.push_back(line_to + (Vector2(0, tsize))); - pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0))); - pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0))); - Vector<Color> cols; - for (int i = 0; i < 3; i++) { - cols.push_back(draw_col); - } + + Vector<Vector2> pts{ + line_to + Vector2(0, tsize), + line_to + Vector2(Math_SQRT12 * tsize, 0), + line_to + Vector2(-Math_SQRT12 * tsize, 0) + }; + + Vector<Color> cols{ draw_col, draw_col, draw_col }; draw_primitive(pts, cols, Vector<Vector2>()); } diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index f62e7f24e3..4673a99082 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -152,11 +152,14 @@ void CPUParticles2D::_update_mesh_texture() { } else { tex_size = Size2(1, 1); } - Vector<Vector2> vertices; - vertices.push_back(-tex_size * 0.5); - vertices.push_back(-tex_size * 0.5 + Vector2(tex_size.x, 0)); - vertices.push_back(-tex_size * 0.5 + tex_size); - vertices.push_back(-tex_size * 0.5 + Vector2(0, tex_size.y)); + + Vector<Vector2> vertices = { + -tex_size * 0.5, + -tex_size * 0.5 + Vector2(tex_size.x, 0), + -tex_size * 0.5 + tex_size, + -tex_size * 0.5 + Vector2(0, tex_size.y) + }; + Vector<Vector2> uvs; AtlasTexture *atlas_texure = Object::cast_to<AtlasTexture>(*texture); if (atlas_texure && atlas_texure->get_atlas().is_valid()) { @@ -172,18 +175,15 @@ void CPUParticles2D::_update_mesh_texture() { uvs.push_back(Vector2(1, 1)); uvs.push_back(Vector2(0, 1)); } - Vector<Color> colors; - colors.push_back(Color(1, 1, 1, 1)); - colors.push_back(Color(1, 1, 1, 1)); - colors.push_back(Color(1, 1, 1, 1)); - colors.push_back(Color(1, 1, 1, 1)); - Vector<int> indices; - indices.push_back(0); - indices.push_back(1); - indices.push_back(2); - indices.push_back(2); - indices.push_back(3); - indices.push_back(0); + + Vector<Color> colors = { + Color(1, 1, 1, 1), + Color(1, 1, 1, 1), + Color(1, 1, 1, 1), + Color(1, 1, 1, 1) + }; + + Vector<int> indices = { 0, 1, 2, 2, 3, 0 }; Array arr; arr.resize(RS::ARRAY_MAX); diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index 8c8f794298..b6d1e5c934 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -427,26 +427,23 @@ void GPUParticles2D::_notification(int p_what) { } else { RS::get_singleton()->mesh_clear(mesh); - Vector<Vector2> points; - points.resize(4); - points.write[0] = Vector2(-size.x / 2.0, -size.y / 2.0); - points.write[1] = Vector2(size.x / 2.0, -size.y / 2.0); - points.write[2] = Vector2(size.x / 2.0, size.y / 2.0); - points.write[3] = Vector2(-size.x / 2.0, size.y / 2.0); - Vector<Vector2> uvs; - uvs.resize(4); - uvs.write[0] = Vector2(0, 0); - uvs.write[1] = Vector2(1, 0); - uvs.write[2] = Vector2(1, 1); - uvs.write[3] = Vector2(0, 1); - Vector<int> indices; - indices.resize(6); - indices.write[0] = 0; - indices.write[1] = 1; - indices.write[2] = 2; - indices.write[3] = 0; - indices.write[4] = 2; - indices.write[5] = 3; + + Vector<Vector2> points = { + Vector2(-size.x / 2.0, -size.y / 2.0), + Vector2(size.x / 2.0, -size.y / 2.0), + Vector2(size.x / 2.0, size.y / 2.0), + Vector2(-size.x / 2.0, size.y / 2.0) + }; + + Vector<Vector2> uvs = { + Vector2(0, 0), + Vector2(1, 0), + Vector2(1, 1), + Vector2(0, 1) + }; + + Vector<int> indices = { 0, 1, 2, 0, 2, 3 }; + Array arr; arr.resize(RS::ARRAY_MAX); arr[RS::ARRAY_VERTEX] = points; diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp index 28aeff98ca..67aff9c520 100644 --- a/scene/2d/position_2d.cpp +++ b/scene/2d/position_2d.cpp @@ -36,37 +36,41 @@ void Position2D::_draw_cross() { const real_t extents = get_gizmo_extents(); // Add more points to create a "hard stop" in the color gradient. - PackedVector2Array points_x; - points_x.push_back(Point2(+extents, 0)); - points_x.push_back(Point2()); - points_x.push_back(Point2()); - points_x.push_back(Point2(-extents, 0)); - - PackedVector2Array points_y; - points_y.push_back(Point2(0, +extents)); - points_y.push_back(Point2()); - points_y.push_back(Point2()); - points_y.push_back(Point2(0, -extents)); + PackedVector2Array points_x = { + Point2(+extents, 0), + Point2(), + Point2(), + Point2(-extents, 0) + }; + + PackedVector2Array points_y = { + Point2(0, +extents), + Point2(), + Point2(), + Point2(0, -extents) + }; // Use the axis color which is brighter for the positive axis. // Use a darkened axis color for the negative axis. // This makes it possible to see in which direction the Position3D node is rotated // (which can be important depending on how it's used). // Axis colors are taken from `axis_x_color` and `axis_y_color` (defined in `editor/editor_themes.cpp`). - PackedColorArray colors_x; const Color color_x = Color(0.96, 0.20, 0.32); - colors_x.push_back(color_x); - colors_x.push_back(color_x); - colors_x.push_back(color_x.lerp(Color(0, 0, 0), 0.5)); - colors_x.push_back(color_x.lerp(Color(0, 0, 0), 0.5)); + PackedColorArray colors_x = { + color_x, + color_x, + color_x.lerp(Color(0, 0, 0), 0.5), + color_x.lerp(Color(0, 0, 0), 0.5) + }; draw_multiline_colors(points_x, colors_x); - PackedColorArray colors_y; const Color color_y = Color(0.53, 0.84, 0.01); - colors_y.push_back(color_y); - colors_y.push_back(color_y); - colors_y.push_back(color_y.lerp(Color(0, 0, 0), 0.5)); - colors_y.push_back(color_y.lerp(Color(0, 0, 0), 0.5)); + PackedColorArray colors_y = { + color_y, + color_y, + color_y.lerp(Color(0, 0, 0), 0.5), + color_y.lerp(Color(0, 0, 0), 0.5) + }; draw_multiline_colors(points_y, colors_y); } diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 33090fbacc..1fdd8b05a6 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -244,15 +244,13 @@ void RayCast2D::_draw_debug_shape() { xf.rotate(target_position.angle()); xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0)); - Vector<Vector2> pts; - pts.push_back(xf.xform(Vector2(arrow_size, 0))); - pts.push_back(xf.xform(Vector2(0, 0.5 * arrow_size))); - pts.push_back(xf.xform(Vector2(0, -0.5 * arrow_size))); - - Vector<Color> cols; - for (int i = 0; i < 3; i++) { - cols.push_back(draw_col); - } + Vector<Vector2> pts = { + xf.xform(Vector2(arrow_size, 0)), + xf.xform(Vector2(0, 0.5 * arrow_size)), + xf.xform(Vector2(0, -0.5 * arrow_size)) + }; + + Vector<Color> cols = { draw_col, draw_col, draw_col }; draw_primitive(pts, cols, Vector<Vector2>()); } diff --git a/scene/2d/shape_cast_2d.cpp b/scene/2d/shape_cast_2d.cpp index 7fc1992e96..10194861b4 100644 --- a/scene/2d/shape_cast_2d.cpp +++ b/scene/2d/shape_cast_2d.cpp @@ -239,14 +239,16 @@ void ShapeCast2D::_notification(int p_what) { xf.translate(Vector2(target_position.length(), 0)); draw_line(Vector2(), target_position, draw_col, 2); - Vector<Vector2> pts; + float tsize = 8; - pts.push_back(xf.xform(Vector2(tsize, 0))); - pts.push_back(xf.xform(Vector2(0, Math_SQRT12 * tsize))); - pts.push_back(xf.xform(Vector2(0, -Math_SQRT12 * tsize))); - Vector<Color> cols; - for (int i = 0; i < 3; i++) - cols.push_back(draw_col); + + Vector<Vector2> pts = { + xf.xform(Vector2(tsize, 0)), + xf.xform(Vector2(0, Math_SQRT12 * tsize)), + xf.xform(Vector2(0, -Math_SQRT12 * tsize)) + }; + + Vector<Color> cols = { draw_col, draw_col, draw_col }; draw_primitive(pts, cols, Vector<Vector2>()); } diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index 77e6ad44c6..ff186b01f2 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -32,13 +32,13 @@ #include "scene/main/window.h" -void TouchScreenButton::set_texture(const Ref<Texture2D> &p_texture) { - texture = p_texture; +void TouchScreenButton::set_texture_normal(const Ref<Texture2D> &p_texture) { + texture_normal = p_texture; update(); } -Ref<Texture2D> TouchScreenButton::get_texture() const { - return texture; +Ref<Texture2D> TouchScreenButton::get_texture_normal() const { + return texture_normal; } void TouchScreenButton::set_texture_pressed(const Ref<Texture2D> &p_texture_pressed) { @@ -107,13 +107,13 @@ void TouchScreenButton::_notification(int p_what) { if (finger_pressed != -1) { if (texture_pressed.is_valid()) { draw_texture(texture_pressed, Point2()); - } else if (texture.is_valid()) { - draw_texture(texture, Point2()); + } else if (texture_normal.is_valid()) { + draw_texture(texture_normal, Point2()); } } else { - if (texture.is_valid()) { - draw_texture(texture, Point2()); + if (texture_normal.is_valid()) { + draw_texture(texture_normal, Point2()); } } @@ -127,8 +127,8 @@ void TouchScreenButton::_notification(int p_what) { Color draw_col = get_tree()->get_debug_collisions_color(); Vector2 pos; - if (shape_centered && texture.is_valid()) { - pos = texture->get_size() * 0.5; + if (shape_centered && texture_normal.is_valid()) { + pos = texture_normal->get_size() * 0.5; } draw_set_transform_matrix(get_canvas_transform().translated(pos)); @@ -254,8 +254,8 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) { check_rect = false; Vector2 pos; - if (shape_centered && texture.is_valid()) { - pos = texture->get_size() * 0.5; + if (shape_centered && texture_normal.is_valid()) { + pos = texture_normal->get_size() * 0.5; } touched = shape->collide(Transform2D().translated(pos), unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5))); @@ -271,8 +271,8 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) { } if (!touched && check_rect) { - if (texture.is_valid()) { - touched = Rect2(Size2(), texture->get_size()).has_point(coord); + if (texture_normal.is_valid()) { + touched = Rect2(Size2(), texture_normal->get_size()).has_point(coord); } } @@ -317,24 +317,24 @@ void TouchScreenButton::_release(bool p_exiting_tree) { #ifdef TOOLS_ENABLED Rect2 TouchScreenButton::_edit_get_rect() const { - if (texture.is_null()) { + if (texture_normal.is_null()) { return CanvasItem::_edit_get_rect(); } - return Rect2(Size2(), texture->get_size()); + return Rect2(Size2(), texture_normal->get_size()); } bool TouchScreenButton::_edit_use_rect() const { - return !texture.is_null(); + return !texture_normal.is_null(); } #endif Rect2 TouchScreenButton::get_anchorable_rect() const { - if (texture.is_null()) { + if (texture_normal.is_null()) { return CanvasItem::get_anchorable_rect(); } - return Rect2(Size2(), texture->get_size()); + return Rect2(Size2(), texture_normal->get_size()); } void TouchScreenButton::set_visibility_mode(VisibilityMode p_mode) { @@ -355,10 +355,10 @@ bool TouchScreenButton::is_passby_press_enabled() const { } void TouchScreenButton::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_texture", "texture"), &TouchScreenButton::set_texture); - ClassDB::bind_method(D_METHOD("get_texture"), &TouchScreenButton::get_texture); + ClassDB::bind_method(D_METHOD("set_texture_normal", "texture"), &TouchScreenButton::set_texture_normal); + ClassDB::bind_method(D_METHOD("get_texture_normal"), &TouchScreenButton::get_texture_normal); - ClassDB::bind_method(D_METHOD("set_texture_pressed", "texture_pressed"), &TouchScreenButton::set_texture_pressed); + ClassDB::bind_method(D_METHOD("set_texture_pressed", "texture"), &TouchScreenButton::set_texture_pressed); ClassDB::bind_method(D_METHOD("get_texture_pressed"), &TouchScreenButton::get_texture_pressed); ClassDB::bind_method(D_METHOD("set_bitmask", "bitmask"), &TouchScreenButton::set_bitmask); @@ -384,8 +384,8 @@ void TouchScreenButton::_bind_methods() { ClassDB::bind_method(D_METHOD("is_pressed"), &TouchScreenButton::is_pressed); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture_pressed", "get_texture_pressed"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture_normal", "get_texture_normal"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture_pressed", "get_texture_pressed"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "bitmask", PROPERTY_HINT_RESOURCE_TYPE, "BitMap"), "set_bitmask", "get_bitmask"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", "get_shape"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shape_centered"), "set_shape_centered", "is_shape_centered"); diff --git a/scene/2d/touch_screen_button.h b/scene/2d/touch_screen_button.h index 6ed9ba8dc7..e7f6da9f50 100644 --- a/scene/2d/touch_screen_button.h +++ b/scene/2d/touch_screen_button.h @@ -46,7 +46,7 @@ public: }; private: - Ref<Texture2D> texture; + Ref<Texture2D> texture_normal; Ref<Texture2D> texture_pressed; Ref<BitMap> bitmask; Ref<Shape2D> shape; @@ -78,8 +78,8 @@ public: virtual bool _edit_use_rect() const override; #endif - void set_texture(const Ref<Texture2D> &p_texture); - Ref<Texture2D> get_texture() const; + void set_texture_normal(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture_normal() const; void set_texture_pressed(const Ref<Texture2D> &p_texture_pressed); Ref<Texture2D> get_texture_pressed() const; diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index 55fa05d3fd..2c95010eb4 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -331,11 +331,13 @@ Vector<Vector3> Camera3D::get_near_plane_points() const { Vector3 endpoints[8]; cm.get_endpoints(Transform3D(), endpoints); - Vector<Vector3> points; - points.push_back(Vector3()); - for (int i = 0; i < 4; i++) { - points.push_back(endpoints[i + 4]); - } + Vector<Vector3> points = { + Vector3(), + endpoints[4], + endpoints[5], + endpoints[6], + endpoints[7] + }; return points; } diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp index 6089c785a2..c645009c72 100644 --- a/scene/3d/skeleton_ik_3d.cpp +++ b/scene/3d/skeleton_ik_3d.cpp @@ -28,10 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -/** - * @author AndreaCatania - */ - #include "skeleton_ik_3d.h" #ifndef _3D_DISABLED diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 2b4ddce0e2..a37fce9469 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -141,15 +141,6 @@ real_t SpriteBase3D::get_pixel_size() const { return pixel_size; } -void SpriteBase3D::set_opacity(float p_amount) { - opacity = p_amount; - _queue_update(); -} - -float SpriteBase3D::get_opacity() const { - return opacity; -} - void SpriteBase3D::set_axis(Vector3::Axis p_axis) { ERR_FAIL_INDEX(p_axis, 3); axis = p_axis; @@ -295,9 +286,6 @@ void SpriteBase3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_modulate", "modulate"), &SpriteBase3D::set_modulate); ClassDB::bind_method(D_METHOD("get_modulate"), &SpriteBase3D::get_modulate); - ClassDB::bind_method(D_METHOD("set_opacity", "opacity"), &SpriteBase3D::set_opacity); - ClassDB::bind_method(D_METHOD("get_opacity"), &SpriteBase3D::get_opacity); - ClassDB::bind_method(D_METHOD("set_pixel_size", "pixel_size"), &SpriteBase3D::set_pixel_size); ClassDB::bind_method(D_METHOD("get_pixel_size"), &SpriteBase3D::get_pixel_size); @@ -324,7 +312,6 @@ void SpriteBase3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_v"), "set_flip_v", "is_flipped_v"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "opacity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_opacity", "get_opacity"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pixel_size", PROPERTY_HINT_RANGE, "0.0001,128,0.0001"), "set_pixel_size", "get_pixel_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "axis", PROPERTY_HINT_ENUM, "X-Axis,Y-Axis,Z-Axis"), "set_axis", "get_axis"); ADD_GROUP("Flags", ""); @@ -468,7 +455,6 @@ void Sprite3D::_draw() { } Color color = _get_color_accum(); - color.a *= get_opacity(); real_t pixel_size = get_pixel_size(); @@ -837,7 +823,6 @@ void AnimatedSprite3D::_draw() { } Color color = _get_color_accum(); - color.a *= get_opacity(); real_t pixel_size = get_pixel_size(); diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index 6a61219edf..985103e190 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -69,7 +69,6 @@ private: bool vflip = false; Color modulate = Color(1, 1, 1, 1); - float opacity = 1.0; Vector3::Axis axis = Vector3::AXIS_Z; real_t pixel_size = 0.01; @@ -121,9 +120,6 @@ public: void set_modulate(const Color &p_color); Color get_modulate() const; - void set_opacity(float p_amount); - float get_opacity() const; - void set_pixel_size(real_t p_amount); real_t get_pixel_size() const; diff --git a/scene/3d/xr_nodes.h b/scene/3d/xr_nodes.h index 8e1ef1a4fb..5675cbd944 100644 --- a/scene/3d/xr_nodes.h +++ b/scene/3d/xr_nodes.h @@ -34,13 +34,10 @@ #include "scene/3d/camera_3d.h" #include "servers/xr/xr_positional_tracker.h" -/** - @author Bastiaan Olij <mux213@gmail.com> -**/ - /* XRCamera is a subclass of camera which will register itself with its parent XROrigin and as a result is automatically positioned */ + class XRCamera3D : public Camera3D { GDCLASS(XRCamera3D, Camera3D); @@ -181,6 +178,7 @@ public: Our camera and controllers will always be child nodes and thus place relative to this origin point. This node will automatically locate any camera child nodes and update its position while our XRController3D node will handle tracked controllers. */ + class XROrigin3D : public Node3D { GDCLASS(XROrigin3D, Node3D); @@ -204,4 +202,4 @@ public: ~XROrigin3D() {} }; -#endif /* XR_NODES_H */ +#endif // XR_NODES_H diff --git a/scene/gui/check_box.h b/scene/gui/check_box.h index 735c7aedfe..fcdb2ce08c 100644 --- a/scene/gui/check_box.h +++ b/scene/gui/check_box.h @@ -32,9 +32,7 @@ #define CHECK_BOX_H #include "scene/gui/button.h" -/** -@author Mariano Suligoy <marianognu.esyrpg@gmail.com> -*/ + class CheckBox : public Button { GDCLASS(CheckBox, Button); @@ -50,4 +48,4 @@ public: ~CheckBox(); }; -#endif +#endif // CHECK_BOX_H diff --git a/scene/gui/check_button.h b/scene/gui/check_button.h index 5ba81a1027..9a72d04db2 100644 --- a/scene/gui/check_button.h +++ b/scene/gui/check_button.h @@ -32,9 +32,7 @@ #define CHECK_BUTTON_H #include "scene/gui/button.h" -/** -@author Juan Linietsky <reduzio@gmail.com> -*/ + class CheckButton : public Button { GDCLASS(CheckButton, Button); @@ -48,4 +46,4 @@ public: ~CheckButton(); }; -#endif +#endif // CHECK_BUTTON_H diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index 398b909195..040075150b 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -92,7 +92,7 @@ void CodeEdit::_notification(int p_what) { if (line_length_guideline_columns.size() > 0) { const int xmargin_beg = style_normal->get_margin(SIDE_LEFT) + get_total_gutter_width(); const int xmargin_end = size.width - style_normal->get_margin(SIDE_RIGHT) - (is_drawing_minimap() ? get_minimap_width() : 0); - const int char_size = (int)font->get_char_size('0', 0, font_size).width; + const int char_size = Math::round(font->get_char_size('0', 0, font_size).width); for (int i = 0; i < line_length_guideline_columns.size(); i++) { const int xoffset = xmargin_beg + char_size * (int)line_length_guideline_columns[i] - get_h_scroll(); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 378bfb69dc..79b73f7cc3 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -35,6 +35,7 @@ #include "core/os/keyboard.h" #include "scene/gui/box_container.h" #include "scene/gui/button.h" +#include "scene/gui/view_panner.h" constexpr int MINIMAP_OFFSET = 12; constexpr int MINIMAP_PADDING = 5; @@ -1069,13 +1070,9 @@ void GraphEdit::set_selected(Node *p_child) { void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { ERR_FAIL_COND(p_ev.is_null()); + panner->gui_input(p_ev); Ref<InputEventMouseMotion> mm = p_ev; - if (mm.is_valid() && ((mm->get_button_mask() & MouseButton::MASK_MIDDLE) != MouseButton::NONE || ((mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE && Input::get_singleton()->is_key_pressed(Key::SPACE)))) { - Vector2i relative = Input::get_singleton()->warp_mouse_motion(mm, get_global_rect()); - h_scroll->set_value(h_scroll->get_value() - relative.x); - v_scroll->set_value(v_scroll->get_value() - relative.y); - } if (mm.is_valid() && dragging) { if (!moving_selection) { @@ -1327,22 +1324,6 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { top_layer->update(); minimap->update(); } - - int scroll_direction = (b->get_button_index() == MouseButton::WHEEL_DOWN) - (b->get_button_index() == MouseButton::WHEEL_UP); - if (scroll_direction != 0) { - if (b->is_ctrl_pressed()) { - if (b->is_shift_pressed()) { - // Horizontal scrolling. - h_scroll->set_value(h_scroll->get_value() + (h_scroll->get_page() * b->get_factor() / 8) * scroll_direction); - } else { - // Vertical scrolling. - v_scroll->set_value(v_scroll->get_value() + (v_scroll->get_page() * b->get_factor() / 8) * scroll_direction); - } - } else { - // Zooming. - set_zoom_custom(scroll_direction < 0 ? zoom * zoom_step : zoom / zoom_step, b->get_position()); - } - } } if (p_ev->is_pressed()) { @@ -1373,6 +1354,23 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { } } +void GraphEdit::_scroll_callback(Vector2 p_scroll_vec) { + if (p_scroll_vec.x != 0) { + h_scroll->set_value(h_scroll->get_value() + (h_scroll->get_page() * Math::abs(p_scroll_vec.x) / 8) * SIGN(p_scroll_vec.x)); + } else { + v_scroll->set_value(v_scroll->get_value() + (v_scroll->get_page() * Math::abs(p_scroll_vec.y) / 8) * SIGN(p_scroll_vec.y)); + } +} + +void GraphEdit::_pan_callback(Vector2 p_scroll_vec) { + h_scroll->set_value(h_scroll->get_value() - p_scroll_vec.x); + v_scroll->set_value(v_scroll->get_value() - p_scroll_vec.y); +} + +void GraphEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) { + set_zoom_custom(p_scroll_vec.y < 0 ? zoom * zoom_step : zoom / zoom_step, p_origin); +} + void GraphEdit::set_connection_activity(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port, float p_activity) { for (Connection &E : connections) { if (E.from == p_from && E.from_port == p_from_port && E.to == p_to && E.to_port == p_to_port) { @@ -1406,6 +1404,15 @@ void GraphEdit::force_connection_drag_end() { emit_signal(SNAME("connection_drag_ended")); } +void GraphEdit::set_panning_scheme(PanningScheme p_scheme) { + panning_scheme = p_scheme; + panner->set_control_scheme((ViewPanner::ControlScheme)p_scheme); +} + +GraphEdit::PanningScheme GraphEdit::get_panning_scheme() const { + return panning_scheme; +} + void GraphEdit::set_zoom(float p_zoom) { set_zoom_custom(p_zoom, get_size() / 2); } @@ -2190,6 +2197,9 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("is_valid_connection_type", "from_type", "to_type"), &GraphEdit::is_valid_connection_type); ClassDB::bind_method(D_METHOD("get_connection_line", "from", "to"), &GraphEdit::get_connection_line); + ClassDB::bind_method(D_METHOD("set_panning_scheme", "scheme"), &GraphEdit::set_panning_scheme); + ClassDB::bind_method(D_METHOD("get_panning_scheme"), &GraphEdit::get_panning_scheme); + ClassDB::bind_method(D_METHOD("set_zoom", "zoom"), &GraphEdit::set_zoom); ClassDB::bind_method(D_METHOD("get_zoom"), &GraphEdit::get_zoom); @@ -2244,6 +2254,7 @@ void GraphEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll_offset"), "set_scroll_ofs", "get_scroll_ofs"); ADD_PROPERTY(PropertyInfo(Variant::INT, "snap_distance"), "set_snap", "get_snap"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_snap"), "set_use_snap", "is_using_snap"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "panning_scheme", PROPERTY_HINT_ENUM, "Scroll Zooms,Scroll Pans"), "set_panning_scheme", "get_panning_scheme"); ADD_GROUP("Connection Lines", "connection_lines"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "connection_lines_thickness"), "set_connection_lines_thickness", "get_connection_lines_thickness"); @@ -2277,6 +2288,9 @@ void GraphEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("scroll_offset_changed", PropertyInfo(Variant::VECTOR2, "ofs"))); ADD_SIGNAL(MethodInfo("connection_drag_started", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::STRING, "slot"), PropertyInfo(Variant::BOOL, "is_output"))); ADD_SIGNAL(MethodInfo("connection_drag_ended")); + + BIND_ENUM_CONSTANT(SCROLL_ZOOMS); + BIND_ENUM_CONSTANT(SCROLL_PANS); } GraphEdit::GraphEdit() { @@ -2289,6 +2303,10 @@ GraphEdit::GraphEdit() { // Allow zooming 4 times from the default zoom level. zoom_max = (1 * Math::pow(zoom_step, 4)); + panner.instantiate(); + panner->set_callbacks(callable_mp(this, &GraphEdit::_scroll_callback), callable_mp(this, &GraphEdit::_pan_callback), callable_mp(this, &GraphEdit::_zoom_callback)); + panner->set_disable_rmb(true); + top_layer = memnew(GraphEditFilter(this)); add_child(top_layer, false, INTERNAL_MODE_BACK); top_layer->set_mouse_filter(MOUSE_FILTER_PASS); diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 145e0dcc59..4e998d30a7 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -41,6 +41,7 @@ #include "scene/gui/texture_rect.h" class GraphEdit; +class ViewPanner; class GraphEditFilter : public Control { GDCLASS(GraphEditFilter, Control); @@ -103,6 +104,12 @@ public: float activity = 0.0; }; + // Should be in sync with ControlScheme in ViewPanner. + enum PanningScheme { + SCROLL_ZOOMS, + SCROLL_PANS, + }; + private: Label *zoom_label; Button *zoom_minus; @@ -122,6 +129,11 @@ private: float port_grab_distance_horizontal = 0.0; float port_grab_distance_vertical; + Ref<ViewPanner> panner; + void _scroll_callback(Vector2 p_scroll_vec); + void _pan_callback(Vector2 p_scroll_vec); + void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin); + bool connecting = false; String connecting_from; bool connecting_out = false; @@ -136,6 +148,7 @@ private: bool connecting_valid = false; Vector2 click_pos; + PanningScheme panning_scheme = SCROLL_ZOOMS; bool dragging = false; bool just_selected = false; bool moving_selection = false; @@ -277,6 +290,9 @@ public: void remove_valid_connection_type(int p_type, int p_with_type); bool is_valid_connection_type(int p_type, int p_with_type) const; + void set_panning_scheme(PanningScheme p_scheme); + PanningScheme get_panning_scheme() const; + void set_zoom(float p_zoom); void set_zoom_custom(float p_zoom, const Vector2 &p_center); float get_zoom() const; @@ -338,4 +354,6 @@ public: GraphEdit(); }; +VARIANT_ENUM_CAST(GraphEdit::PanningScheme); + #endif // GRAPHEdit_H diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index edd206a1ca..861b70f17e 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -183,11 +183,9 @@ void Label::_shape() { TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], width, overrun_flags); } } - } else if (lines_hidden) { TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], width, overrun_flags); } - } else { // Autowrap disabled. for (int i = 0; i < lines_rid.size(); i++) { @@ -294,7 +292,7 @@ void Label::_notification(int p_what) { Color font_outline_color = get_theme_color(SNAME("font_outline_color")); int outline_size = get_theme_constant(SNAME("outline_size")); int shadow_outline_size = get_theme_constant(SNAME("shadow_outline_size")); - bool rtl = TS->shaped_text_get_direction(text_rid); + bool rtl = (TS->shaped_text_get_inferred_direction(text_rid) == TextServer::DIRECTION_RTL); bool rtl_layout = is_layout_rtl(); style->draw(ci, Rect2(Point2(0, 0), get_size())); @@ -422,19 +420,19 @@ void Label::_notification(int p_what) { // Draw main text. for (int j = 0; j < gl_size; j++) { - for (int k = 0; k < glyphs[j].repeat; k++) { - // Trim when necessary. - if (trim_pos >= 0) { - if (rtl) { - if (j < trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - continue; - } - } else { - if (j >= trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - break; - } + // Trim when necessary. + if (trim_pos >= 0) { + if (rtl) { + if (j < trim_pos) { + continue; + } + } else { + if (j >= trim_pos) { + break; } } + } + for (int k = 0; k < glyphs[j].repeat; k++) { bool skip = (trim_chars && glyphs[j].end > visible_chars) || (trim_glyphs_ltr && (processed_glyphs_ol >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_ol < total_glyphs - visible_glyphs)); // Draw glyph outlines and shadow. @@ -480,19 +478,19 @@ void Label::_notification(int p_what) { // Draw main text. for (int j = 0; j < gl_size; j++) { - for (int k = 0; k < glyphs[j].repeat; k++) { - // Trim when necessary. - if (trim_pos >= 0) { - if (rtl) { - if (j < trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - continue; - } - } else { - if (j >= trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - break; - } + // Trim when necessary. + if (trim_pos >= 0) { + if (rtl) { + if (j < trim_pos) { + continue; + } + } else { + if (j >= trim_pos) { + break; } } + } + for (int k = 0; k < glyphs[j].repeat; k++) { bool skip = (trim_chars && glyphs[j].end > visible_chars) || (trim_glyphs_ltr && (processed_glyphs >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs < total_glyphs - visible_glyphs)); // Draw glyph outlines and shadow. diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index ec18101d2f..f7d6850a88 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -780,8 +780,6 @@ void LineEdit::_notification(int p_what) { ofs_max -= r_icon->get_width(); } - int caret_width = Math::round(1 * get_theme_default_base_scale()); - // Draw selections rects. Vector2 ofs = Point2(x_ofs + scroll_offset, y_ofs); if (selection.enabled) { @@ -843,6 +841,8 @@ void LineEdit::_notification(int p_what) { // Draw carets. ofs.x = x_ofs + scroll_offset; if (draw_caret || drag_caret_force_displayed) { + const int caret_width = get_theme_constant(SNAME("caret_width")) * get_theme_default_base_scale(); + if (ime_text.length() == 0) { // Normal caret. CaretInfo caret = TS->shaped_text_get_carets(text_rid, caret_column); diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp index 92da169487..9da030f0a2 100644 --- a/scene/gui/tab_bar.cpp +++ b/scene/gui/tab_bar.cpp @@ -147,6 +147,7 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { if (scrolling_enabled && buttons_visible) { if (offset > 0) { offset--; + _update_cache(); update(); } } @@ -154,9 +155,9 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { if (mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN && !mb->is_command_pressed()) { if (scrolling_enabled && buttons_visible) { - if (missing_right) { + if (missing_right && offset < tabs.size()) { offset++; - _ensure_no_over_offset(); // Avoid overreaching when scrolling fast. + _update_cache(); update(); } } @@ -194,12 +195,14 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { if (pos.x < decr->get_width()) { if (missing_right) { offset++; + _update_cache(); update(); } return; } else if (pos.x < incr->get_width() + decr->get_width()) { if (offset > 0) { offset--; + _update_cache(); update(); } return; @@ -209,12 +212,14 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { if (pos.x > limit + decr->get_width()) { if (missing_right) { offset++; + _update_cache(); update(); } return; } else if (pos.x > limit) { if (offset > 0) { offset--; + _update_cache(); update(); } return; @@ -294,8 +299,9 @@ void TabBar::_notification(int p_what) { ensure_tab_visible(current); } break; case NOTIFICATION_DRAW: { - _update_cache(); - RID ci = get_canvas_item(); + if (tabs.is_empty()) { + return; + } Ref<StyleBox> tab_unselected = get_theme_stylebox(SNAME("tab_unselected")); Ref<StyleBox> tab_selected = get_theme_stylebox(SNAME("tab_selected")); @@ -303,174 +309,46 @@ void TabBar::_notification(int p_what) { Color font_selected_color = get_theme_color(SNAME("font_selected_color")); Color font_unselected_color = get_theme_color(SNAME("font_unselected_color")); Color font_disabled_color = get_theme_color(SNAME("font_disabled_color")); - Ref<Texture2D> close = get_theme_icon(SNAME("close")); - Color font_outline_color = get_theme_color(SNAME("font_outline_color")); - int outline_size = get_theme_constant(SNAME("outline_size")); - - Vector2 size = get_size(); - bool rtl = is_layout_rtl(); - - int h = get_size().height; - int w = 0; - int mw = 0; - - for (int i = 0; i < tabs.size(); i++) { - tabs.write[i].ofs_cache = mw; - mw += get_tab_width(i); - } - - if (tab_alignment == ALIGNMENT_CENTER) { - w = (get_size().width - mw) / 2; - } else if (tab_alignment == ALIGNMENT_RIGHT) { - w = get_size().width - mw; - } - - if (w < 0) { - w = 0; - } - Ref<Texture2D> incr = get_theme_icon(SNAME("increment")); Ref<Texture2D> decr = get_theme_icon(SNAME("decrement")); Ref<Texture2D> incr_hl = get_theme_icon(SNAME("increment_highlight")); Ref<Texture2D> decr_hl = get_theme_icon(SNAME("decrement_highlight")); - int limit = get_size().width; - int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width(); - - missing_right = false; - - for (int i = offset; i < tabs.size(); i++) { - tabs.write[i].ofs_cache = w; - - int lsize = tabs[i].size_cache; - - Ref<StyleBox> sb; - Color col; - - if (tabs[i].disabled) { - sb = tab_disabled; - col = font_disabled_color; - } else if (i == current) { - sb = tab_selected; - col = font_selected_color; - } else { - sb = tab_unselected; - col = font_unselected_color; - } - - int new_width = w + lsize; - if (new_width > limit || (i < tabs.size() - 1 && new_width > limit_minus_buttons)) { // For the last tab, we accept if the tab covers the buttons. - max_drawn_tab = i - 1; - missing_right = true; - break; - } else { - max_drawn_tab = i; - } - - Rect2 sb_rect; - if (rtl) { - sb_rect = Rect2(size.width - w - tabs[i].size_cache, 0, tabs[i].size_cache, h); - } else { - sb_rect = Rect2(w, 0, tabs[i].size_cache, h); - } - sb->draw(ci, sb_rect); - - w += sb->get_margin(SIDE_LEFT); - - Size2i sb_ms = sb->get_minimum_size(); - Ref<Texture2D> icon = tabs[i].icon; - if (icon.is_valid()) { - if (rtl) { - icon->draw(ci, Point2i(size.width - w - icon->get_width(), sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2)); - } else { - icon->draw(ci, Point2i(w, sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2)); - } - if (!tabs[i].text.is_empty()) { - w += icon->get_width() + get_theme_constant(SNAME("hseparation")); - } - } - - if (rtl) { - Vector2 text_pos = Point2i(size.width - w - tabs[i].text_buf->get_size().x, sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tabs[i].text_buf->get_size().y) / 2); - if (outline_size > 0 && font_outline_color.a > 0) { - tabs[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); - } - tabs[i].text_buf->draw(ci, text_pos, col); - } else { - Vector2 text_pos = Point2i(w, sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tabs[i].text_buf->get_size().y) / 2); - if (outline_size > 0 && font_outline_color.a > 0) { - tabs[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); - } - tabs[i].text_buf->draw(ci, text_pos, col); - } - - w += tabs[i].size_text; - - if (tabs[i].right_button.is_valid()) { - Ref<StyleBox> style = get_theme_stylebox(SNAME("close_bg_highlight")); - Ref<Texture2D> rb = tabs[i].right_button; + bool rtl = is_layout_rtl(); + Vector2 size = get_size(); + int limit_minus_buttons = size.width - incr->get_width() - decr->get_width(); - w += get_theme_constant(SNAME("hseparation")); + int ofs = tabs[offset].ofs_cache; - Rect2 rb_rect; - rb_rect.size = style->get_minimum_size() + rb->get_size(); - if (rtl) { - rb_rect.position.x = size.width - w - rb_rect.size.x; + // Draw unselected tabs in the back. + for (int i = offset; i <= max_drawn_tab; i++) { + if (i != current) { + Ref<StyleBox> sb; + Color col; + + if (tabs[i].disabled) { + sb = tab_disabled; + col = font_disabled_color; + } else if (i == current) { + sb = tab_selected; + col = font_selected_color; } else { - rb_rect.position.x = w; + sb = tab_unselected; + col = font_unselected_color; } - rb_rect.position.y = sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - (rb_rect.size.y)) / 2; - if (rb_hover == i) { - if (rb_pressing) { - get_theme_stylebox(SNAME("button_pressed"))->draw(ci, rb_rect); - } else { - style->draw(ci, rb_rect); - } - } - - if (rtl) { - rb->draw(ci, Point2i(size.width - w - rb_rect.size.x + style->get_margin(SIDE_LEFT), rb_rect.position.y + style->get_margin(SIDE_TOP))); - } else { - rb->draw(ci, Point2i(w + style->get_margin(SIDE_LEFT), rb_rect.position.y + style->get_margin(SIDE_TOP))); - } - w += rb->get_width(); - tabs.write[i].rb_rect = rb_rect; + _draw_tab(sb, col, i, rtl ? size.width - ofs - tabs[i].size_cache : ofs); } - if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) { - Ref<StyleBox> style = get_theme_stylebox(SNAME("close_bg_highlight")); - Ref<Texture2D> cb = close; - - w += get_theme_constant(SNAME("hseparation")); - - Rect2 cb_rect; - cb_rect.size = style->get_minimum_size() + cb->get_size(); - if (rtl) { - cb_rect.position.x = size.width - w - cb_rect.size.x; - } else { - cb_rect.position.x = w; - } - cb_rect.position.y = sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - (cb_rect.size.y)) / 2; - - if (!tabs[i].disabled && cb_hover == i) { - if (cb_pressing) { - get_theme_stylebox(SNAME("close_bg_pressed"))->draw(ci, cb_rect); - } else { - style->draw(ci, cb_rect); - } - } + ofs += tabs[i].size_cache; + } - if (rtl) { - cb->draw(ci, Point2i(size.width - w - cb_rect.size.x + style->get_margin(SIDE_LEFT), cb_rect.position.y + style->get_margin(SIDE_TOP))); - } else { - cb->draw(ci, Point2i(w + style->get_margin(SIDE_LEFT), cb_rect.position.y + style->get_margin(SIDE_TOP))); - } - w += cb->get_width(); - tabs.write[i].cb_rect = cb_rect; - } + // Draw selected tab in the front, but only if it's visible. + if (current >= offset && current <= max_drawn_tab) { + Ref<StyleBox> sb = tabs[current].disabled ? tab_disabled : tab_selected; + float x = rtl ? size.width - tabs[current].ofs_cache - tabs[current].size_cache : tabs[current].ofs_cache; - w += sb->get_margin(SIDE_RIGHT); + _draw_tab(sb, font_selected_color, current, x); } if (offset > 0 || missing_right) { @@ -501,18 +379,96 @@ void TabBar::_notification(int p_what) { draw_texture(incr, Point2(limit_minus_buttons + decr->get_size().width, vofs), Color(1, 1, 1, 0.5)); } } + } + } break; + } +} + +void TabBar::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, int p_index, float p_x) { + RID ci = get_canvas_item(); + + Color font_outline_color = get_theme_color(SNAME("font_outline_color")); + int outline_size = get_theme_constant(SNAME("outline_size")); + + Tab tab = tabs[p_index]; + + Rect2 sb_rect = Rect2(p_x, 0, tab.size_cache, get_size().height); + p_tab_style->draw(ci, sb_rect); + + p_x += p_tab_style->get_margin(SIDE_LEFT); + + Size2i sb_ms = p_tab_style->get_minimum_size(); + + Ref<Texture2D> icon = tab.icon; + if (icon.is_valid()) { + icon->draw(ci, Point2i(p_x, p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2)); + + if (!tab.text.is_empty()) { + p_x += icon->get_width() + get_theme_constant(SNAME("hseparation")); + } + } + + Vector2 text_pos = Point2i(p_x, p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tab.text_buf->get_size().y) / 2); + if (outline_size > 0 && font_outline_color.a > 0) { + tab.text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); + } + tab.text_buf->draw(ci, text_pos, p_font_color); + + p_x += tab.size_text; - buttons_visible = true; + if (tab.right_button.is_valid()) { + Ref<StyleBox> style = get_theme_stylebox(SNAME("close_bg_highlight")); + Ref<Texture2D> rb = tab.right_button; + + p_x += get_theme_constant(SNAME("hseparation")); + + Rect2 rb_rect; + rb_rect.size = style->get_minimum_size() + rb->get_size(); + rb_rect.position.x = p_x; + rb_rect.position.y = p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - (rb_rect.size.y)) / 2; + + if (rb_hover == p_index) { + if (rb_pressing) { + get_theme_stylebox(SNAME("button_pressed"))->draw(ci, rb_rect); } else { - buttons_visible = false; + style->draw(ci, rb_rect); } - } break; + } + + rb->draw(ci, Point2i(p_x + style->get_margin(SIDE_LEFT), rb_rect.position.y + style->get_margin(SIDE_TOP))); + p_x += rb->get_width(); + tabs.write[p_index].rb_rect = rb_rect; + } + + if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && p_index == current)) { + Ref<StyleBox> style = get_theme_stylebox(SNAME("close_bg_highlight")); + Ref<Texture2D> cb = get_theme_icon(SNAME("close")); + + p_x += get_theme_constant(SNAME("hseparation")); + + Rect2 cb_rect; + cb_rect.size = style->get_minimum_size() + cb->get_size(); + cb_rect.position.x = p_x; + cb_rect.position.y = p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - (cb_rect.size.y)) / 2; + + if (!tab.disabled && cb_hover == p_index) { + if (cb_pressing) { + get_theme_stylebox(SNAME("close_bg_pressed"))->draw(ci, cb_rect); + } else { + style->draw(ci, cb_rect); + } + } + + cb->draw(ci, Point2i(p_x + style->get_margin(SIDE_LEFT), cb_rect.position.y + style->get_margin(SIDE_TOP))); + p_x += cb->get_width(); + tabs.write[p_index].cb_rect = cb_rect; } } void TabBar::set_tab_count(int p_count) { ERR_FAIL_COND(p_count < 0); tabs.resize(p_count); + _update_cache(); update(); notify_property_list_changed(); } @@ -560,6 +516,7 @@ void TabBar::set_tab_title(int p_tab, const String &p_title) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs.write[p_tab].text = p_title; _shape(p_tab); + _update_cache(); update(); update_minimum_size(); } @@ -588,6 +545,7 @@ void TabBar::clear_tab_opentype_features(int p_tab) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs.write[p_tab].opentype_features.clear(); _shape(p_tab); + _update_cache(); update(); } @@ -597,6 +555,7 @@ void TabBar::set_tab_opentype_feature(int p_tab, const String &p_name, int p_val if (!tabs[p_tab].opentype_features.has(tag) || (int)tabs[p_tab].opentype_features[tag] != p_value) { tabs.write[p_tab].opentype_features[tag] = p_value; _shape(p_tab); + _update_cache(); update(); } } @@ -627,6 +586,7 @@ String TabBar::get_tab_language(int p_tab) const { void TabBar::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs.write[p_tab].icon = p_icon; + _update_cache(); update(); update_minimum_size(); } @@ -698,33 +658,43 @@ void TabBar::_update_hover() { } void TabBar::_update_cache() { + if (tabs.is_empty()) { + return; + } + Ref<StyleBox> tab_disabled = get_theme_stylebox(SNAME("tab_disabled")); Ref<StyleBox> tab_unselected = get_theme_stylebox(SNAME("tab_unselected")); Ref<StyleBox> tab_selected = get_theme_stylebox(SNAME("tab_selected")); Ref<Texture2D> incr = get_theme_icon(SNAME("increment")); Ref<Texture2D> decr = get_theme_icon(SNAME("decrement")); - int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width(); + + int limit = get_size().width; + int limit_minus_buttons = limit - incr->get_width() - decr->get_width(); int w = 0; int mw = 0; int size_fixed = 0; int count_resize = 0; + for (int i = 0; i < tabs.size(); i++) { - tabs.write[i].ofs_cache = mw; + tabs.write[i].ofs_cache = 0; tabs.write[i].size_cache = get_tab_width(i); tabs.write[i].size_text = Math::ceil(tabs[i].text_buf->get_size().x); tabs.write[i].text_buf->set_width(-1); mw += tabs[i].size_cache; + if (tabs[i].size_cache <= min_width || i == current) { size_fixed += tabs[i].size_cache; } else { count_resize++; } } + int m_width = min_width; if (count_resize > 0) { m_width = MAX((limit_minus_buttons - size_fixed) / count_resize, min_width); } + for (int i = offset; i < tabs.size(); i++) { Ref<StyleBox> sb; if (tabs[i].disabled) { @@ -734,11 +704,13 @@ void TabBar::_update_cache() { } else { sb = tab_unselected; } + int lsize = tabs[i].size_cache; int slen = tabs[i].size_text; if (min_width > 0 && mw > limit_minus_buttons && i != current) { if (lsize > m_width) { slen = m_width - (sb->get_margin(SIDE_LEFT) + sb->get_margin(SIDE_RIGHT)); + if (tabs[i].icon.is_valid()) { slen -= tabs[i].icon->get_width(); slen -= get_theme_constant(SNAME("hseparation")); @@ -748,15 +720,52 @@ void TabBar::_update_cache() { slen -= cb->get_width(); slen -= get_theme_constant(SNAME("hseparation")); } + slen = MAX(slen, 1); lsize = m_width; } } + tabs.write[i].ofs_cache = w; tabs.write[i].size_cache = lsize; tabs.write[i].size_text = slen; tabs.write[i].text_buf->set_width(slen); + w += lsize; + max_drawn_tab = i; + + // Check if all tabs would fit inside the area. + if (i > offset && (w > limit || (offset > 0 && w > limit_minus_buttons))) { + w -= get_tab_width(i); + max_drawn_tab -= 1; + + while (w > limit_minus_buttons && max_drawn_tab > offset) { + w -= get_tab_width(max_drawn_tab); + max_drawn_tab -= 1; + } + + break; + } + } + + missing_right = max_drawn_tab < tabs.size() - 1; + buttons_visible = offset > 0 || missing_right; + + if (tab_alignment == ALIGNMENT_LEFT) { + return; + } else if (tab_alignment == ALIGNMENT_CENTER) { + w = ((buttons_visible ? limit_minus_buttons : limit) - w) / 2; + } else if (tab_alignment == ALIGNMENT_RIGHT) { + w = (buttons_visible ? limit_minus_buttons : limit) - w; + } + + if (w < 0) { + w = 0; + } + + for (int i = offset; i <= max_drawn_tab; i++) { + tabs.write[i].ofs_cache = w; + w += tabs.write[i].size_cache; } } @@ -916,10 +925,10 @@ void TabBar::drop_data(const Point2 &p_point, const Variant &p_data) { set_current_tab(hover_now); emit_signal(SNAME("tab_changed"), hover_now); _update_cache(); + update(); } } } - update(); } int TabBar::get_tab_idx_at_point(const Point2 &p_point) const { @@ -937,6 +946,7 @@ int TabBar::get_tab_idx_at_point(const Point2 &p_point) const { void TabBar::set_tab_alignment(AlignmentMode p_alignment) { ERR_FAIL_INDEX(p_alignment, ALIGNMENT_MAX); tab_alignment = p_alignment; + _update_cache(); update(); } @@ -949,6 +959,7 @@ void TabBar::set_clip_tabs(bool p_clip_tabs) { return; } clip_tabs = p_clip_tabs; + _update_cache(); update(); update_minimum_size(); } @@ -1017,64 +1028,73 @@ int TabBar::get_tab_width(int p_idx) const { } void TabBar::_ensure_no_over_offset() { - if (!is_inside_tree()) { + if (!is_inside_tree() || !buttons_visible) { return; } Ref<Texture2D> incr = get_theme_icon(SNAME("increment")); Ref<Texture2D> decr = get_theme_icon(SNAME("decrement")); - - int limit = get_size().width; int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width(); + int prev_offset = offset; + + int total_w = tabs[max_drawn_tab].ofs_cache + tabs[max_drawn_tab].size_cache - tabs[offset].ofs_cache; while (offset > 0) { - int total_w = 0; - for (int i = offset - 1; i < tabs.size(); i++) { - total_w += tabs[i].size_cache; - } + total_w += tabs[offset - 1].size_cache; - if ((buttons_visible && total_w < limit_minus_buttons) || total_w < limit) { // For the last tab, we accept if the tab covers the buttons. + if (total_w < limit_minus_buttons) { offset--; - update(); } else { break; } } -} -void TabBar::ensure_tab_visible(int p_idx) { - if (!is_inside_tree()) { - return; + if (prev_offset != offset) { + _update_cache(); + update(); } +} - if (tabs.size() == 0) { +void TabBar::ensure_tab_visible(int p_idx) { + if (!is_inside_tree() || !buttons_visible) { return; } ERR_FAIL_INDEX(p_idx, tabs.size()); - if (p_idx == offset) { + if (p_idx >= offset && p_idx <= max_drawn_tab) { return; } + if (p_idx < offset) { offset = p_idx; + _update_cache(); update(); + return; } - int prev_offset = offset; Ref<Texture2D> incr = get_theme_icon(SNAME("increment")); Ref<Texture2D> decr = get_theme_icon(SNAME("decrement")); - int limit = get_size().width; int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width(); - for (int i = offset; i <= p_idx; i++) { - int total_w = tabs[i].ofs_cache + tabs[i].size_cache; - if (total_w > limit || (buttons_visible && total_w > limit_minus_buttons)) { + int total_w = tabs[max_drawn_tab].ofs_cache - tabs[offset].ofs_cache; + for (int i = max_drawn_tab; i <= p_idx; i++) { + total_w += tabs[i].size_cache; + } + + int prev_offset = offset; + + for (int i = offset; i < p_idx; i++) { + if (total_w > limit_minus_buttons) { + total_w -= tabs[i].size_cache; offset++; + } else { + break; } } if (prev_offset != offset) { + _update_cache(); update(); } } @@ -1091,6 +1111,7 @@ Rect2 TabBar::get_tab_rect(int p_tab) const { void TabBar::set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy) { ERR_FAIL_INDEX(p_policy, CLOSE_BUTTON_MAX); cb_displaypolicy = p_policy; + _update_cache(); update(); } diff --git a/scene/gui/tab_bar.h b/scene/gui/tab_bar.h index 1741481b40..d0055ae4d2 100644 --- a/scene/gui/tab_bar.h +++ b/scene/gui/tab_bar.h @@ -113,6 +113,7 @@ private: void _on_mouse_exited(); void _shape(int p_tab); + void _draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, int p_index, float p_x); protected: virtual void gui_input(const Ref<InputEvent> &p_event) override; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 8df77daafb..17f2ed1db5 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1244,7 +1244,7 @@ void TextEdit::_notification(int p_what) { } // Carets. - int caret_width = Math::round(1 * get_theme_default_base_scale()); + const int caret_width = get_theme_constant(SNAME("caret_width")) * get_theme_default_base_scale(); if (!clipped && caret.line == line && line_wrap_index == caret_wrap_index) { caret.draw_pos.y = ofs_y + ldata->get_line_descent(line_wrap_index); diff --git a/scene/gui/view_panner.cpp b/scene/gui/view_panner.cpp new file mode 100644 index 0000000000..ba5e8d4a17 --- /dev/null +++ b/scene/gui/view_panner.cpp @@ -0,0 +1,142 @@ +/*************************************************************************/ +/* view_panner.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "view_panner.h" + +#include "core/input/input.h" +#include "core/os/keyboard.h" + +bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect) { + Ref<InputEventMouseButton> mb = p_event; + if (mb.is_valid()) { + // Alt modifier is unused, so ignore such events. + if (mb->is_alt_pressed()) { + return false; + } + + Vector2i scroll_vec = Vector2((mb->get_button_index() == MouseButton::WHEEL_RIGHT) - (mb->get_button_index() == MouseButton::WHEEL_LEFT), (mb->get_button_index() == MouseButton::WHEEL_DOWN) - (mb->get_button_index() == MouseButton::WHEEL_UP)); + if (scroll_vec != Vector2()) { + if (control_scheme == SCROLL_PANS) { + if (mb->is_ctrl_pressed()) { + scroll_vec.y *= mb->get_factor(); + callback_helper(zoom_callback, scroll_vec, mb->get_position()); + return true; + } else { + Vector2 panning; + if (mb->is_shift_pressed()) { + panning.x += mb->get_factor() * scroll_vec.y; + panning.y += mb->get_factor() * scroll_vec.x; + } else { + panning.y += mb->get_factor() * scroll_vec.y; + panning.x += mb->get_factor() * scroll_vec.x; + } + callback_helper(scroll_callback, panning); + return true; + } + } else { + if (mb->is_ctrl_pressed()) { + Vector2 panning; + if (mb->is_shift_pressed()) { + panning.x += mb->get_factor() * scroll_vec.y; + panning.y += mb->get_factor() * scroll_vec.x; + } else { + panning.y += mb->get_factor() * scroll_vec.y; + panning.x += mb->get_factor() * scroll_vec.x; + } + callback_helper(scroll_callback, panning); + return true; + } else if (!mb->is_shift_pressed()) { + scroll_vec.y *= mb->get_factor(); + callback_helper(zoom_callback, scroll_vec, mb->get_position()); + return true; + } + } + } + + if (mb->get_button_index() == MouseButton::MIDDLE || (mb->get_button_index() == MouseButton::RIGHT && !disable_rmb) || (mb->get_button_index() == MouseButton::LEFT && (Input::get_singleton()->is_key_pressed(Key::SPACE) || (is_dragging && !mb->is_pressed())))) { + if (mb->is_pressed()) { + is_dragging = true; + } else { + is_dragging = false; + } + return true; + } + } + + Ref<InputEventMouseMotion> mm = p_event; + if (mm.is_valid()) { + if (is_dragging) { + if (p_canvas_rect != Rect2()) { + callback_helper(pan_callback, Input::get_singleton()->warp_mouse_motion(mm, p_canvas_rect)); + } else { + callback_helper(pan_callback, mm->get_relative()); + } + return true; + } + } + + return false; +} + +void ViewPanner::callback_helper(Callable p_callback, Vector2 p_arg1, Vector2 p_arg2) { + if (p_callback == zoom_callback) { + const Variant **argptr = (const Variant **)alloca(sizeof(Variant *) * 2); + Variant var1 = p_arg1; + argptr[0] = &var1; + Variant var2 = p_arg2; + argptr[1] = &var2; + + Variant result; + Callable::CallError ce; + p_callback.call(argptr, 2, result, ce); + } else { + const Variant **argptr = (const Variant **)alloca(sizeof(Variant *)); + Variant var = p_arg1; + argptr[0] = &var; + + Variant result; + Callable::CallError ce; + p_callback.call(argptr, 1, result, ce); + } +} + +void ViewPanner::set_callbacks(Callable p_scroll_callback, Callable p_pan_callback, Callable p_zoom_callback) { + scroll_callback = p_scroll_callback; + pan_callback = p_pan_callback; + zoom_callback = p_zoom_callback; +} + +void ViewPanner::set_control_scheme(ControlScheme p_scheme) { + control_scheme = p_scheme; +} + +void ViewPanner::set_disable_rmb(bool p_disable) { + disable_rmb = p_disable; +} diff --git a/drivers/gles3/rasterizer_platforms.h b/scene/gui/view_panner.h index 97a205e90d..0a92cb3dfd 100644 --- a/drivers/gles3/rasterizer_platforms.h +++ b/scene/gui/view_panner.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rasterizer_platforms.h */ +/* view_panner.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,21 +28,41 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RASTERIZER_PLATFORMS_H -#define RASTERIZER_PLATFORMS_H +#ifndef VIEW_PANNER_H +#define VIEW_PANNER_H -///////////////////////////////////////////////////// -// override for intellisense .. ONLY FOR DEVELOPMENT -//#ifndef X11_ENABLED -//#define X11_ENABLED -//#endif -//#define GLES3_BACKEND_ENABLED -///////////////////////////////////////////////////// +#include "core/object/ref_counted.h" -#if defined(GLES3_ENABLED) || defined(GLES_ENABLED) +class InputEvent; -#define GLES3_BACKEND_ENABLED +class ViewPanner : public RefCounted { + GDCLASS(ViewPanner, RefCounted); -#endif // defined(GLES3_ENABLED) || defined(GLES_ENABLED) +public: + enum ControlScheme { + SCROLL_ZOOMS, + SCROLL_PANS, + }; -#endif // RASTERIZER_PLATFORMS_H +private: + bool is_dragging = false; + bool disable_rmb = false; + + Callable scroll_callback; + Callable pan_callback; + Callable zoom_callback; + + void callback_helper(Callable p_callback, Vector2 p_arg1, Vector2 p_arg2 = Vector2()); + ControlScheme control_scheme = SCROLL_ZOOMS; + +public: + void set_callbacks(Callable p_scroll_callback, Callable p_pan_callback, Callable p_zoom_callback); + void set_control_scheme(ControlScheme p_scheme); + void set_disable_rmb(bool p_disable); + + bool is_panning() const { return is_dragging; } + + bool gui_input(const Ref<InputEvent> &p_ev, Rect2 p_canvas_rect = Rect2()); +}; + +#endif // VIEW_PANNER_H diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index c80665cf2e..59d933fa1d 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -99,34 +99,31 @@ void CanvasItem::_propagate_visibility_changed(bool p_visible) { _unblock(); } -void CanvasItem::show() { - if (visible) { +void CanvasItem::set_visible(bool p_visible) { + if (visible == p_visible) { return; } - visible = true; - RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, true); + visible = p_visible; + RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, p_visible); if (!is_inside_tree()) { return; } - _propagate_visibility_changed(true); + _propagate_visibility_changed(p_visible); } -void CanvasItem::hide() { - if (!visible) { - return; - } - - visible = false; - RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, false); +void CanvasItem::show() { + set_visible(true); +} - if (!is_inside_tree()) { - return; - } +void CanvasItem::hide() { + set_visible(false); +} - _propagate_visibility_changed(false); +bool CanvasItem::is_visible() const { + return visible; } CanvasItem *CanvasItem::current_item_drawn = nullptr; @@ -348,24 +345,12 @@ void CanvasItem::_notification(int p_what) { } } -void CanvasItem::set_visible(bool p_visible) { - if (p_visible) { - show(); - } else { - hide(); - } -} - void CanvasItem::_window_visibility_changed() { if (visible) { _propagate_visibility_changed(window->is_visible()); } } -bool CanvasItem::is_visible() const { - return visible; -} - void CanvasItem::update() { if (!is_inside_tree()) { return; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 93c7eb43a1..61cd834867 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -407,6 +407,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("minimum_character_width", "LineEdit", 4); theme->set_constant("outline_size", "LineEdit", 0); + theme->set_constant("caret_width", "LineEdit", 1); theme->set_icon("clear", "LineEdit", make_icon(line_edit_clear_png)); @@ -451,6 +452,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("line_spacing", "TextEdit", 4 * scale); theme->set_constant("outline_size", "TextEdit", 0); + theme->set_constant("caret_width", "TextEdit", 1); // CodeEdit @@ -770,8 +772,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const tc_sb->set_default_margin(SIDE_TOP, 8 * scale); theme->set_stylebox("tab_selected", "TabContainer", sb_expand(make_stylebox(tab_current_png, 4, 4, 4, 1, 16, 4, 16, 4), 2, 2, 2, 2)); - theme->set_stylebox("tab_unselected", "TabContainer", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); - theme->set_stylebox("tab_disabled", "TabContainer", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); + theme->set_stylebox("tab_unselected", "TabContainer", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 0)); + theme->set_stylebox("tab_disabled", "TabContainer", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 0)); theme->set_stylebox("panel", "TabContainer", tc_sb); theme->set_icon("increment", "TabContainer", make_icon(scroll_button_right_png)); @@ -795,9 +797,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // TabBar - theme->set_stylebox("tab_selected", "TabBar", sb_expand(make_stylebox(tab_current_png, 4, 3, 4, 1, 16, 3, 16, 2), 2, 2, 2, 2)); - theme->set_stylebox("tab_unselected", "TabBar", sb_expand(make_stylebox(tab_behind_png, 5, 4, 5, 1, 16, 5, 16, 2), 3, 3, 3, 3)); - theme->set_stylebox("tab_disabled", "TabBar", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); + theme->set_stylebox("tab_selected", "TabBar", sb_expand(make_stylebox(tab_current_png, 4, 4, 4, 1, 16, 4, 16, 4), 2, 2, 2, 2)); + theme->set_stylebox("tab_unselected", "TabBar", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 0)); + theme->set_stylebox("tab_disabled", "TabBar", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 0)); theme->set_stylebox("close_bg_pressed", "TabBar", make_stylebox(button_pressed_png, 4, 4, 4, 4)); theme->set_stylebox("close_bg_highlight", "TabBar", make_stylebox(button_normal_png, 4, 4, 4, 4)); diff --git a/scene/resources/default_theme/tab_current.png b/scene/resources/default_theme/tab_current.png Binary files differindex d5641e917a..ce2b9b0925 100644 --- a/scene/resources/default_theme/tab_current.png +++ b/scene/resources/default_theme/tab_current.png diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index 57ff9a5325..1cec50eab4 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -395,7 +395,7 @@ static const unsigned char tab_container_bg_png[] = { }; static const unsigned char tab_current_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x99, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x3d, 0x48, 0x5b, 0x58, 0x66, 0x5b, 0x57, 0x65, 0x57, 0x54, 0x62, 0x55, 0x53, 0x62, 0x4a, 0x46, 0x52, 0x46, 0x41, 0x4e, 0x45, 0x41, 0x4d, 0x55, 0x52, 0x60, 0x44, 0x41, 0x4c, 0x53, 0x50, 0x5e, 0x43, 0x40, 0x4b, 0x52, 0x4e, 0x5d, 0x41, 0x3e, 0x4a, 0x4f, 0x4d, 0x5a, 0x3f, 0x3d, 0x48, 0x4e, 0x4b, 0x59, 0x3e, 0x3c, 0x47, 0x4d, 0x4a, 0x58, 0x3d, 0x3b, 0x46, 0x4b, 0x49, 0x54, 0x3c, 0x3a, 0x44, 0x4b, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x3b, 0x39, 0x42, 0x3b, 0x38, 0x43, 0x3b, 0x38, 0x42, 0x3a, 0x37, 0x41, 0x39, 0x37, 0x41, 0x3a, 0x38, 0x41, 0x39, 0x36, 0x3f, 0x38, 0x36, 0x3f, 0x39, 0x36, 0x40, 0x38, 0x36, 0x40, 0x37, 0x35, 0x3e, 0x37, 0x34, 0x3e, 0x36, 0x35, 0x3d, 0xd7, 0x41, 0xa4, 0x19, 0x0, 0x0, 0x0, 0x11, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xa3, 0x31, 0x6b, 0xc2, 0x0, 0x0, 0x0, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x55, 0xca, 0x85, 0xd, 0xc0, 0x40, 0x14, 0xc3, 0x50, 0x27, 0xf7, 0xd5, 0xfd, 0xd7, 0x2d, 0xa6, 0x4c, 0x16, 0x3f, 0x59, 0xe8, 0x8, 0xc8, 0x91, 0xd4, 0x5d, 0x92, 0xa3, 0xa1, 0x76, 0xb1, 0xd8, 0xcb, 0x92, 0x41, 0x1b, 0xb8, 0xe9, 0x2, 0xcf, 0xd2, 0x7e, 0xc4, 0x9c, 0x2d, 0xed, 0x3c, 0xc4, 0x95, 0xa3, 0x3f, 0xb0, 0x3, 0x7f, 0xa0, 0xe0, 0xb, 0x50, 0xe4, 0xb, 0xa1, 0xf2, 0x87, 0x38, 0x31, 0x4f, 0x4e, 0xa, 0x30, 0x22, 0x58, 0x33, 0x81, 0x1d, 0x4a, 0x44, 0x5a, 0xec, 0x8c, 0x27, 0x34, 0x10, 0x58, 0xf1, 0xf8, 0x39, 0xe0, 0x60, 0x56, 0x63, 0x63, 0x30, 0x69, 0xf8, 0x3c, 0xb4, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x1, 0x71, 0x69, 0x43, 0x43, 0x50, 0x69, 0x63, 0x63, 0x0, 0x0, 0x28, 0x91, 0x75, 0x91, 0x3d, 0x4b, 0xc3, 0x50, 0x14, 0x86, 0xdf, 0xb6, 0x8a, 0xa2, 0x91, 0xe, 0x15, 0x11, 0x71, 0xc8, 0x50, 0xc5, 0xa1, 0x85, 0xa2, 0x20, 0x8e, 0x5a, 0x87, 0x2e, 0x45, 0x4a, 0xad, 0x60, 0xd5, 0x25, 0xb9, 0x4d, 0x5a, 0x21, 0x49, 0xc3, 0x4d, 0x8a, 0x14, 0x57, 0xc1, 0xc5, 0xa1, 0xe0, 0x20, 0xba, 0xf8, 0x35, 0xf8, 0xf, 0x74, 0x15, 0x5c, 0x15, 0x4, 0x41, 0x11, 0x44, 0x9c, 0xfc, 0x1, 0x7e, 0x2d, 0x52, 0xe2, 0xb9, 0x4d, 0xa1, 0x45, 0xda, 0x13, 0x6e, 0xce, 0xc3, 0x7b, 0xcf, 0x7b, 0xb8, 0xf7, 0x5c, 0x20, 0x98, 0x36, 0x98, 0xe9, 0xf4, 0x24, 0x0, 0xd3, 0x72, 0x79, 0x36, 0x95, 0x94, 0x57, 0xf3, 0x6b, 0x72, 0xdf, 0x3b, 0x2, 0x90, 0x30, 0x82, 0x8, 0x24, 0x85, 0x39, 0xf6, 0x42, 0x26, 0x93, 0x46, 0xd7, 0xf8, 0x79, 0xa4, 0x6a, 0x8a, 0x87, 0xb8, 0xe8, 0xd5, 0xbd, 0xae, 0x63, 0xc, 0x16, 0x34, 0x87, 0x1, 0x81, 0x7e, 0xe2, 0x59, 0x66, 0x73, 0x97, 0x78, 0x9e, 0x38, 0xbd, 0xe5, 0xda, 0x82, 0xf7, 0x88, 0x87, 0x59, 0x49, 0x29, 0x10, 0x9f, 0x10, 0xc7, 0x38, 0x1d, 0x90, 0xf8, 0x56, 0xe8, 0xaa, 0xcf, 0x6f, 0x82, 0x8b, 0x3e, 0x7f, 0x9, 0xe6, 0xb9, 0xec, 0x22, 0x10, 0x14, 0x3d, 0xe5, 0x62, 0x1b, 0xab, 0x6d, 0xcc, 0x4a, 0xdc, 0x24, 0x9e, 0x22, 0x8e, 0x9a, 0x46, 0x85, 0x35, 0xcf, 0x23, 0x6e, 0x22, 0x69, 0xd6, 0xca, 0x32, 0xe5, 0x31, 0x5a, 0xe3, 0x70, 0x90, 0x45, 0xa, 0x49, 0xc8, 0x50, 0x51, 0xc1, 0x26, 0xc, 0xb8, 0x88, 0x53, 0xb6, 0x68, 0x66, 0x9d, 0x7d, 0x89, 0x86, 0x6f, 0x9, 0x65, 0xf2, 0x30, 0xfa, 0xdb, 0xa8, 0x82, 0x93, 0xa3, 0x88, 0x12, 0x79, 0x63, 0xa4, 0x56, 0xa8, 0xab, 0x46, 0x59, 0x27, 0x5d, 0xa3, 0xcf, 0x40, 0x55, 0xcc, 0xfd, 0xff, 0x3c, 0x1d, 0x7d, 0x66, 0xda, 0xef, 0x2e, 0x25, 0x81, 0xde, 0x57, 0xcf, 0xfb, 0x9c, 0x0, 0xfa, 0xf6, 0x81, 0x7a, 0xcd, 0xf3, 0x7e, 0x4f, 0x3d, 0xaf, 0x7e, 0x6, 0x84, 0x5e, 0x80, 0x6b, 0xab, 0xe5, 0x2f, 0xd3, 0x9c, 0xe6, 0xbe, 0x49, 0xaf, 0xb5, 0xb4, 0xe8, 0x31, 0x10, 0xde, 0x1, 0x2e, 0x6f, 0x5a, 0x9a, 0x7a, 0x0, 0x5c, 0xed, 0x2, 0xa3, 0xcf, 0xb6, 0xc2, 0x95, 0x86, 0x14, 0xa2, 0x15, 0xd4, 0x75, 0xe0, 0xe3, 0x2, 0x18, 0xca, 0x3, 0x91, 0x7b, 0x60, 0x60, 0xdd, 0x9f, 0x55, 0x73, 0x1f, 0xe7, 0x4f, 0x40, 0x6e, 0x9b, 0x9e, 0xe8, 0xe, 0x38, 0x3c, 0x2, 0x26, 0xa9, 0x3e, 0xbc, 0xf1, 0x7, 0x9c, 0x2f, 0x67, 0xdc, 0x46, 0x9a, 0x3c, 0x4e, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x12, 0x0, 0x0, 0xb, 0x12, 0x1, 0xd2, 0xdd, 0x7e, 0xfc, 0x0, 0x0, 0x1, 0x27, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0x9d, 0x93, 0x41, 0x4e, 0xc3, 0x30, 0x10, 0x45, 0xc7, 0xee, 0xd0, 0x82, 0x58, 0xd4, 0x6b, 0x28, 0xdc, 0x4, 0xc1, 0x92, 0x35, 0xa7, 0xe9, 0x11, 0x38, 0xd, 0x6b, 0x36, 0x2c, 0x10, 0x3b, 0xee, 0xc0, 0x6, 0x95, 0x1d, 0x6a, 0x83, 0x54, 0x4, 0xad, 0x1d, 0xf, 0x7f, 0xf0, 0x4, 0xb5, 0x52, 0x11, 0xe, 0x3f, 0x7a, 0x91, 0x93, 0x7c, 0xff, 0x78, 0x9c, 0x89, 0x23, 0x22, 0x6, 0x43, 0x30, 0x2, 0xfb, 0x36, 0x1e, 0x0, 0x4f, 0xdb, 0xca, 0xa0, 0x5, 0x6b, 0xf0, 0x9, 0x56, 0x3a, 0xee, 0x26, 0x1f, 0x82, 0x0, 0xc6, 0x36, 0xd6, 0x30, 0x67, 0xa8, 0xc4, 0xd0, 0x49, 0xef, 0xe0, 0xd, 0x34, 0x64, 0x6f, 0x57, 0x73, 0x38, 0x3f, 0xbb, 0xbc, 0x9a, 0x1c, 0x9f, 0x4e, 0x53, 0x4a, 0x21, 0xb, 0xed, 0x94, 0x47, 0x1c, 0x33, 0x37, 0xb3, 0x97, 0xe7, 0xeb, 0xfb, 0x87, 0xdb, 0x1b, 0xdc, 0x4a, 0x6c, 0xcb, 0x1e, 0x4f, 0x8e, 0x4e, 0xa6, 0x8b, 0xf9, 0x6b, 0x48, 0x31, 0xe1, 0x55, 0xbb, 0x13, 0x1c, 0xe, 0xde, 0xe3, 0xa0, 0x5e, 0x5c, 0xde, 0x81, 0xe5, 0x4f, 0x9, 0xeb, 0x18, 0x43, 0x8c, 0xf1, 0xd7, 0xc9, 0xa5, 0xe, 0x21, 0xf5, 0xa8, 0xd7, 0x4a, 0x1d, 0xb2, 0x6d, 0xd8, 0x28, 0xe7, 0x4c, 0x59, 0x32, 0xfd, 0x25, 0xd, 0x51, 0xaf, 0x95, 0x3e, 0x60, 0xdb, 0x6d, 0x27, 0x59, 0x1f, 0x8, 0xd5, 0x48, 0x8a, 0x4f, 0x37, 0xd8, 0x73, 0x57, 0x5e, 0x2b, 0x6d, 0xd5, 0xa, 0x54, 0xea, 0xed, 0xbe, 0x10, 0x6f, 0xa6, 0x8a, 0xf4, 0x5a, 0x1, 0x6d, 0x6, 0x88, 0x4e, 0xae, 0xe, 0x28, 0xbe, 0xef, 0x93, 0xb7, 0xe, 0x43, 0x68, 0xa2, 0x5a, 0x99, 0x57, 0x3, 0xb2, 0xb7, 0xf6, 0x5c, 0x51, 0xa6, 0x7a, 0x15, 0xaf, 0x76, 0x65, 0xcb, 0x5b, 0x8d, 0xe2, 0x1c, 0xf5, 0x15, 0xdb, 0x8f, 0xd1, 0xfc, 0x23, 0xe0, 0xa0, 0x6b, 0x24, 0xfd, 0xbb, 0x96, 0xa5, 0xd7, 0x7b, 0x5, 0xcc, 0xc1, 0x87, 0xee, 0xc1, 0x2, 0x3c, 0x81, 0xb, 0xa1, 0xba, 0x43, 0xbd, 0xe0, 0x11, 0xcc, 0xbe, 0x0, 0xbe, 0xe0, 0x95, 0x8, 0xaf, 0xb2, 0x52, 0x33, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char tab_disabled_png[] = { diff --git a/scene/resources/material.h b/scene/resources/material.h index 7250544d10..57591bee2f 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -35,7 +35,6 @@ #include "core/templates/self_list.h" #include "scene/resources/shader.h" #include "scene/resources/texture.h" -#include "servers/rendering/shader_language.h" #include "servers/rendering_server.h" class Material : public Resource { diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index 75ea6a0f12..aa9682bd80 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -36,11 +36,10 @@ ///@TODO probably should change a few integers to unsigned integers... /** - @author Bastiaan Olij <mux213@gmail.com> - Base class for all the classes in this file, handles a number of code functions that are shared among all meshes. This class is set apart that it assumes a single surface is always generated for our mesh. */ + class PrimitiveMesh : public Mesh { GDCLASS(PrimitiveMesh, Mesh); diff --git a/scene/resources/separation_ray_shape_2d.cpp b/scene/resources/separation_ray_shape_2d.cpp index 5ac8d0a475..0406c91b70 100644 --- a/scene/resources/separation_ray_shape_2d.cpp +++ b/scene/resources/separation_ray_shape_2d.cpp @@ -59,15 +59,13 @@ void SeparationRayShape2D::draw(const RID &p_to_rid, const Color &p_color) { xf.rotate(target_position.angle()); xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0)); - Vector<Vector2> pts; - pts.push_back(xf.xform(Vector2(arrow_size, 0))); - pts.push_back(xf.xform(Vector2(0, 0.5 * arrow_size))); - pts.push_back(xf.xform(Vector2(0, -0.5 * arrow_size))); - - Vector<Color> cols; - for (int i = 0; i < 3; i++) { - cols.push_back(p_color); - } + Vector<Vector2> pts = { + xf.xform(Vector2(arrow_size, 0)), + xf.xform(Vector2(0, 0.5 * arrow_size)), + xf.xform(Vector2(0, -0.5 * arrow_size)) + }; + + Vector<Color> cols = { p_color, p_color, p_color }; RS::get_singleton()->canvas_item_add_primitive(p_to_rid, pts, cols, Vector<Point2>(), RID()); } diff --git a/scene/resources/separation_ray_shape_3d.cpp b/scene/resources/separation_ray_shape_3d.cpp index a059d55bbe..5aa7616589 100644 --- a/scene/resources/separation_ray_shape_3d.cpp +++ b/scene/resources/separation_ray_shape_3d.cpp @@ -33,9 +33,10 @@ #include "servers/physics_server_3d.h" Vector<Vector3> SeparationRayShape3D::get_debug_mesh_lines() const { - Vector<Vector3> points; - points.push_back(Vector3()); - points.push_back(Vector3(0, 0, get_length())); + Vector<Vector3> points = { + Vector3(), + Vector3(0, 0, get_length()) + }; return points; } diff --git a/scene/resources/skin.cpp b/scene/resources/skin.cpp index d371598cc0..54ed71999c 100644 --- a/scene/resources/skin.cpp +++ b/scene/resources/skin.cpp @@ -143,6 +143,7 @@ void Skin::_bind_methods() { ClassDB::bind_method(D_METHOD("get_bind_count"), &Skin::get_bind_count); ClassDB::bind_method(D_METHOD("add_bind", "bone", "pose"), &Skin::add_bind); + ClassDB::bind_method(D_METHOD("add_named_bind", "name", "pose"), &Skin::add_named_bind); ClassDB::bind_method(D_METHOD("set_bind_pose", "bind_index", "pose"), &Skin::set_bind_pose); ClassDB::bind_method(D_METHOD("get_bind_pose", "bind_index"), &Skin::get_bind_pose); diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index c39902739f..5afd424e03 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -521,21 +521,22 @@ inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color set_inner_corner_radius(style_rect, ring_rect, corner_radius, ring_corner_radius); // Corner radius center points. - Vector<Point2> outer_points; - outer_points.push_back(ring_rect.position + Vector2(ring_corner_radius[0], ring_corner_radius[0])); //tl - outer_points.push_back(Point2(ring_rect.position.x + ring_rect.size.x - ring_corner_radius[1], ring_rect.position.y + ring_corner_radius[1])); //tr - outer_points.push_back(ring_rect.position + ring_rect.size - Vector2(ring_corner_radius[2], ring_corner_radius[2])); //br - outer_points.push_back(Point2(ring_rect.position.x + ring_corner_radius[3], ring_rect.position.y + ring_rect.size.y - ring_corner_radius[3])); //bl + Vector<Point2> outer_points = { + ring_rect.position + Vector2(ring_corner_radius[0], ring_corner_radius[0]), //tl + Point2(ring_rect.position.x + ring_rect.size.x - ring_corner_radius[1], ring_rect.position.y + ring_corner_radius[1]), //tr + ring_rect.position + ring_rect.size - Vector2(ring_corner_radius[2], ring_corner_radius[2]), //br + Point2(ring_rect.position.x + ring_corner_radius[3], ring_rect.position.y + ring_rect.size.y - ring_corner_radius[3]) //bl + }; real_t inner_corner_radius[4]; set_inner_corner_radius(style_rect, inner_rect, corner_radius, inner_corner_radius); - Vector<Point2> inner_points; - inner_points.push_back(inner_rect.position + Vector2(inner_corner_radius[0], inner_corner_radius[0])); //tl - inner_points.push_back(Point2(inner_rect.position.x + inner_rect.size.x - inner_corner_radius[1], inner_rect.position.y + inner_corner_radius[1])); //tr - inner_points.push_back(inner_rect.position + inner_rect.size - Vector2(inner_corner_radius[2], inner_corner_radius[2])); //br - inner_points.push_back(Point2(inner_rect.position.x + inner_corner_radius[3], inner_rect.position.y + inner_rect.size.y - inner_corner_radius[3])); //bl - + Vector<Point2> inner_points = { + inner_rect.position + Vector2(inner_corner_radius[0], inner_corner_radius[0]), //tl + Point2(inner_rect.position.x + inner_rect.size.x - inner_corner_radius[1], inner_rect.position.y + inner_corner_radius[1]), //tr + inner_rect.position + inner_rect.size - Vector2(inner_corner_radius[2], inner_corner_radius[2]), //br + Point2(inner_rect.position.x + inner_corner_radius[3], inner_rect.position.y + inner_rect.size.y - inner_corner_radius[3]) //bl + }; // Calculate the vertices. for (int corner_index = 0; corner_index < 4; corner_index++) { for (int detail = 0; detail <= adapted_corner_detail; detail++) { diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp index 18e46e5476..c3bdef7b01 100644 --- a/scene/resources/text_paragraph.cpp +++ b/scene/resources/text_paragraph.cpp @@ -561,7 +561,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo if (h_offset > 0) { // Draw dropcap. Vector2 dc_off = ofs; - if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_RTL) { + if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_RTL) { if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) { dc_off.x += width - h_offset; } else { @@ -579,7 +579,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo ofs.x = p_pos.x; ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top; if (i <= dropcap_lines) { - if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_LTR) { + if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) { ofs.x -= h_offset; } l_width -= h_offset; @@ -588,7 +588,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo ofs.y = p_pos.y; ofs.x += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top; if (i <= dropcap_lines) { - if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_LTR) { + if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) { ofs.x -= h_offset; } l_width -= h_offset; @@ -598,7 +598,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo if (width > 0) { switch (alignment) { case HORIZONTAL_ALIGNMENT_FILL: - if (TS->shaped_text_get_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) { + if (TS->shaped_text_get_inferred_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) { if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x += l_width - line_width; } else { @@ -655,7 +655,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli if (h_offset > 0) { // Draw dropcap. Vector2 dc_off = ofs; - if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_RTL) { + if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_RTL) { if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) { dc_off.x += width - h_offset; } else { @@ -671,7 +671,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli ofs.x = p_pos.x; ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top; if (i <= dropcap_lines) { - if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_LTR) { + if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) { ofs.x -= h_offset; } l_width -= h_offset; @@ -680,7 +680,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli ofs.y = p_pos.y; ofs.x += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top; if (i <= dropcap_lines) { - if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_LTR) { + if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) { ofs.x -= h_offset; } l_width -= h_offset; @@ -690,7 +690,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli if (width > 0) { switch (alignment) { case HORIZONTAL_ALIGNMENT_FILL: - if (TS->shaped_text_get_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) { + if (TS->shaped_text_get_inferred_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) { if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x += l_width - length; } else { @@ -772,7 +772,7 @@ void TextParagraph::draw_dropcap(RID p_canvas, const Vector2 &p_pos, const Color if (h_offset > 0) { // Draw dropcap. - if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_RTL) { + if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_RTL) { if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x += width - h_offset; } else { @@ -794,7 +794,7 @@ void TextParagraph::draw_dropcap_outline(RID p_canvas, const Vector2 &p_pos, int if (h_offset > 0) { // Draw dropcap. - if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_RTL) { + if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_RTL) { if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x += width - h_offset; } else { diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 44a7af75b9..ddb9cc7440 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -1765,11 +1765,14 @@ Vector<Point2> TileSet::_get_square_corner_or_side_terrain_bit_polygon(Vector2i break; } bit_rect.position *= Vector2(p_size) / 6.0; - Vector<Vector2> polygon; - polygon.push_back(bit_rect.position); - polygon.push_back(Vector2(bit_rect.get_end().x, bit_rect.position.y)); - polygon.push_back(bit_rect.get_end()); - polygon.push_back(Vector2(bit_rect.position.x, bit_rect.get_end().y)); + + Vector<Vector2> polygon = { + bit_rect.position, + Vector2(bit_rect.get_end().x, bit_rect.position.y), + bit_rect.get_end(), + Vector2(bit_rect.position.x, bit_rect.get_end().y) + }; + return polygon; } @@ -1984,25 +1987,26 @@ Vector<Point2> TileSet::_get_isometric_side_terrain_bit_polygon(Vector2i p_size, } Vector<Point2> TileSet::_get_half_offset_corner_or_side_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) { - Vector<Vector2> point_list; - point_list.push_back(Vector2(3, (3.0 * (1.0 - p_overlap * 2.0)) / 2.0)); - point_list.push_back(Vector2(3, 3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(2, 3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0))); - point_list.push_back(Vector2(1, 3.0 - p_overlap * 2.0)); - point_list.push_back(Vector2(0, 3)); - point_list.push_back(Vector2(-1, 3.0 - p_overlap * 2.0)); - point_list.push_back(Vector2(-2, 3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0))); - point_list.push_back(Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(-3, (3.0 * (1.0 - p_overlap * 2.0)) / 2.0)); - point_list.push_back(Vector2(-3, -(3.0 * (1.0 - p_overlap * 2.0)) / 2.0)); - point_list.push_back(Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(-2, -3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0))); - point_list.push_back(Vector2(-1, -(3.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(0, -3)); - point_list.push_back(Vector2(1, -(3.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(2, -3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0))); - point_list.push_back(Vector2(3, -3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(3, -(3.0 * (1.0 - p_overlap * 2.0)) / 2.0)); + Vector<Vector2> point_list = { + Vector2(3, (3.0 * (1.0 - p_overlap * 2.0)) / 2.0), + Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)), + Vector2(2, 3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)), + Vector2(1, 3.0 - p_overlap * 2.0), + Vector2(0, 3), + Vector2(-1, 3.0 - p_overlap * 2.0), + Vector2(-2, 3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)), + Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)), + Vector2(-3, (3.0 * (1.0 - p_overlap * 2.0)) / 2.0), + Vector2(-3, -(3.0 * (1.0 - p_overlap * 2.0)) / 2.0), + Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)), + Vector2(-2, -3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)), + Vector2(-1, -(3.0 - p_overlap * 2.0)), + Vector2(0, -3), + Vector2(1, -(3.0 - p_overlap * 2.0)), + Vector2(2, -3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)), + Vector2(3, -3.0 * (1.0 - p_overlap * 2.0)), + Vector2(3, -(3.0 * (1.0 - p_overlap * 2.0)) / 2.0) + }; Vector2 unit = Vector2(p_size) / 6.0; for (int i = 0; i < point_list.size(); i++) { @@ -2144,19 +2148,20 @@ Vector<Point2> TileSet::_get_half_offset_corner_or_side_terrain_bit_polygon(Vect } Vector<Point2> TileSet::_get_half_offset_corner_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) { - Vector<Vector2> point_list; - point_list.push_back(Vector2(3, 0)); - point_list.push_back(Vector2(3, 3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(1.5, (3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0)); - point_list.push_back(Vector2(0, 3)); - point_list.push_back(Vector2(-1.5, (3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0)); - point_list.push_back(Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(-3, 0)); - point_list.push_back(Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(-1.5, -(3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0)); - point_list.push_back(Vector2(0, -3)); - point_list.push_back(Vector2(1.5, -(3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0)); - point_list.push_back(Vector2(3, -3.0 * (1.0 - p_overlap * 2.0))); + Vector<Vector2> point_list = { + Vector2(3, 0), + Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)), + Vector2(1.5, (3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0), + Vector2(0, 3), + Vector2(-1.5, (3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0), + Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)), + Vector2(-3, 0), + Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)), + Vector2(-1.5, -(3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0), + Vector2(0, -3), + Vector2(1.5, -(3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0), + Vector2(3, -3.0 * (1.0 - p_overlap * 2.0)) + }; Vector2 unit = Vector2(p_size) / 6.0; for (int i = 0; i < point_list.size(); i++) { @@ -2250,13 +2255,14 @@ Vector<Point2> TileSet::_get_half_offset_corner_terrain_bit_polygon(Vector2i p_s } Vector<Point2> TileSet::_get_half_offset_side_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) { - Vector<Vector2> point_list; - point_list.push_back(Vector2(3, 3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(0, 3)); - point_list.push_back(Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(0, -3)); - point_list.push_back(Vector2(3, -3.0 * (1.0 - p_overlap * 2.0))); + Vector<Vector2> point_list = { + Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)), + Vector2(0, 3), + Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)), + Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)), + Vector2(0, -3), + Vector2(3, -3.0 * (1.0 - p_overlap * 2.0)) + }; Vector2 unit = Vector2(p_size) / 6.0; for (int i = 0; i < point_list.size(); i++) { diff --git a/scene/resources/world_boundary_shape_3d.cpp b/scene/resources/world_boundary_shape_3d.cpp index efa288511d..09d41e8291 100644 --- a/scene/resources/world_boundary_shape_3d.cpp +++ b/scene/resources/world_boundary_shape_3d.cpp @@ -34,7 +34,6 @@ Vector<Vector3> WorldBoundaryShape3D::get_debug_mesh_lines() const { Plane p = get_plane(); - Vector<Vector3> points; Vector3 n1 = p.get_any_perpendicular_normal(); Vector3 n2 = p.normal.cross(n1).normalized(); @@ -46,16 +45,18 @@ Vector<Vector3> WorldBoundaryShape3D::get_debug_mesh_lines() const { p.normal * p.d + n1 * -10.0 + n2 * 10.0, }; - points.push_back(pface[0]); - points.push_back(pface[1]); - points.push_back(pface[1]); - points.push_back(pface[2]); - points.push_back(pface[2]); - points.push_back(pface[3]); - points.push_back(pface[3]); - points.push_back(pface[0]); - points.push_back(p.normal * p.d); - points.push_back(p.normal * p.d + p.normal * 3); + Vector<Vector3> points = { + pface[0], + pface[1], + pface[1], + pface[2], + pface[2], + pface[3], + pface[3], + pface[0], + p.normal * p.d, + p.normal * p.d + p.normal * 3 + }; return points; } diff --git a/servers/audio/effects/eq.h b/servers/audio/effects/eq.h index 74280ee22e..d6293bf875 100644 --- a/servers/audio/effects/eq.h +++ b/servers/audio/effects/eq.h @@ -28,18 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// Author: reduzio@gmail.com (C) 2006 - #ifndef EQ_FILTER_H #define EQ_FILTER_H #include "core/templates/vector.h" #include "core/typedefs.h" -/** -@author Juan Linietsky -*/ - class EQ { public: enum Preset { @@ -105,4 +99,4 @@ inline void EQ::BandProcess::process_one(float &p_data) { history.b2 = history.b1; } -#endif +#endif // EQ_FILTER_H diff --git a/servers/audio/effects/reverb.h b/servers/audio/effects/reverb.h index fa06d262a3..ff59ab8d82 100644 --- a/servers/audio/effects/reverb.h +++ b/servers/audio/effects/reverb.h @@ -28,8 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// Author: Juan Linietsky <reduzio@gmail.com>, (C) 2006 - #ifndef REVERB_H #define REVERB_H @@ -120,4 +118,4 @@ public: ~Reverb(); }; -#endif +#endif // REVERB_H diff --git a/servers/camera/camera_feed.h b/servers/camera/camera_feed.h index ea66c5f947..e86605a89b 100644 --- a/servers/camera/camera_feed.h +++ b/servers/camera/camera_feed.h @@ -37,8 +37,6 @@ #include "servers/rendering_server.h" /** - @author Bastiaan Olij <mux213@gmail.com> - The camera server is a singleton object that gives access to the various camera feeds that can be used as the background for our environment. **/ @@ -111,4 +109,4 @@ public: VARIANT_ENUM_CAST(CameraFeed::FeedDataType); VARIANT_ENUM_CAST(CameraFeed::FeedPosition); -#endif /* !CAMERA_FEED_H */ +#endif // CAMERA_FEED_H diff --git a/servers/camera_server.h b/servers/camera_server.h index 893fdba912..b70938c34f 100644 --- a/servers/camera_server.h +++ b/servers/camera_server.h @@ -38,8 +38,6 @@ #include "core/variant/variant.h" /** - @author Bastiaan Olij <mux213@gmail.com> - The camera server is a singleton object that gives access to the various camera feeds that can be used as the background for our environment. **/ @@ -113,4 +111,4 @@ public: VARIANT_ENUM_CAST(CameraServer::FeedImage); -#endif /* CAMERA_SERVER_H */ +#endif // CAMERA_SERVER_H diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp index 53190d7681..ee196673a3 100644 --- a/servers/navigation_server_2d.cpp +++ b/servers/navigation_server_2d.cpp @@ -29,14 +29,11 @@ /*************************************************************************/ #include "servers/navigation_server_2d.h" + #include "core/math/transform_2d.h" #include "core/math/transform_3d.h" #include "servers/navigation_server_3d.h" -/** - @author AndreaCatania -*/ - NavigationServer2D *NavigationServer2D::singleton = nullptr; #define FORWARD_0_C(FUNC_NAME) \ diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h index 2dd718e09c..7350eeb5b1 100644 --- a/servers/navigation_server_2d.h +++ b/servers/navigation_server_2d.h @@ -28,12 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -/** - @author AndreaCatania -*/ - -#ifndef NAVIGATION_2D_SERVER_H -#define NAVIGATION_2D_SERVER_H +#ifndef NAVIGATION_SERVER_2D_H +#define NAVIGATION_SERVER_2D_H #include "core/object/class_db.h" #include "core/templates/rid.h" @@ -171,4 +167,4 @@ public: virtual ~NavigationServer2D(); }; -#endif +#endif // NAVIGATION_SERVER_2D_H diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index d78e58bea0..d18777869a 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -28,10 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -/** - @author AndreaCatania -*/ - #include "navigation_server_3d.h" NavigationServer3D *NavigationServer3D::singleton = nullptr; diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index f711e4e0e5..0a75b07931 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -28,12 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -/** - @author AndreaCatania -*/ - -#ifndef NAVIGATION_SERVER_H -#define NAVIGATION_SERVER_H +#ifndef NAVIGATION_SERVER_3D_H +#define NAVIGATION_SERVER_3D_H #include "core/object/class_db.h" #include "core/templates/rid.h" @@ -205,4 +201,4 @@ public: static NavigationServer3D *new_default_server(); }; -#endif +#endif // NAVIGATION_SERVER_3D_H diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index 02af3c6eb9..f5e2cbcd6c 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -261,6 +261,10 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2 if (ci->clip) { if (p_canvas_clip != nullptr) { ci->final_clip_rect = p_canvas_clip->final_clip_rect.intersection(global_rect); + if (ci->final_clip_rect == Rect2()) { + // Clip rects do not intersect, so don't draw this item. + return; + } } else { ci->final_clip_rect = global_rect; } diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index 4a19519995..4ab50782df 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -446,7 +446,7 @@ void EffectsRD::set_color(RID p_dest_texture, const Color &p_color, const Rect2i } void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst) { - ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use the compute version of the gaussian blur with the mobile renderer."); + ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the gaussian blur with the mobile renderer."); memset(©.push_constant, 0, sizeof(CopyPushConstant)); 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 cd7b2622ab..36604073cc 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -1795,12 +1795,14 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform { RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, false, rp_uniform_set); //regular forward for now - Vector<Color> clear; - clear.push_back(Color(0, 0, 0, 0)); - clear.push_back(Color(0, 0, 0, 0)); - clear.push_back(Color(0, 0, 0, 0)); - clear.push_back(Color(0, 0, 0, 0)); - clear.push_back(Color(0, 0, 0, 0)); + Vector<Color> clear = { + Color(0, 0, 0, 0), + Color(0, 0, 0, 0), + Color(0, 0, 0, 0), + Color(0, 0, 0, 0), + Color(0, 0, 0, 0) + }; + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region); _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count); RD::get_singleton()->draw_list_end(); @@ -1839,12 +1841,13 @@ void RenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p { RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, false, rp_uniform_set, true); //regular forward for now - Vector<Color> clear; - clear.push_back(Color(0, 0, 0, 0)); - clear.push_back(Color(0, 0, 0, 0)); - clear.push_back(Color(0, 0, 0, 0)); - clear.push_back(Color(0, 0, 0, 0)); - clear.push_back(Color(0, 0, 0, 0)); + Vector<Color> clear = { + Color(0, 0, 0, 0), + Color(0, 0, 0, 0), + Color(0, 0, 0, 0), + Color(0, 0, 0, 0), + Color(0, 0, 0, 0) + }; RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region); const int uv_offset_count = 9; @@ -1901,11 +1904,12 @@ void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i Vector3 half_extents = p_bounds.size * 0.5; Vector3 center = p_bounds.position + half_extents; - Vector<RID> sbs; - sbs.push_back(p_albedo_texture); - sbs.push_back(p_emission_texture); - sbs.push_back(p_emission_aniso_texture); - sbs.push_back(p_geom_facing_texture); + Vector<RID> sbs = { + p_albedo_texture, + p_emission_texture, + p_emission_aniso_texture, + p_geom_facing_texture + }; //print_line("re-render " + p_from + " - " + p_size + " bounds " + p_bounds); for (int i = 0; i < 3; i++) { 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 942e78e1ff..a27ea75017 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 @@ -48,7 +48,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { return; //just invalid, but no error } - ShaderCompilerRD::GeneratedCode gen_code; + ShaderCompiler::GeneratedCode gen_code; int blend_mode = BLEND_MODE_MIX; int depth_testi = DEPTH_TEST_ENABLED; @@ -79,10 +79,10 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { int depth_drawi = DEPTH_DRAW_OPAQUE; - ShaderCompilerRD::IdentifierActions actions; - actions.entry_point_stages["vertex"] = ShaderCompilerRD::STAGE_VERTEX; - actions.entry_point_stages["fragment"] = ShaderCompilerRD::STAGE_FRAGMENT; - actions.entry_point_stages["light"] = ShaderCompilerRD::STAGE_FRAGMENT; + ShaderCompiler::IdentifierActions actions; + actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX; + actions.entry_point_stages["fragment"] = ShaderCompiler::STAGE_FRAGMENT; + actions.entry_point_stages["light"] = ShaderCompiler::STAGE_FRAGMENT; actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_mode, BLEND_MODE_ADD); actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MIX); @@ -157,10 +157,10 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { } print_line("\n**uniforms:\n" + gen_code.uniforms); - print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX]); - print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT]); + print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]); + print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]); #endif - shader_singleton->shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX], gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT], gen_code.defines); + shader_singleton->shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines); ERR_FAIL_COND(!shader_singleton->shader.version_is_valid(version)); ubo_size = gen_code.uniform_total_size; @@ -510,7 +510,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin { //shader compiler - ShaderCompilerRD::DefaultIdentifierActions actions; + ShaderCompiler::DefaultIdentifierActions actions; actions.renames["WORLD_MATRIX"] = "world_matrix"; actions.renames["WORLD_NORMAL_MATRIX"] = "world_normal_matrix"; 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 98448ce846..8e7bbad63e 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 @@ -129,7 +129,7 @@ public: String path; Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; - Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms; + Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size; @@ -208,7 +208,7 @@ public: } SceneForwardClusteredShaderRD shader; - ShaderCompilerRD compiler; + ShaderCompiler compiler; RID default_shader; RID default_material; 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 8b2a60c487..b9c51f5461 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -1002,12 +1002,13 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c { RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set, 0); //regular forward for now - Vector<Color> clear; - clear.push_back(Color(0, 0, 0, 0)); - clear.push_back(Color(0, 0, 0, 0)); - clear.push_back(Color(0, 0, 0, 0)); - clear.push_back(Color(0, 0, 0, 0)); - clear.push_back(Color(0, 0, 0, 0)); + Vector<Color> clear = { + Color(0, 0, 0, 0), + Color(0, 0, 0, 0), + Color(0, 0, 0, 0), + Color(0, 0, 0, 0), + Color(0, 0, 0, 0) + }; RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region); _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count); RD::get_singleton()->draw_list_end(); @@ -1043,12 +1044,14 @@ void RenderForwardMobile::_render_uv2(const PagedArray<GeometryInstance *> &p_in { RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set, true, 0); //regular forward for now - Vector<Color> clear; - clear.push_back(Color(0, 0, 0, 0)); - clear.push_back(Color(0, 0, 0, 0)); - clear.push_back(Color(0, 0, 0, 0)); - clear.push_back(Color(0, 0, 0, 0)); - clear.push_back(Color(0, 0, 0, 0)); + Vector<Color> clear = { + Color(0, 0, 0, 0), + Color(0, 0, 0, 0), + Color(0, 0, 0, 0), + Color(0, 0, 0, 0), + Color(0, 0, 0, 0) + }; + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region); const int uv_offset_count = 9; 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 b0cc26340d..1613a307ec 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 @@ -51,7 +51,7 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { return; //just invalid, but no error } - ShaderCompilerRD::GeneratedCode gen_code; + ShaderCompiler::GeneratedCode gen_code; int blend_mode = BLEND_MODE_MIX; int depth_testi = DEPTH_TEST_ENABLED; @@ -81,10 +81,10 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { int depth_drawi = DEPTH_DRAW_OPAQUE; - ShaderCompilerRD::IdentifierActions actions; - actions.entry_point_stages["vertex"] = ShaderCompilerRD::STAGE_VERTEX; - actions.entry_point_stages["fragment"] = ShaderCompilerRD::STAGE_FRAGMENT; - actions.entry_point_stages["light"] = ShaderCompilerRD::STAGE_FRAGMENT; + ShaderCompiler::IdentifierActions actions; + actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX; + actions.entry_point_stages["fragment"] = ShaderCompiler::STAGE_FRAGMENT; + actions.entry_point_stages["light"] = ShaderCompiler::STAGE_FRAGMENT; actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_mode, BLEND_MODE_ADD); actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MIX); @@ -159,11 +159,11 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { } print_line("\n**uniforms:\n" + gen_code.uniforms); - print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX]); - print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT]); + print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]); + print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]); #endif - shader_singleton->shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX], gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT], gen_code.defines); + shader_singleton->shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines); ERR_FAIL_COND(!shader_singleton->shader.version_is_valid(version)); ubo_size = gen_code.uniform_total_size; @@ -498,7 +498,7 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p { //shader compiler - ShaderCompilerRD::DefaultIdentifierActions actions; + ShaderCompiler::DefaultIdentifierActions actions; actions.renames["WORLD_MATRIX"] = "world_matrix"; actions.renames["WORLD_NORMAL_MATRIX"] = "world_normal_matrix"; 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 770f9bde3b..c136afd9f3 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 @@ -105,7 +105,7 @@ public: String path; Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; - Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms; + Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size; @@ -184,7 +184,7 @@ public: } SceneForwardMobileShaderRD shader; - ShaderCompilerRD compiler; + ShaderCompiler compiler; RID default_shader; RID default_material; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index da75c70cbb..7e188926e0 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1957,15 +1957,15 @@ void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) { return; //just invalid, but no error } - ShaderCompilerRD::GeneratedCode gen_code; + ShaderCompiler::GeneratedCode gen_code; int blend_mode = BLEND_MODE_MIX; uses_screen_texture = false; - ShaderCompilerRD::IdentifierActions actions; - actions.entry_point_stages["vertex"] = ShaderCompilerRD::STAGE_VERTEX; - actions.entry_point_stages["fragment"] = ShaderCompilerRD::STAGE_FRAGMENT; - actions.entry_point_stages["light"] = ShaderCompilerRD::STAGE_FRAGMENT; + ShaderCompiler::IdentifierActions actions; + actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX; + actions.entry_point_stages["fragment"] = ShaderCompiler::STAGE_FRAGMENT; + actions.entry_point_stages["light"] = ShaderCompiler::STAGE_FRAGMENT; actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_mode, BLEND_MODE_ADD); actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MIX); @@ -2002,7 +2002,7 @@ void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) { print_line("\n**fragment_code:\n" + gen_code.fragment); print_line("\n**light_code:\n" + gen_code.light); #endif - canvas_singleton->shader.canvas_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX], gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT], gen_code.defines); + canvas_singleton->shader.canvas_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines); ERR_FAIL_COND(!canvas_singleton->shader.canvas_shader.version_is_valid(version)); ubo_size = gen_code.uniform_total_size; @@ -2359,7 +2359,7 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) { { //shader compiler - ShaderCompilerRD::DefaultIdentifierActions actions; + ShaderCompiler::DefaultIdentifierActions actions; actions.renames["VERTEX"] = "vertex"; actions.renames["LIGHT_VERTEX"] = "light_vertex"; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index c9544a5239..b409264c9a 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -35,10 +35,10 @@ #include "servers/rendering/renderer_compositor.h" #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" #include "servers/rendering/renderer_rd/renderer_storage_rd.h" -#include "servers/rendering/renderer_rd/shader_compiler_rd.h" #include "servers/rendering/renderer_rd/shaders/canvas.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl.gen.h" #include "servers/rendering/rendering_device.h" +#include "servers/rendering/shader_compiler.h" class RendererCanvasRenderRD : public RendererCanvasRender { RendererStorageRD *storage; @@ -148,7 +148,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { RID default_skeleton_uniform_buffer; RID default_skeleton_texture_buffer; - ShaderCompilerRD compiler; + ShaderCompiler compiler; } shader; struct ShaderData : public RendererStorageRD::ShaderData { @@ -167,7 +167,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { String path; Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; - Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms; + Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 77843ceee5..a499cedd2c 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -3837,9 +3837,9 @@ void RendererSceneRenderRD::FogShaderData::set_code(const String &p_code) { return; //just invalid, but no error } - ShaderCompilerRD::GeneratedCode gen_code; - ShaderCompilerRD::IdentifierActions actions; - actions.entry_point_stages["fog"] = ShaderCompilerRD::STAGE_COMPUTE; + ShaderCompiler::GeneratedCode gen_code; + ShaderCompiler::IdentifierActions actions; + actions.entry_point_stages["fog"] = ShaderCompiler::STAGE_COMPUTE; uses_time = false; @@ -3856,7 +3856,7 @@ void RendererSceneRenderRD::FogShaderData::set_code(const String &p_code) { version = scene_singleton->volumetric_fog.shader.version_create(); } - scene_singleton->volumetric_fog.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_COMPUTE], gen_code.defines); + scene_singleton->volumetric_fog.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_COMPUTE], gen_code.defines); ERR_FAIL_COND(!scene_singleton->volumetric_fog.shader.version_is_valid(version)); ubo_size = gen_code.uniform_total_size; @@ -5653,7 +5653,7 @@ void RendererSceneRenderRD::init() { } { - ShaderCompilerRD::DefaultIdentifierActions actions; + ShaderCompiler::DefaultIdentifierActions actions; actions.renames["TIME"] = "scene_params.time"; actions.renames["PI"] = _MKSTR(Math_PI); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index b8a088d041..6432ca99f0 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -834,7 +834,7 @@ private: float transform[16]; }; - ShaderCompilerRD compiler; + ShaderCompiler compiler; VolumetricFogShaderRD shader; FogPushConstant push_constant; RID volume_ubo; @@ -917,7 +917,7 @@ private: RID pipeline; Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; - Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms; + Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size; diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index 8fb3c607fa..f0419b7907 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -50,9 +50,9 @@ void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) { return; //just invalid, but no error } - ShaderCompilerRD::GeneratedCode gen_code; - ShaderCompilerRD::IdentifierActions actions; - actions.entry_point_stages["sky"] = ShaderCompilerRD::STAGE_FRAGMENT; + ShaderCompiler::GeneratedCode gen_code; + ShaderCompiler::IdentifierActions actions; + actions.entry_point_stages["sky"] = ShaderCompiler::STAGE_FRAGMENT; uses_time = false; uses_half_res = false; @@ -112,7 +112,7 @@ void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) { print_line("\n**light_code:\n" + gen_code.light); #endif - scene_singleton->sky.sky_shader.shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX], gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT], gen_code.defines); + scene_singleton->sky.sky_shader.shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines); ERR_FAIL_COND(!scene_singleton->sky.sky_shader.shader.version_is_valid(version)); ubo_size = gen_code.uniform_total_size; @@ -807,7 +807,7 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) { storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_SKY, _create_sky_material_funcs); { - ShaderCompilerRD::DefaultIdentifierActions actions; + ShaderCompiler::DefaultIdentifierActions actions; actions.renames["COLOR"] = "color"; actions.renames["ALPHA"] = "alpha"; diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h index 1359cdec67..46d376e667 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h @@ -111,7 +111,7 @@ private: PipelineCacheRD pipelines[SKY_VERSION_MAX]; Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; - Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms; + Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size; @@ -220,7 +220,7 @@ public: struct SkyShader { SkyShaderRD shader; - ShaderCompilerRD compiler; + ShaderCompiler compiler; RID default_shader; RID default_material; diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index 932cdcaea8..eafb4e0182 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -2612,7 +2612,7 @@ void RendererStorageRD::MaterialData::update_uniform_buffer(const Map<StringName } if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; //instance uniforms don't appear in the bufferr + continue; //instance uniforms don't appear in the buffer } if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) { @@ -2710,7 +2710,7 @@ RendererStorageRD::MaterialData::~MaterialData() { } } -void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) { +void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) { RendererStorageRD *singleton = (RendererStorageRD *)RendererStorage::base_singleton; #ifdef TOOLS_ENABLED Texture *roughness_detect_texture = nullptr; @@ -2936,7 +2936,7 @@ void RendererStorageRD::MaterialData::free_parameters_uniform_set(RID p_uniform_ } } -bool RendererStorageRD::MaterialData::update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier) { +bool RendererStorageRD::MaterialData::update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier) { if ((uint32_t)ubo_data.size() != p_ubo_size) { p_uniform_dirty = true; if (uniform_buffer.is_valid()) { @@ -5812,10 +5812,10 @@ void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) { return; //just invalid, but no error } - ShaderCompilerRD::GeneratedCode gen_code; - ShaderCompilerRD::IdentifierActions actions; - actions.entry_point_stages["start"] = ShaderCompilerRD::STAGE_COMPUTE; - actions.entry_point_stages["process"] = ShaderCompilerRD::STAGE_COMPUTE; + ShaderCompiler::GeneratedCode gen_code; + ShaderCompiler::IdentifierActions actions; + actions.entry_point_stages["start"] = ShaderCompiler::STAGE_COMPUTE; + actions.entry_point_stages["process"] = ShaderCompiler::STAGE_COMPUTE; /* uses_time = false; @@ -5837,7 +5837,7 @@ void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) { version = base_singleton->particles_shader.shader.version_create(); } - base_singleton->particles_shader.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_COMPUTE], gen_code.defines); + base_singleton->particles_shader.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_COMPUTE], gen_code.defines); ERR_FAIL_COND(!base_singleton->particles_shader.shader.version_is_valid(version)); ubo_size = gen_code.uniform_total_size; @@ -10016,7 +10016,7 @@ RendererStorageRD::RendererStorageRD() { material_set_data_request_function(RendererStorageRD::SHADER_TYPE_PARTICLES, _create_particles_material_funcs); { - ShaderCompilerRD::DefaultIdentifierActions actions; + ShaderCompiler::DefaultIdentifierActions actions; actions.renames["COLOR"] = "PARTICLE.color"; actions.renames["VELOCITY"] = "PARTICLE.velocity"; diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h index cca61008c7..8c04274c3f 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.h +++ b/servers/rendering/renderer_rd/renderer_storage_rd.h @@ -36,7 +36,6 @@ #include "core/templates/rid_owner.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering/renderer_rd/effects_rd.h" -#include "servers/rendering/renderer_rd/shader_compiler_rd.h" #include "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/particles.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/particles_copy.glsl.gen.h" @@ -44,6 +43,7 @@ #include "servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl.gen.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" +#include "servers/rendering/shader_compiler.h" class RendererStorageRD : public RendererStorage { public: static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) { @@ -152,7 +152,7 @@ public: struct MaterialData { void update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color); - void update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color); + void update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color); virtual void set_render_priority(int p_priority) = 0; virtual void set_next_pass(RID p_pass) = 0; @@ -160,7 +160,7 @@ public: virtual ~MaterialData(); //to be used internally by update_parameters, in the most common configuration of material parameters - bool update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier = RD::BARRIER_MASK_ALL); + bool update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier = RD::BARRIER_MASK_ALL); void free_parameters_uniform_set(RID p_uniform_set); private: @@ -826,7 +826,7 @@ private: }; ParticlesShaderRD shader; - ShaderCompilerRD compiler; + ShaderCompiler compiler; RID default_shader; RID default_material; @@ -877,7 +877,7 @@ private: //PipelineCacheRD pipelines[SKY_VERSION_MAX]; Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; - Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms; + Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size; diff --git a/servers/rendering/renderer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h index 06f78ab193..8e57f0d9af 100644 --- a/servers/rendering/renderer_rd/shader_rd.h +++ b/servers/rendering/renderer_rd/shader_rd.h @@ -40,11 +40,6 @@ #include "core/variant/variant.h" #include "servers/rendering_server.h" -#include <stdio.h> -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - class ShaderRD { //versions CharString general_defines; @@ -173,4 +168,4 @@ public: virtual ~ShaderRD(); }; -#endif +#endif // SHADER_RD_H diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index 608b76b108..97f7e0a6e6 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -575,7 +575,7 @@ void main() { uint instance_index = instance_index_interp; - //lay out everything, whathever is unused is optimized away anyway + //lay out everything, whatever is unused is optimized away anyway vec3 vertex = vertex_interp; vec3 view = -normalize(vertex_interp); vec3 albedo = vec3(1.0); diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index 9e3732fd2b..4d6a3b5864 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -581,7 +581,7 @@ void main() { discard; #endif - //lay out everything, whathever is unused is optimized away anyway + //lay out everything, whatever is unused is optimized away anyway vec3 vertex = vertex_interp; vec3 view = -normalize(vertex_interp); vec3 albedo = vec3(1.0); diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl index 4d9fa85a74..f6ec249b5e 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl @@ -102,7 +102,7 @@ dispatch_data; struct ProcessVoxel { uint position; // xyz 7 bit packed, extra 11 bits for neighbors. - uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neibhbours + uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neighbours uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbours uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbours //total neighbours: 26 @@ -135,7 +135,7 @@ dispatch_data; struct ProcessVoxel { uint position; // xyz 7 bit packed, extra 11 bits for neighbors. - uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neibhbours + uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neighbours uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbours uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbours //total neighbours: 26 diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/shader_compiler.cpp index 38ac00176f..b0629de2f0 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/shader_compiler.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* shader_compiler_rd.cpp */ +/* shader_compiler.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "shader_compiler_rd.h" +#include "shader_compiler.h" #include "core/config/project_settings.h" #include "core/os/os.h" -#include "renderer_storage_rd.h" +#include "servers/rendering/shader_types.h" #include "servers/rendering_server.h" #define SL ShaderLanguage @@ -277,7 +277,7 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo } } -String ShaderCompilerRD::_get_sampler_name(ShaderLanguage::TextureFilter p_filter, ShaderLanguage::TextureRepeat p_repeat) { +String ShaderCompiler::_get_sampler_name(ShaderLanguage::TextureFilter p_filter, ShaderLanguage::TextureRepeat p_repeat) { if (p_filter == ShaderLanguage::FILTER_DEFAULT) { ERR_FAIL_COND_V(actions.default_filter == ShaderLanguage::FILTER_DEFAULT, String()); p_filter = actions.default_filter; @@ -289,7 +289,7 @@ String ShaderCompilerRD::_get_sampler_name(ShaderLanguage::TextureFilter p_filte return actions.sampler_array_name + "[" + itos(p_filter + (p_repeat == ShaderLanguage::REPEAT_ENABLE ? ShaderLanguage::FILTER_DEFAULT : 0)) + "]"; } -void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added) { +void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added) { int fidx = -1; for (int i = 0; i < p_node->functions.size(); i++) { @@ -435,7 +435,7 @@ static String _get_global_variable_from_type_and_index(const String &p_buffer, c } } -String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope) { +String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope) { String code; switch (p_node->type) { @@ -692,17 +692,36 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge vcode += _prestr(varying.precision, ShaderLanguage::is_float_type(varying.type)); vcode += _typestr(varying.type); vcode += " " + _mkid(varying_name); + uint32_t inc = 1U; + if (varying.array_size > 0) { + inc = (uint32_t)varying.array_size; + vcode += "["; vcode += itos(varying.array_size); vcode += "]"; } + + switch (varying.type) { + case SL::TYPE_MAT2: + inc *= 2U; + break; + case SL::TYPE_MAT3: + inc *= 3U; + break; + case SL::TYPE_MAT4: + inc *= 4U; + break; + default: + break; + } + vcode += ";\n"; r_gen_code.stage_globals[STAGE_VERTEX] += "layout(location=" + itos(index) + ") " + interp_mode + "out " + vcode; r_gen_code.stage_globals[STAGE_FRAGMENT] += "layout(location=" + itos(index) + ") " + interp_mode + "in " + vcode; - index++; + index += inc; } if (var_frag_to_light.size() > 0) { @@ -1332,12 +1351,12 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge return code; } -ShaderLanguage::DataType ShaderCompilerRD::_get_variable_type(const StringName &p_type) { - RS::GlobalVariableType gvt = ((RendererStorageRD *)(RendererStorage::base_singleton))->global_variable_get_type_internal(p_type); - return RS::global_variable_type_get_shader_datatype(gvt); +ShaderLanguage::DataType ShaderCompiler::_get_variable_type(const StringName &p_type) { + RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_type); + return (ShaderLanguage::DataType)RS::global_variable_type_get_shader_datatype(gvt); } -Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) { +Error ShaderCompiler::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) { SL::ShaderCompileInfo info; info.functions = ShaderTypes::get_singleton()->get_functions(p_mode); info.render_modes = ShaderTypes::get_singleton()->get_modes(p_mode); @@ -1383,7 +1402,7 @@ Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, Ide return OK; } -void ShaderCompilerRD::initialize(DefaultIdentifierActions p_actions) { +void ShaderCompiler::initialize(DefaultIdentifierActions p_actions) { actions = p_actions; time_name = "TIME"; @@ -1405,7 +1424,7 @@ void ShaderCompilerRD::initialize(DefaultIdentifierActions p_actions) { texture_functions.insert("texelFetch"); } -ShaderCompilerRD::ShaderCompilerRD() { +ShaderCompiler::ShaderCompiler() { #if 0 /** SPATIAL SHADER **/ diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.h b/servers/rendering/shader_compiler.h index 5670d881f6..8f0ee664ac 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.h +++ b/servers/rendering/shader_compiler.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* shader_compiler_rd.h */ +/* shader_compiler.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,15 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SHADER_COMPILER_RD_H -#define SHADER_COMPILER_RD_H +#ifndef SHADER_COMPILER_H +#define SHADER_COMPILER_H #include "core/templates/pair.h" #include "servers/rendering/shader_language.h" -#include "servers/rendering/shader_types.h" #include "servers/rendering_server.h" -class ShaderCompilerRD { +class ShaderCompiler { public: enum Stage { STAGE_VERTEX, @@ -127,7 +126,7 @@ public: Error compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code); void initialize(DefaultIdentifierActions p_actions); - ShaderCompilerRD(); + ShaderCompiler(); }; -#endif // SHADERCOMPILERRD_H +#endif // SHADER_COMPILER_H diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index adbcdedacc..a03ba9a02a 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -7563,17 +7563,13 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } - tk = _get_token(); + StringName shader_type_identifier; + _get_completable_identifier(nullptr, COMPLETION_SHADER_TYPE, shader_type_identifier); - if (tk.type != TK_IDENTIFIER) { + if (shader_type_identifier == StringName()) { _set_error("Expected identifier after 'shader_type', indicating type of shader. Valid types are: " + _get_shader_type_list(p_shader_types)); return ERR_PARSE_ERROR; } - - String shader_type_identifier; - - shader_type_identifier = tk.text; - if (!p_shader_types.has(shader_type_identifier)) { _set_error("Invalid shader type. Valid types are: " + _get_shader_type_list(p_shader_types)); return ERR_PARSE_ERROR; @@ -8346,6 +8342,10 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } } break; + case TK_SHADER_TYPE: { + _set_error("Shader type is already defined."); + return ERR_PARSE_ERROR; + } break; default: { //function or constant variable @@ -8774,6 +8774,13 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } } + for (int i = 0; i < shader->functions.size(); i++) { + if (!shader->functions[i].callable && shader->functions[i].name == name) { + _set_error("Redefinition of '" + String(name) + "'"); + return ERR_PARSE_ERROR; + } + } + ShaderNode::Function function; function.callable = !p_functions.has(name); @@ -9260,6 +9267,13 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_ //do nothing return OK; } break; + case COMPLETION_SHADER_TYPE: { + for (const String &shader_type : p_info.shader_types) { + ScriptCodeCompletionOption option(shader_type, ScriptCodeCompletionOption::KIND_PLAIN_TEXT); + r_options->push_back(option); + } + return OK; + } break; case COMPLETION_RENDER_MODE: { for (int i = 0; i < p_info.render_modes.size(); i++) { const ModeInfo &info = p_info.render_modes[i]; @@ -9275,7 +9289,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_ if (!found) { for (int j = 0; j < info.options.size(); j++) { - ScriptCodeCompletionOption option(String(info.name) + "_" + String(info.options[j]), ScriptCodeCompletionOption::KIND_ENUM); + ScriptCodeCompletionOption option(String(info.name) + "_" + String(info.options[j]), ScriptCodeCompletionOption::KIND_PLAIN_TEXT); r_options->push_back(option); } } @@ -9283,7 +9297,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_ const String name = String(info.name); if (!shader->render_modes.has(name)) { - ScriptCodeCompletionOption option(name, ScriptCodeCompletionOption::KIND_ENUM); + ScriptCodeCompletionOption option(name, ScriptCodeCompletionOption::KIND_PLAIN_TEXT); r_options->push_back(option); } } @@ -9369,6 +9383,9 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_ } } + for (const KeyValue<StringName, ShaderNode::Constant> &E : shader->constants) { + matches.insert(E.key, ScriptCodeCompletionOption::KIND_CONSTANT); + } for (const KeyValue<StringName, ShaderNode::Varying> &E : shader->varyings) { matches.insert(E.key, ScriptCodeCompletionOption::KIND_VARIABLE); } diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index b9c2d4b33c..bc6dae7fa2 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -742,6 +742,7 @@ public: enum CompletionType { COMPLETION_NONE, + COMPLETION_SHADER_TYPE, COMPLETION_RENDER_MODE, COMPLETION_MAIN_FUNCTION, COMPLETION_IDENTIFIER, diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index a94f70e20f..793c6f1379 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -32,6 +32,7 @@ #include "core/config/project_settings.h" #include "servers/rendering/rendering_server_globals.h" +#include "servers/rendering/shader_language.h" RenderingServer *RenderingServer::singleton = nullptr; RenderingServer *(*RenderingServer::create_func)() = nullptr; @@ -1411,7 +1412,7 @@ Array RenderingServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_su } #endif -ShaderLanguage::DataType RenderingServer::global_variable_type_get_shader_datatype(GlobalVariableType p_type) { +int RenderingServer::global_variable_type_get_shader_datatype(GlobalVariableType p_type) { switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: return ShaderLanguage::TYPE_BOOL; diff --git a/servers/rendering_server.h b/servers/rendering_server.h index ada50292fc..5dbec04665 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -41,7 +41,6 @@ #include "servers/display_server.h" #include "servers/rendering/renderer_thread_pool.h" #include "servers/rendering/rendering_device.h" -#include "servers/rendering/shader_language.h" class RenderingServer : public Object { GDCLASS(RenderingServer, Object); @@ -1456,7 +1455,7 @@ public: virtual void global_variables_load_settings(bool p_load_textures) = 0; virtual void global_variables_clear() = 0; - static ShaderLanguage::DataType global_variable_type_get_shader_datatype(GlobalVariableType p_type); + static int global_variable_type_get_shader_datatype(GlobalVariableType p_type); /* FREE */ diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp index a51b62e730..a2195d1ddf 100644 --- a/servers/text/text_server_extension.cpp +++ b/servers/text/text_server_extension.cpp @@ -194,6 +194,7 @@ void TextServerExtension::_bind_methods() { GDVIRTUAL_BIND(_shaped_text_set_direction, "shaped", "direction"); GDVIRTUAL_BIND(_shaped_text_get_direction, "shaped"); + GDVIRTUAL_BIND(_shaped_text_get_inferred_direction, "shaped"); GDVIRTUAL_BIND(_shaped_text_set_bidi_override, "shaped", "override"); @@ -954,6 +955,14 @@ TextServer::Direction TextServerExtension::shaped_text_get_direction(RID p_shape return TextServer::Direction::DIRECTION_AUTO; } +TextServer::Direction TextServerExtension::shaped_text_get_inferred_direction(RID p_shaped) const { + int ret; + if (GDVIRTUAL_CALL(_shaped_text_get_inferred_direction, p_shaped, ret)) { + return (TextServer::Direction)ret; + } + return TextServer::Direction::DIRECTION_LTR; +} + void TextServerExtension::shaped_text_set_orientation(RID p_shaped, TextServer::Orientation p_orientation) { GDVIRTUAL_CALL(_shaped_text_set_orientation, p_shaped, p_orientation); } diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h index 9b456c2dd7..77f2ced951 100644 --- a/servers/text/text_server_extension.h +++ b/servers/text/text_server_extension.h @@ -315,8 +315,10 @@ public: virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) override; virtual Direction shaped_text_get_direction(RID p_shaped) const override; + virtual Direction shaped_text_get_inferred_direction(RID p_shaped) const override; GDVIRTUAL2(_shaped_text_set_direction, RID, Direction); GDVIRTUAL1RC(/*Direction*/ int, _shaped_text_get_direction, RID); + GDVIRTUAL1RC(/*Direction*/ int, _shaped_text_get_inferred_direction, RID); virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) override; GDVIRTUAL2(_shaped_text_set_bidi_override, RID, const Array &); diff --git a/servers/text_server.cpp b/servers/text_server.cpp index 143cda985d..0cc4358785 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -347,6 +347,7 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("shaped_text_set_direction", "shaped", "direction"), &TextServer::shaped_text_set_direction, DEFVAL(DIRECTION_AUTO)); ClassDB::bind_method(D_METHOD("shaped_text_get_direction", "shaped"), &TextServer::shaped_text_get_direction); + ClassDB::bind_method(D_METHOD("shaped_text_get_inferred_direction", "shaped"), &TextServer::shaped_text_get_inferred_direction); ClassDB::bind_method(D_METHOD("shaped_text_set_bidi_override", "shaped", "override"), &TextServer::shaped_text_set_bidi_override); @@ -1224,6 +1225,17 @@ void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_p } // Draw at the baseline. for (int i = 0; i < v_size; i++) { + if (trim_pos >= 0) { + if (rtl) { + if (i < trim_pos) { + continue; + } + } else { + if (i >= trim_pos) { + break; + } + } + } for (int j = 0; j < glyphs[i].repeat; j++) { if (p_clip_r > 0) { // Clip right / bottom. @@ -1251,17 +1263,6 @@ void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_p } } } - if (trim_pos >= 0) { - if (rtl) { - if (i < trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - continue; - } - } else { - if (i >= trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - break; - } - } - } if (glyphs[i].font_rid != RID()) { font_draw_glyph(glyphs[i].font_rid, p_canvas, glyphs[i].font_size, ofs + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, p_color); @@ -1293,7 +1294,7 @@ void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_p void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l, float p_clip_r, int p_outline_size, const Color &p_color) const { TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped); - bool rtl = (shaped_text_get_direction(p_shaped) == DIRECTION_RTL); + bool rtl = (shaped_text_get_inferred_direction(p_shaped) == DIRECTION_RTL); int ellipsis_pos = shaped_text_get_ellipsis_pos(p_shaped); int trim_pos = shaped_text_get_trim_pos(p_shaped); @@ -1319,6 +1320,17 @@ void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vect } // Draw at the baseline. for (int i = 0; i < v_size; i++) { + if (trim_pos >= 0) { + if (rtl) { + if (i < trim_pos) { + continue; + } + } else { + if (i >= trim_pos) { + break; + } + } + } for (int j = 0; j < glyphs[i].repeat; j++) { if (p_clip_r > 0) { // Clip right / bottom. @@ -1346,17 +1358,6 @@ void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vect } } } - if (trim_pos >= 0) { - if (rtl) { - if (i < trim_pos) { - continue; - } - } else { - if (i >= trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - break; - } - } - } if (glyphs[i].font_rid != RID()) { font_draw_glyph_outline(glyphs[i].font_rid, p_canvas, glyphs[i].font_size, p_outline_size, ofs + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, p_color); } diff --git a/servers/text_server.h b/servers/text_server.h index d5dccc0edb..07f0ae5045 100644 --- a/servers/text_server.h +++ b/servers/text_server.h @@ -370,6 +370,7 @@ public: virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) = 0; virtual Direction shaped_text_get_direction(RID p_shaped) const = 0; + virtual Direction shaped_text_get_inferred_direction(RID p_shaped) const = 0; virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) = 0; diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h index 03563026c8..aee98f8fee 100644 --- a/servers/xr/xr_interface.h +++ b/servers/xr/xr_interface.h @@ -39,8 +39,6 @@ struct BlitToScreen; /** - @author Bastiaan Olij <mux213@gmail.com> - The XR interface is a template class on top of which we build interface to different AR, VR and tracking SDKs. The idea is that we subclass this class, implement the logic, and then instantiate a singleton of each interface when Godot starts. These instances do not initialize themselves but register themselves with the AR/VR server. @@ -138,4 +136,4 @@ VARIANT_ENUM_CAST(XRInterface::Capabilities); VARIANT_ENUM_CAST(XRInterface::TrackingStatus); VARIANT_ENUM_CAST(XRInterface::PlayAreaMode); -#endif // !XR_INTERFACE_H +#endif // XR_INTERFACE_H diff --git a/servers/xr/xr_positional_tracker.h b/servers/xr/xr_positional_tracker.h index 895bcab215..2bcbf2c018 100644 --- a/servers/xr/xr_positional_tracker.h +++ b/servers/xr/xr_positional_tracker.h @@ -37,8 +37,6 @@ #include "servers/xr_server.h" /** - @author Bastiaan Olij <mux213@gmail.com> - The positional tracker object as an object that represents the position and orientation of a tracked object like a controller or headset. An AR/VR Interface will registered the trackers it manages with our AR/VR server and update its position and orientation. This is where potentially additional AR/VR interfaces may be active as there are AR/VR SDKs that solely deal with positional tracking. @@ -99,4 +97,4 @@ public: VARIANT_ENUM_CAST(XRPositionalTracker::TrackerHand); -#endif +#endif // XR_POSITIONAL_TRACKER_H diff --git a/servers/xr_server.h b/servers/xr_server.h index 824a42ed31..a820634bd9 100644 --- a/servers/xr_server.h +++ b/servers/xr_server.h @@ -41,8 +41,6 @@ class XRInterface; class XRPositionalTracker; /** - @author Bastiaan Olij <mux213@gmail.com> - The XR server is a singleton object that gives access to the various objects and SDKs that are available on the system. Because there can be multiple SDKs active this is exposed as an array @@ -193,4 +191,4 @@ public: VARIANT_ENUM_CAST(XRServer::TrackerType); VARIANT_ENUM_CAST(XRServer::RotationMode); -#endif +#endif // XR_SERVER_H diff --git a/tests/core/math/test_math.cpp b/tests/core/math/test_math.cpp index 7b1f3af2b9..a24a8fde2b 100644 --- a/tests/core/math/test_math.cpp +++ b/tests/core/math/test_math.cpp @@ -308,7 +308,7 @@ public: curly_stack++; break; } else { - break; //whathever else + break; //whatever else } } diff --git a/tests/core/math/test_vector2.h b/tests/core/math/test_vector2.h new file mode 100644 index 0000000000..7dd14736e8 --- /dev/null +++ b/tests/core/math/test_vector2.h @@ -0,0 +1,366 @@ +/*************************************************************************/ +/* test_vector2.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_VECTOR2_H +#define TEST_VECTOR2_H + +#include "core/math/vector2.h" +#include "tests/test_macros.h" + +namespace TestVector2 { + +TEST_CASE("[Vector2] Angle methods") { + const Vector2 vector_x = Vector2(1, 0); + const Vector2 vector_y = Vector2(0, 1); + CHECK_MESSAGE( + Math::is_equal_approx(vector_x.angle_to(vector_y), (real_t)Math_TAU / 4), + "Vector2 angle_to should work as expected."); + CHECK_MESSAGE( + Math::is_equal_approx(vector_y.angle_to(vector_x), (real_t)-Math_TAU / 4), + "Vector2 angle_to should work as expected."); + CHECK_MESSAGE( + Math::is_equal_approx(vector_x.angle_to_point(vector_y), (real_t)Math_TAU * 3 / 8), + "Vector2 angle_to_point should work as expected."); + CHECK_MESSAGE( + Math::is_equal_approx(vector_y.angle_to_point(vector_x), (real_t)-Math_TAU / 8), + "Vector2 angle_to_point should work as expected."); +} + +TEST_CASE("[Vector2] Axis methods") { + Vector2 vector = Vector2(1.2, 3.4); + CHECK_MESSAGE( + vector.max_axis_index() == Vector2::Axis::AXIS_Y, + "Vector2 max_axis_index should work as expected."); + CHECK_MESSAGE( + vector.min_axis_index() == Vector2::Axis::AXIS_X, + "Vector2 min_axis_index should work as expected."); + CHECK_MESSAGE( + vector[vector.min_axis_index()] == (real_t)1.2, + "Vector2 array operator should work as expected."); + vector[Vector2::Axis::AXIS_Y] = 3.7; + CHECK_MESSAGE( + vector[Vector2::Axis::AXIS_Y] == (real_t)3.7, + "Vector2 array operator setter should work as expected."); +} + +TEST_CASE("[Vector2] Interpolation methods") { + const Vector2 vector1 = Vector2(1, 2); + const Vector2 vector2 = Vector2(4, 5); + CHECK_MESSAGE( + vector1.lerp(vector2, 0.5) == Vector2(2.5, 3.5), + "Vector2 lerp should work as expected."); + CHECK_MESSAGE( + vector1.lerp(vector2, 1.0 / 3.0).is_equal_approx(Vector2(2, 3)), + "Vector2 lerp should work as expected."); + CHECK_MESSAGE( + vector1.normalized().slerp(vector2.normalized(), 0.5).is_equal_approx(Vector2(0.538953602313995361, 0.84233558177947998)), + "Vector2 slerp should work as expected."); + CHECK_MESSAGE( + vector1.normalized().slerp(vector2.normalized(), 1.0 / 3.0).is_equal_approx(Vector2(0.508990883827209473, 0.860771894454956055)), + "Vector2 slerp should work as expected."); + CHECK_MESSAGE( + Vector2(5, 0).slerp(Vector2(0, 5), 0.5).is_equal_approx(Vector2(5, 5) * Math_SQRT12), + "Vector2 slerp with non-normalized values should work as expected."); + CHECK_MESSAGE( + Vector2().slerp(Vector2(), 0.5) == Vector2(), + "Vector2 slerp with both inputs as zero vectors should return a zero vector."); + CHECK_MESSAGE( + Vector2().slerp(Vector2(1, 1), 0.5) == Vector2(0.5, 0.5), + "Vector2 slerp with one input as zero should behave like a regular lerp."); + CHECK_MESSAGE( + Vector2(1, 1).slerp(Vector2(), 0.5) == Vector2(0.5, 0.5), + "Vector2 slerp with one input as zero should behave like a regular lerp."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.slerp(vector2, 0.5).length(), (real_t)4.31959610746631919), + "Vector2 slerp with different length input should return a vector with an interpolated length."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.angle_to(vector1.slerp(vector2, 0.5)) * 2, vector1.angle_to(vector2)), + "Vector2 slerp with different length input should return a vector with an interpolated angle."); + CHECK_MESSAGE( + vector1.cubic_interpolate(vector2, Vector2(), Vector2(7, 7), 0.5) == Vector2(2.375, 3.5), + "Vector2 cubic_interpolate should work as expected."); + CHECK_MESSAGE( + vector1.cubic_interpolate(vector2, Vector2(), Vector2(7, 7), 1.0 / 3.0).is_equal_approx(Vector2(1.851851940155029297, 2.962963104248046875)), + "Vector2 cubic_interpolate should work as expected."); + CHECK_MESSAGE( + Vector2(1, 0).move_toward(Vector2(10, 0), 3) == Vector2(4, 0), + "Vector2 move_toward should work as expected."); +} + +TEST_CASE("[Vector2] Length methods") { + const Vector2 vector1 = Vector2(10, 10); + const Vector2 vector2 = Vector2(20, 30); + CHECK_MESSAGE( + vector1.length_squared() == 200, + "Vector2 length_squared should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.length(), 10 * (real_t)Math_SQRT2), + "Vector2 length should work as expected."); + CHECK_MESSAGE( + vector2.length_squared() == 1300, + "Vector2 length_squared should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector2.length(), (real_t)36.05551275463989293119), + "Vector2 length should work as expected."); + CHECK_MESSAGE( + vector1.distance_squared_to(vector2) == 500, + "Vector2 distance_squared_to should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.distance_to(vector2), (real_t)22.36067977499789696409), + "Vector2 distance_to should work as expected."); +} + +TEST_CASE("[Vector2] Limiting methods") { + const Vector2 vector = Vector2(10, 10); + CHECK_MESSAGE( + vector.limit_length().is_equal_approx(Vector2(Math_SQRT12, Math_SQRT12)), + "Vector2 limit_length should work as expected."); + CHECK_MESSAGE( + vector.limit_length(5).is_equal_approx(5 * Vector2(Math_SQRT12, Math_SQRT12)), + "Vector2 limit_length should work as expected."); + + CHECK_MESSAGE( + Vector2(-5, 15).clamp(Vector2(), vector).is_equal_approx(Vector2(0, 10)), + "Vector2 clamp should work as expected."); + CHECK_MESSAGE( + vector.clamp(Vector2(0, 15), Vector2(5, 20)).is_equal_approx(Vector2(5, 15)), + "Vector2 clamp should work as expected."); +} + +TEST_CASE("[Vector2] Normalization methods") { + CHECK_MESSAGE( + Vector2(1, 0).is_normalized() == true, + "Vector2 is_normalized should return true for a normalized vector."); + CHECK_MESSAGE( + Vector2(1, 1).is_normalized() == false, + "Vector2 is_normalized should return false for a non-normalized vector."); + CHECK_MESSAGE( + Vector2(1, 0).normalized() == Vector2(1, 0), + "Vector2 normalized should return the same vector for a normalized vector."); + CHECK_MESSAGE( + Vector2(1, 1).normalized().is_equal_approx(Vector2(Math_SQRT12, Math_SQRT12)), + "Vector2 normalized should work as expected."); +} + +TEST_CASE("[Vector2] Operators") { + const Vector2 decimal1 = Vector2(2.3, 4.9); + const Vector2 decimal2 = Vector2(1.2, 3.4); + const Vector2 power1 = Vector2(0.75, 1.5); + const Vector2 power2 = Vector2(0.5, 0.125); + const Vector2 int1 = Vector2(4, 5); + const Vector2 int2 = Vector2(1, 2); + + CHECK_MESSAGE( + (decimal1 + decimal2).is_equal_approx(Vector2(3.5, 8.3)), + "Vector2 addition should behave as expected."); + CHECK_MESSAGE( + (power1 + power2) == Vector2(1.25, 1.625), + "Vector2 addition with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 + int2) == Vector2(5, 7), + "Vector2 addition with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 - decimal2).is_equal_approx(Vector2(1.1, 1.5)), + "Vector2 subtraction should behave as expected."); + CHECK_MESSAGE( + (power1 - power2) == Vector2(0.25, 1.375), + "Vector2 subtraction with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 - int2) == Vector2(3, 3), + "Vector2 subtraction with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 * decimal2).is_equal_approx(Vector2(2.76, 16.66)), + "Vector2 multiplication should behave as expected."); + CHECK_MESSAGE( + (power1 * power2) == Vector2(0.375, 0.1875), + "Vector2 multiplication with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 * int2) == Vector2(4, 10), + "Vector2 multiplication with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 / decimal2).is_equal_approx(Vector2(1.91666666666666666, 1.44117647058823529)), + "Vector2 division should behave as expected."); + CHECK_MESSAGE( + (power1 / power2) == Vector2(1.5, 12.0), + "Vector2 division with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 / int2) == Vector2(4, 2.5), + "Vector2 division with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 * 2).is_equal_approx(Vector2(4.6, 9.8)), + "Vector2 multiplication should behave as expected."); + CHECK_MESSAGE( + (power1 * 2) == Vector2(1.5, 3), + "Vector2 multiplication with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 * 2) == Vector2(8, 10), + "Vector2 multiplication with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 / 2).is_equal_approx(Vector2(1.15, 2.45)), + "Vector2 division should behave as expected."); + CHECK_MESSAGE( + (power1 / 2) == Vector2(0.375, 0.75), + "Vector2 division with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 / 2) == Vector2(2, 2.5), + "Vector2 division with integers should give exact results."); + + CHECK_MESSAGE( + ((Vector2i)decimal1) == Vector2i(2, 4), + "Vector2 cast to Vector2i should work as expected."); + CHECK_MESSAGE( + ((Vector2i)decimal2) == Vector2i(1, 3), + "Vector2 cast to Vector2i should work as expected."); + CHECK_MESSAGE( + Vector2(Vector2i(1, 2)) == Vector2(1, 2), + "Vector2 constructed from Vector2i should work as expected."); +} + +TEST_CASE("[Vector2] Other methods") { + const Vector2 vector = Vector2(1.2, 3.4); + CHECK_MESSAGE( + Math::is_equal_approx(vector.aspect(), (real_t)1.2 / (real_t)3.4), + "Vector2 aspect should work as expected."); + CHECK_MESSAGE( + vector.direction_to(Vector2()).is_equal_approx(-vector.normalized()), + "Vector2 direction_to should work as expected."); + CHECK_MESSAGE( + Vector2(1, 1).direction_to(Vector2(2, 2)).is_equal_approx(Vector2(Math_SQRT12, Math_SQRT12)), + "Vector2 direction_to should work as expected."); + CHECK_MESSAGE( + vector.posmod(2).is_equal_approx(Vector2(1.2, 1.4)), + "Vector2 posmod should work as expected."); + CHECK_MESSAGE( + (-vector).posmod(2).is_equal_approx(Vector2(0.8, 0.6)), + "Vector2 posmod should work as expected."); + CHECK_MESSAGE( + vector.posmodv(Vector2(1, 2)).is_equal_approx(Vector2(0.2, 1.4)), + "Vector2 posmodv should work as expected."); + CHECK_MESSAGE( + (-vector).posmodv(Vector2(2, 3)).is_equal_approx(Vector2(0.8, 2.6)), + "Vector2 posmodv should work as expected."); + CHECK_MESSAGE( + vector.rotated(Math_TAU / 4).is_equal_approx(Vector2(-3.4, 1.2)), + "Vector2 rotated should work as expected."); + CHECK_MESSAGE( + vector.snapped(Vector2(1, 1)) == Vector2(1, 3), + "Vector2 snapped to integers should be the same as rounding."); + CHECK_MESSAGE( + Vector2(3.4, 5.6).snapped(Vector2(1, 1)) == Vector2(3, 6), + "Vector2 snapped to integers should be the same as rounding."); + CHECK_MESSAGE( + vector.snapped(Vector2(0.25, 0.25)) == Vector2(1.25, 3.5), + "Vector2 snapped to 0.25 should give exact results."); +} + +TEST_CASE("[Vector2] Plane methods") { + const Vector2 vector = Vector2(1.2, 3.4); + const Vector2 vector_y = Vector2(0, 1); + CHECK_MESSAGE( + vector.bounce(vector_y) == Vector2(1.2, -3.4), + "Vector2 bounce on a plane with normal of the Y axis should."); + CHECK_MESSAGE( + vector.reflect(vector_y) == Vector2(-1.2, 3.4), + "Vector2 reflect on a plane with normal of the Y axis should."); + CHECK_MESSAGE( + vector.project(vector_y) == Vector2(0, 3.4), + "Vector2 projected on the X axis should only give the Y component."); + CHECK_MESSAGE( + vector.slide(vector_y) == Vector2(1.2, 0), + "Vector2 slide on a plane with normal of the Y axis should set the Y to zero."); +} + +TEST_CASE("[Vector2] Rounding methods") { + const Vector2 vector1 = Vector2(1.2, 5.6); + const Vector2 vector2 = Vector2(1.2, -5.6); + CHECK_MESSAGE( + vector1.abs() == vector1, + "Vector2 abs should work as expected."); + CHECK_MESSAGE( + vector2.abs() == vector1, + "Vector2 abs should work as expected."); + + CHECK_MESSAGE( + vector1.ceil() == Vector2(2, 6), + "Vector2 ceil should work as expected."); + CHECK_MESSAGE( + vector2.ceil() == Vector2(2, -5), + "Vector2 ceil should work as expected."); + + CHECK_MESSAGE( + vector1.floor() == Vector2(1, 5), + "Vector2 floor should work as expected."); + CHECK_MESSAGE( + vector2.floor() == Vector2(1, -6), + "Vector2 floor should work as expected."); + + CHECK_MESSAGE( + vector1.round() == Vector2(1, 6), + "Vector2 round should work as expected."); + CHECK_MESSAGE( + vector2.round() == Vector2(1, -6), + "Vector2 round should work as expected."); + + CHECK_MESSAGE( + vector1.sign() == Vector2(1, 1), + "Vector2 sign should work as expected."); + CHECK_MESSAGE( + vector2.sign() == Vector2(1, -1), + "Vector2 sign should work as expected."); +} + +TEST_CASE("[Vector2] Linear algebra methods") { + const Vector2 vector_x = Vector2(1, 0); + const Vector2 vector_y = Vector2(0, 1); + CHECK_MESSAGE( + vector_x.cross(vector_y) == 1, + "Vector2 cross product of X and Y should give 1."); + CHECK_MESSAGE( + vector_y.cross(vector_x) == -1, + "Vector2 cross product of Y and X should give negative 1."); + + CHECK_MESSAGE( + vector_x.dot(vector_y) == 0.0, + "Vector2 dot product of perpendicular vectors should be zero."); + CHECK_MESSAGE( + vector_x.dot(vector_x) == 1.0, + "Vector2 dot product of identical unit vectors should be one."); + CHECK_MESSAGE( + (vector_x * 10).dot(vector_x * 10) == 100.0, + "Vector2 dot product of same direction vectors should behave as expected."); +} +} // namespace TestVector2 + +#endif // TEST_VECTOR2_H diff --git a/tests/core/math/test_vector2i.h b/tests/core/math/test_vector2i.h new file mode 100644 index 0000000000..86e254654d --- /dev/null +++ b/tests/core/math/test_vector2i.h @@ -0,0 +1,144 @@ +/*************************************************************************/ +/* test_vector2i.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_VECTOR2I_H +#define TEST_VECTOR2I_H + +#include "core/math/vector2.h" +#include "tests/test_macros.h" + +namespace TestVector2i { + +TEST_CASE("[Vector2i] Axis methods") { + Vector2i vector = Vector2i(2, 3); + CHECK_MESSAGE( + vector.max_axis_index() == Vector2i::Axis::AXIS_Y, + "Vector2i max_axis_index should work as expected."); + CHECK_MESSAGE( + vector.min_axis_index() == Vector2i::Axis::AXIS_X, + "Vector2i min_axis_index should work as expected."); + CHECK_MESSAGE( + vector[vector.min_axis_index()] == 2, + "Vector2i array operator should work as expected."); + vector[Vector2i::Axis::AXIS_Y] = 5; + CHECK_MESSAGE( + vector[Vector2i::Axis::AXIS_Y] == 5, + "Vector2i array operator setter should work as expected."); +} + +TEST_CASE("[Vector2i] Clamp method") { + const Vector2i vector = Vector2i(10, 10); + CHECK_MESSAGE( + Vector2i(-5, 15).clamp(Vector2i(), vector) == Vector2i(0, 10), + "Vector2i clamp should work as expected."); + CHECK_MESSAGE( + vector.clamp(Vector2i(0, 15), Vector2i(5, 20)) == Vector2i(5, 15), + "Vector2i clamp should work as expected."); +} + +TEST_CASE("[Vector2i] Length methods") { + const Vector2i vector1 = Vector2i(10, 10); + const Vector2i vector2 = Vector2i(20, 30); + CHECK_MESSAGE( + vector1.length_squared() == 200, + "Vector2i length_squared should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.length(), 10 * Math_SQRT2), + "Vector2i length should work as expected."); + CHECK_MESSAGE( + vector2.length_squared() == 1300, + "Vector2i length_squared should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector2.length(), 36.05551275463989293119), + "Vector2i length should work as expected."); +} + +TEST_CASE("[Vector2i] Operators") { + const Vector2i vector1 = Vector2i(5, 9); + const Vector2i vector2 = Vector2i(2, 3); + + CHECK_MESSAGE( + (vector1 + vector2) == Vector2i(7, 12), + "Vector2i addition with integers should give exact results."); + CHECK_MESSAGE( + (vector1 - vector2) == Vector2i(3, 6), + "Vector2i subtraction with integers should give exact results."); + CHECK_MESSAGE( + (vector1 * vector2) == Vector2i(10, 27), + "Vector2i multiplication with integers should give exact results."); + CHECK_MESSAGE( + (vector1 / vector2) == Vector2i(2, 3), + "Vector2i division with integers should give exact results."); + + CHECK_MESSAGE( + (vector1 * 2) == Vector2i(10, 18), + "Vector2i multiplication with integers should give exact results."); + CHECK_MESSAGE( + (vector1 / 2) == Vector2i(2, 4), + "Vector2i division with integers should give exact results."); + + CHECK_MESSAGE( + ((Vector2)vector1) == Vector2(5, 9), + "Vector2i cast to Vector2 should work as expected."); + CHECK_MESSAGE( + ((Vector2)vector2) == Vector2(2, 3), + "Vector2i cast to Vector2 should work as expected."); + CHECK_MESSAGE( + Vector2i(Vector2(1.1, 2.9)) == Vector2i(1, 2), + "Vector2i constructed from Vector2 should work as expected."); +} + +TEST_CASE("[Vector2i] Other methods") { + const Vector2i vector = Vector2i(1, 3); + CHECK_MESSAGE( + Math::is_equal_approx(vector.aspect(), (real_t)1.0 / (real_t)3.0), + "Vector2i aspect should work as expected."); +} + +TEST_CASE("[Vector2i] Abs and sign methods") { + const Vector2i vector1 = Vector2i(1, 3); + const Vector2i vector2 = Vector2i(1, -3); + CHECK_MESSAGE( + vector1.abs() == vector1, + "Vector2i abs should work as expected."); + CHECK_MESSAGE( + vector2.abs() == vector1, + "Vector2i abs should work as expected."); + + CHECK_MESSAGE( + vector1.sign() == Vector2i(1, 1), + "Vector2i sign should work as expected."); + CHECK_MESSAGE( + vector2.sign() == Vector2i(1, -1), + "Vector2i sign should work as expected."); +} +} // namespace TestVector2i + +#endif // TEST_VECTOR2I_H diff --git a/tests/core/math/test_vector3.h b/tests/core/math/test_vector3.h new file mode 100644 index 0000000000..97da035046 --- /dev/null +++ b/tests/core/math/test_vector3.h @@ -0,0 +1,395 @@ +/*************************************************************************/ +/* test_vector3.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_VECTOR3_H +#define TEST_VECTOR3_H + +#include "core/math/vector3.h" +#include "tests/test_macros.h" + +#define Math_SQRT13 0.57735026918962576450914878050196 +#define Math_SQRT3 1.7320508075688772935274463415059 + +namespace TestVector3 { + +TEST_CASE("[Vector3] Angle methods") { + const Vector3 vector_x = Vector3(1, 0, 0); + const Vector3 vector_y = Vector3(0, 1, 0); + const Vector3 vector_yz = Vector3(0, 1, 1); + CHECK_MESSAGE( + Math::is_equal_approx(vector_x.angle_to(vector_y), (real_t)Math_TAU / 4), + "Vector3 angle_to should work as expected."); + CHECK_MESSAGE( + Math::is_equal_approx(vector_x.angle_to(vector_yz), (real_t)Math_TAU / 4), + "Vector3 angle_to should work as expected."); + CHECK_MESSAGE( + Math::is_equal_approx(vector_yz.angle_to(vector_x), (real_t)Math_TAU / 4), + "Vector3 angle_to should work as expected."); + CHECK_MESSAGE( + Math::is_equal_approx(vector_y.angle_to(vector_yz), (real_t)Math_TAU / 8), + "Vector3 angle_to should work as expected."); + + CHECK_MESSAGE( + Math::is_equal_approx(vector_x.signed_angle_to(vector_y, vector_y), (real_t)Math_TAU / 4), + "Vector3 signed_angle_to edge case should be postiive."); + CHECK_MESSAGE( + Math::is_equal_approx(vector_x.signed_angle_to(vector_yz, vector_y), (real_t)Math_TAU / -4), + "Vector3 signed_angle_to should work as expected."); + CHECK_MESSAGE( + Math::is_equal_approx(vector_yz.signed_angle_to(vector_x, vector_y), (real_t)Math_TAU / 4), + "Vector3 signed_angle_to should work as expected."); +} + +TEST_CASE("[Vector3] Axis methods") { + Vector3 vector = Vector3(1.2, 3.4, 5.6); + CHECK_MESSAGE( + vector.max_axis_index() == Vector3::Axis::AXIS_Z, + "Vector3 max_axis_index should work as expected."); + CHECK_MESSAGE( + vector.min_axis_index() == Vector3::Axis::AXIS_X, + "Vector3 min_axis_index should work as expected."); + CHECK_MESSAGE( + vector.get_axis(vector.max_axis_index()) == (real_t)5.6, + "Vector3 get_axis should work as expected."); + CHECK_MESSAGE( + vector[vector.min_axis_index()] == (real_t)1.2, + "Vector3 array operator should work as expected."); + + vector.set_axis(Vector3::Axis::AXIS_Y, 4.7); + CHECK_MESSAGE( + vector.get_axis(Vector3::Axis::AXIS_Y) == (real_t)4.7, + "Vector3 set_axis should work as expected."); + vector[Vector3::Axis::AXIS_Y] = 3.7; + CHECK_MESSAGE( + vector[Vector3::Axis::AXIS_Y] == (real_t)3.7, + "Vector3 array operator setter should work as expected."); +} + +TEST_CASE("[Vector3] Interpolation methods") { + const Vector3 vector1 = Vector3(1, 2, 3); + const Vector3 vector2 = Vector3(4, 5, 6); + CHECK_MESSAGE( + vector1.lerp(vector2, 0.5) == Vector3(2.5, 3.5, 4.5), + "Vector3 lerp should work as expected."); + CHECK_MESSAGE( + vector1.lerp(vector2, 1.0 / 3.0).is_equal_approx(Vector3(2, 3, 4)), + "Vector3 lerp should work as expected."); + CHECK_MESSAGE( + vector1.normalized().slerp(vector2.normalized(), 0.5).is_equal_approx(Vector3(0.363866806030273438, 0.555698215961456299, 0.747529566287994385)), + "Vector3 slerp should work as expected."); + CHECK_MESSAGE( + vector1.normalized().slerp(vector2.normalized(), 1.0 / 3.0).is_equal_approx(Vector3(0.332119762897491455, 0.549413740634918213, 0.766707837581634521)), + "Vector3 slerp should work as expected."); + CHECK_MESSAGE( + Vector3(5, 0, 0).slerp(Vector3(0, 3, 4), 0.5).is_equal_approx(Vector3(3.535533905029296875, 2.121320486068725586, 2.828427314758300781)), + "Vector3 slerp with non-normalized values should work as expected."); + CHECK_MESSAGE( + Vector3().slerp(Vector3(), 0.5) == Vector3(), + "Vector3 slerp with both inputs as zero vectors should return a zero vector."); + CHECK_MESSAGE( + Vector3().slerp(Vector3(1, 1, 1), 0.5) == Vector3(0.5, 0.5, 0.5), + "Vector3 slerp with one input as zero should behave like a regular lerp."); + CHECK_MESSAGE( + Vector3(1, 1, 1).slerp(Vector3(), 0.5) == Vector3(0.5, 0.5, 0.5), + "Vector3 slerp with one input as zero should behave like a regular lerp."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.slerp(vector2, 0.5).length(), (real_t)6.25831088708303172), + "Vector3 slerp with different length input should return a vector with an interpolated length."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.angle_to(vector1.slerp(vector2, 0.5)) * 2, vector1.angle_to(vector2)), + "Vector3 slerp with different length input should return a vector with an interpolated angle."); + CHECK_MESSAGE( + vector1.cubic_interpolate(vector2, Vector3(), Vector3(7, 7, 7), 0.5) == Vector3(2.375, 3.5, 4.625), + "Vector3 cubic_interpolate should work as expected."); + CHECK_MESSAGE( + vector1.cubic_interpolate(vector2, Vector3(), Vector3(7, 7, 7), 1.0 / 3.0).is_equal_approx(Vector3(1.851851940155029297, 2.962963104248046875, 4.074074268341064453)), + "Vector3 cubic_interpolate should work as expected."); + CHECK_MESSAGE( + Vector3(1, 0, 0).move_toward(Vector3(10, 0, 0), 3) == Vector3(4, 0, 0), + "Vector3 move_toward should work as expected."); +} + +TEST_CASE("[Vector3] Length methods") { + const Vector3 vector1 = Vector3(10, 10, 10); + const Vector3 vector2 = Vector3(20, 30, 40); + CHECK_MESSAGE( + vector1.length_squared() == 300, + "Vector3 length_squared should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.length(), 10 * (real_t)Math_SQRT3), + "Vector3 length should work as expected."); + CHECK_MESSAGE( + vector2.length_squared() == 2900, + "Vector3 length_squared should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector2.length(), (real_t)53.8516480713450403125), + "Vector3 length should work as expected."); + CHECK_MESSAGE( + vector1.distance_squared_to(vector2) == 1400, + "Vector3 distance_squared_to should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.distance_to(vector2), (real_t)37.41657386773941385584), + "Vector3 distance_to should work as expected."); +} + +TEST_CASE("[Vector3] Limiting methods") { + const Vector3 vector = Vector3(10, 10, 10); + CHECK_MESSAGE( + vector.limit_length().is_equal_approx(Vector3(Math_SQRT13, Math_SQRT13, Math_SQRT13)), + "Vector3 limit_length should work as expected."); + CHECK_MESSAGE( + vector.limit_length(5).is_equal_approx(5 * Vector3(Math_SQRT13, Math_SQRT13, Math_SQRT13)), + "Vector3 limit_length should work as expected."); + + CHECK_MESSAGE( + Vector3(-5, 5, 15).clamp(Vector3(), vector) == Vector3(0, 5, 10), + "Vector3 clamp should work as expected."); + CHECK_MESSAGE( + vector.clamp(Vector3(0, 10, 15), Vector3(5, 10, 20)) == Vector3(5, 10, 15), + "Vector3 clamp should work as expected."); +} + +TEST_CASE("[Vector3] Normalization methods") { + CHECK_MESSAGE( + Vector3(1, 0, 0).is_normalized() == true, + "Vector3 is_normalized should return true for a normalized vector."); + CHECK_MESSAGE( + Vector3(1, 1, 1).is_normalized() == false, + "Vector3 is_normalized should return false for a non-normalized vector."); + CHECK_MESSAGE( + Vector3(1, 0, 0).normalized() == Vector3(1, 0, 0), + "Vector3 normalized should return the same vector for a normalized vector."); + CHECK_MESSAGE( + Vector3(1, 1, 0).normalized().is_equal_approx(Vector3(Math_SQRT12, Math_SQRT12, 0)), + "Vector3 normalized should work as expected."); + CHECK_MESSAGE( + Vector3(1, 1, 1).normalized().is_equal_approx(Vector3(Math_SQRT13, Math_SQRT13, Math_SQRT13)), + "Vector3 normalized should work as expected."); +} + +TEST_CASE("[Vector3] Operators") { + const Vector3 decimal1 = Vector3(2.3, 4.9, 7.8); + const Vector3 decimal2 = Vector3(1.2, 3.4, 5.6); + const Vector3 power1 = Vector3(0.75, 1.5, 0.625); + const Vector3 power2 = Vector3(0.5, 0.125, 0.25); + const Vector3 int1 = Vector3(4, 5, 9); + const Vector3 int2 = Vector3(1, 2, 3); + + CHECK_MESSAGE( + (decimal1 + decimal2).is_equal_approx(Vector3(3.5, 8.3, 13.4)), + "Vector3 addition should behave as expected."); + CHECK_MESSAGE( + (power1 + power2) == Vector3(1.25, 1.625, 0.875), + "Vector3 addition with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 + int2) == Vector3(5, 7, 12), + "Vector3 addition with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 - decimal2).is_equal_approx(Vector3(1.1, 1.5, 2.2)), + "Vector3 subtraction should behave as expected."); + CHECK_MESSAGE( + (power1 - power2) == Vector3(0.25, 1.375, 0.375), + "Vector3 subtraction with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 - int2) == Vector3(3, 3, 6), + "Vector3 subtraction with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 * decimal2).is_equal_approx(Vector3(2.76, 16.66, 43.68)), + "Vector3 multiplication should behave as expected."); + CHECK_MESSAGE( + (power1 * power2) == Vector3(0.375, 0.1875, 0.15625), + "Vector3 multiplication with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 * int2) == Vector3(4, 10, 27), + "Vector3 multiplication with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 / decimal2).is_equal_approx(Vector3(1.91666666666666666, 1.44117647058823529, 1.39285714285714286)), + "Vector3 division should behave as expected."); + CHECK_MESSAGE( + (power1 / power2) == Vector3(1.5, 12.0, 2.5), + "Vector3 division with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 / int2) == Vector3(4, 2.5, 3), + "Vector3 division with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 * 2).is_equal_approx(Vector3(4.6, 9.8, 15.6)), + "Vector3 multiplication should behave as expected."); + CHECK_MESSAGE( + (power1 * 2) == Vector3(1.5, 3, 1.25), + "Vector3 multiplication with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 * 2) == Vector3(8, 10, 18), + "Vector3 multiplication with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 / 2).is_equal_approx(Vector3(1.15, 2.45, 3.9)), + "Vector3 division should behave as expected."); + CHECK_MESSAGE( + (power1 / 2) == Vector3(0.375, 0.75, 0.3125), + "Vector3 division with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 / 2) == Vector3(2, 2.5, 4.5), + "Vector3 division with integers should give exact results."); + + CHECK_MESSAGE( + ((Vector3i)decimal1) == Vector3i(2, 4, 7), + "Vector3 cast to Vector3i should work as expected."); + CHECK_MESSAGE( + ((Vector3i)decimal2) == Vector3i(1, 3, 5), + "Vector3 cast to Vector3i should work as expected."); + CHECK_MESSAGE( + Vector3(Vector3i(1, 2, 3)) == Vector3(1, 2, 3), + "Vector3 constructed from Vector3i should work as expected."); +} + +TEST_CASE("[Vector3] Other methods") { + const Vector3 vector = Vector3(1.2, 3.4, 5.6); + CHECK_MESSAGE( + vector.direction_to(Vector3()).is_equal_approx(-vector.normalized()), + "Vector3 direction_to should work as expected."); + CHECK_MESSAGE( + Vector3(1, 1, 1).direction_to(Vector3(2, 2, 2)).is_equal_approx(Vector3(Math_SQRT13, Math_SQRT13, Math_SQRT13)), + "Vector3 direction_to should work as expected."); + CHECK_MESSAGE( + vector.inverse().is_equal_approx(Vector3(1 / 1.2, 1 / 3.4, 1 / 5.6)), + "Vector3 inverse should work as expected."); + CHECK_MESSAGE( + vector.posmod(2).is_equal_approx(Vector3(1.2, 1.4, 1.6)), + "Vector3 posmod should work as expected."); + CHECK_MESSAGE( + (-vector).posmod(2).is_equal_approx(Vector3(0.8, 0.6, 0.4)), + "Vector3 posmod should work as expected."); + CHECK_MESSAGE( + vector.posmodv(Vector3(1, 2, 3)).is_equal_approx(Vector3(0.2, 1.4, 2.6)), + "Vector3 posmodv should work as expected."); + CHECK_MESSAGE( + (-vector).posmodv(Vector3(2, 3, 4)).is_equal_approx(Vector3(0.8, 2.6, 2.4)), + "Vector3 posmodv should work as expected."); + CHECK_MESSAGE( + vector.rotated(Vector3(0, 1, 0), Math_TAU / 4).is_equal_approx(Vector3(5.6, 3.4, -1.2)), + "Vector3 rotated should work as expected."); + CHECK_MESSAGE( + vector.snapped(Vector3(1, 1, 1)) == Vector3(1, 3, 6), + "Vector3 snapped to integers should be the same as rounding."); + CHECK_MESSAGE( + vector.snapped(Vector3(0.25, 0.25, 0.25)) == Vector3(1.25, 3.5, 5.5), + "Vector3 snapped to 0.25 should give exact results."); +} + +TEST_CASE("[Vector3] Plane methods") { + const Vector3 vector = Vector3(1.2, 3.4, 5.6); + const Vector3 vector_y = Vector3(0, 1, 0); + CHECK_MESSAGE( + vector.bounce(vector_y) == Vector3(1.2, -3.4, 5.6), + "Vector3 bounce on a plane with normal of the Y axis should."); + CHECK_MESSAGE( + vector.reflect(vector_y) == Vector3(-1.2, 3.4, -5.6), + "Vector3 reflect on a plane with normal of the Y axis should."); + CHECK_MESSAGE( + vector.project(vector_y) == Vector3(0, 3.4, 0), + "Vector3 projected on the X axis should only give the Y component."); + CHECK_MESSAGE( + vector.slide(vector_y) == Vector3(1.2, 0, 5.6), + "Vector3 slide on a plane with normal of the Y axis should set the Y to zero."); +} + +TEST_CASE("[Vector3] Rounding methods") { + const Vector3 vector1 = Vector3(1.2, 3.4, 5.6); + const Vector3 vector2 = Vector3(1.2, -3.4, -5.6); + CHECK_MESSAGE( + vector1.abs() == vector1, + "Vector3 abs should work as expected."); + CHECK_MESSAGE( + vector2.abs() == vector1, + "Vector3 abs should work as expected."); + + CHECK_MESSAGE( + vector1.ceil() == Vector3(2, 4, 6), + "Vector3 ceil should work as expected."); + CHECK_MESSAGE( + vector2.ceil() == Vector3(2, -3, -5), + "Vector3 ceil should work as expected."); + + CHECK_MESSAGE( + vector1.floor() == Vector3(1, 3, 5), + "Vector3 floor should work as expected."); + CHECK_MESSAGE( + vector2.floor() == Vector3(1, -4, -6), + "Vector3 floor should work as expected."); + + CHECK_MESSAGE( + vector1.round() == Vector3(1, 3, 6), + "Vector3 round should work as expected."); + CHECK_MESSAGE( + vector2.round() == Vector3(1, -3, -6), + "Vector3 round should work as expected."); + + CHECK_MESSAGE( + vector1.sign() == Vector3(1, 1, 1), + "Vector3 sign should work as expected."); + CHECK_MESSAGE( + vector2.sign() == Vector3(1, -1, -1), + "Vector3 sign should work as expected."); +} + +TEST_CASE("[Vector3] Linear algebra methods") { + const Vector3 vector_x = Vector3(1, 0, 0); + const Vector3 vector_y = Vector3(0, 1, 0); + const Vector3 vector_z = Vector3(0, 0, 1); + CHECK_MESSAGE( + vector_x.cross(vector_y) == vector_z, + "Vector3 cross product of X and Y should give Z."); + CHECK_MESSAGE( + vector_y.cross(vector_x) == -vector_z, + "Vector3 cross product of Y and X should give negative Z."); + CHECK_MESSAGE( + vector_y.cross(vector_z) == vector_x, + "Vector3 cross product of Y and Z should give X."); + CHECK_MESSAGE( + vector_z.cross(vector_x) == vector_y, + "Vector3 cross product of Z and X should give Y."); + + CHECK_MESSAGE( + vector_x.dot(vector_y) == 0.0, + "Vector3 dot product of perpendicular vectors should be zero."); + CHECK_MESSAGE( + vector_x.dot(vector_x) == 1.0, + "Vector3 dot product of identical unit vectors should be one."); + CHECK_MESSAGE( + (vector_x * 10).dot(vector_x * 10) == 100.0, + "Vector3 dot product of same direction vectors should behave as expected."); +} +} // namespace TestVector3 + +#endif // TEST_VECTOR3_H diff --git a/tests/core/math/test_vector3i.h b/tests/core/math/test_vector3i.h new file mode 100644 index 0000000000..b1c6944eba --- /dev/null +++ b/tests/core/math/test_vector3i.h @@ -0,0 +1,145 @@ +/*************************************************************************/ +/* test_vector3i.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_VECTOR3I_H +#define TEST_VECTOR3I_H + +#include "core/math/vector3i.h" +#include "tests/test_macros.h" + +namespace TestVector3i { + +TEST_CASE("[Vector3i] Axis methods") { + Vector3i vector = Vector3i(1, 2, 3); + CHECK_MESSAGE( + vector.max_axis_index() == Vector3i::Axis::AXIS_Z, + "Vector3i max_axis_index should work as expected."); + CHECK_MESSAGE( + vector.min_axis_index() == Vector3i::Axis::AXIS_X, + "Vector3i min_axis_index should work as expected."); + CHECK_MESSAGE( + vector.get_axis(vector.max_axis_index()) == 3, + "Vector3i get_axis should work as expected."); + CHECK_MESSAGE( + vector[vector.min_axis_index()] == 1, + "Vector3i array operator should work as expected."); + + vector.set_axis(Vector3i::Axis::AXIS_Y, 4); + CHECK_MESSAGE( + vector.get_axis(Vector3i::Axis::AXIS_Y) == 4, + "Vector3i set_axis should work as expected."); + vector[Vector3i::Axis::AXIS_Y] = 5; + CHECK_MESSAGE( + vector[Vector3i::Axis::AXIS_Y] == 5, + "Vector3i array operator setter should work as expected."); +} + +TEST_CASE("[Vector3i] Clamp method") { + const Vector3i vector = Vector3i(10, 10, 10); + CHECK_MESSAGE( + Vector3i(-5, 5, 15).clamp(Vector3i(), vector) == Vector3i(0, 5, 10), + "Vector3i clamp should work as expected."); + CHECK_MESSAGE( + vector.clamp(Vector3i(0, 10, 15), Vector3i(5, 10, 20)) == Vector3i(5, 10, 15), + "Vector3i clamp should work as expected."); +} + +TEST_CASE("[Vector3i] Length methods") { + const Vector3i vector1 = Vector3i(10, 10, 10); + const Vector3i vector2 = Vector3i(20, 30, 40); + CHECK_MESSAGE( + vector1.length_squared() == 300, + "Vector3i length_squared should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.length(), 10 * Math_SQRT3), + "Vector3i length should work as expected."); + CHECK_MESSAGE( + vector2.length_squared() == 2900, + "Vector3i length_squared should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector2.length(), 53.8516480713450403125), + "Vector3i length should work as expected."); +} + +TEST_CASE("[Vector3i] Operators") { + const Vector3i vector1 = Vector3i(4, 5, 9); + const Vector3i vector2 = Vector3i(1, 2, 3); + + CHECK_MESSAGE( + (vector1 + vector2) == Vector3i(5, 7, 12), + "Vector3i addition with integers should give exact results."); + CHECK_MESSAGE( + (vector1 - vector2) == Vector3i(3, 3, 6), + "Vector3i subtraction with integers should give exact results."); + CHECK_MESSAGE( + (vector1 * vector2) == Vector3i(4, 10, 27), + "Vector3i multiplication with integers should give exact results."); + CHECK_MESSAGE( + (vector1 / vector2) == Vector3i(4, 2, 3), + "Vector3i division with integers should give exact results."); + + CHECK_MESSAGE( + (vector1 * 2) == Vector3i(8, 10, 18), + "Vector3i multiplication with integers should give exact results."); + CHECK_MESSAGE( + (vector1 / 2) == Vector3i(2, 2, 4), + "Vector3i division with integers should give exact results."); + + CHECK_MESSAGE( + ((Vector3)vector1) == Vector3(4, 5, 9), + "Vector3i cast to Vector3 should work as expected."); + CHECK_MESSAGE( + ((Vector3)vector2) == Vector3(1, 2, 3), + "Vector3i cast to Vector3 should work as expected."); + CHECK_MESSAGE( + Vector3i(Vector3(1.1, 2.9, 3.9)) == Vector3i(1, 2, 3), + "Vector3i constructed from Vector3 should work as expected."); +} + +TEST_CASE("[Vector3i] Abs and sign methods") { + const Vector3i vector1 = Vector3i(1, 3, 5); + const Vector3i vector2 = Vector3i(1, -3, -5); + CHECK_MESSAGE( + vector1.abs() == vector1, + "Vector3i abs should work as expected."); + CHECK_MESSAGE( + vector2.abs() == vector1, + "Vector3i abs should work as expected."); + + CHECK_MESSAGE( + vector1.sign() == Vector3i(1, 1, 1), + "Vector3i sign should work as expected."); + CHECK_MESSAGE( + vector2.sign() == Vector3i(1, -1, -1), + "Vector3i sign should work as expected."); +} +} // namespace TestVector3i + +#endif // TEST_VECTOR3I_H diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h index 52d3d5c340..be6e796da8 100644 --- a/tests/scene/test_code_edit.h +++ b/tests/scene/test_code_edit.h @@ -3220,7 +3220,7 @@ TEST_CASE("[SceneTree][CodeEdit] Backspace delete") { code_edit->backspace(); CHECK(code_edit->get_line(0) == "backspace"); - /* Move caret up to the previous line on backspace if carret is at the first column. */ + /* Move caret up to the previous line on backspace if caret is at the first column. */ code_edit->set_text(""); code_edit->insert_text_at_caret("line 1\nline 2"); code_edit->set_caret_line(1); diff --git a/tests/servers/test_text_server.h b/tests/servers/test_text_server.h index b06f315bc8..0a64237285 100644 --- a/tests/servers/test_text_server.h +++ b/tests/servers/test_text_server.h @@ -154,6 +154,212 @@ TEST_SUITE("[[TextServer]") { } } + SUBCASE("[TextServer] Text layout: Line break and align points") { + for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { + Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); + TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + + RID font1 = ts->create_font(); + ts->font_set_data_ptr(font1, _font_NotoSans_Regular, _font_NotoSans_Regular_size); + RID font2 = ts->create_font(); + ts->font_set_data_ptr(font2, _font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size); + RID font3 = ts->create_font(); + ts->font_set_data_ptr(font3, _font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size); + + Vector<RID> font; + font.push_back(font1); + font.push_back(font2); + font.push_back(font3); + + { + String test = U"Test test long text long text\n"; + RID ctx = ts->create_shaped_text(); + TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + bool ok = ts->shaped_text_add_string(ctx, test, font, 16); + TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + ts->shaped_text_update_breaks(ctx); + ts->shaped_text_update_justification_ops(ctx); + + const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); + int gl_size = ts->shaped_text_get_glyph_count(ctx); + + TEST_FAIL_COND(gl_size != 30, "Invalid glyph count."); + for (int j = 0; j < gl_size; j++) { + bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; + bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; + bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE; + bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; + bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; + if (j == 4 || j == 9 || j == 14 || j == 19 || j == 24) { + TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags."); + } else if (j == 29) { + TEST_FAIL_COND((soft || !space || !hard || virt || elo), "Invalid glyph flags."); + } else { + TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + } + } + ts->free(ctx); + } + + { + String test = U"الØÙ…ـد"; + RID ctx = ts->create_shaped_text(); + TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + bool ok = ts->shaped_text_add_string(ctx, test, font, 16); + TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + ts->shaped_text_update_breaks(ctx); + + const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); + int gl_size = ts->shaped_text_get_glyph_count(ctx); + TEST_FAIL_COND(gl_size != 6, "Invalid glyph count."); + for (int j = 0; j < gl_size; j++) { + bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; + bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; + bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE; + bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; + bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; + TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + } + + if (ts->has_feature(TextServer::FEATURE_KASHIDA_JUSTIFICATION)) { + ts->shaped_text_update_justification_ops(ctx); + + glyphs = ts->shaped_text_get_glyphs(ctx); + gl_size = ts->shaped_text_get_glyph_count(ctx); + + TEST_FAIL_COND(gl_size != 6, "Invalid glyph count."); + for (int j = 0; j < gl_size; j++) { + bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; + bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; + bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE; + bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; + bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; + if (j == 1) { + TEST_FAIL_COND((soft || space || hard || virt || !elo), "Invalid glyph flags."); + } else { + TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + } + } + } + ts->free(ctx); + } + + { + String test = U"الØÙ…ـد الرياضي العربي"; + RID ctx = ts->create_shaped_text(); + TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + bool ok = ts->shaped_text_add_string(ctx, test, font, 16); + TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + ts->shaped_text_update_breaks(ctx); + + const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); + int gl_size = ts->shaped_text_get_glyph_count(ctx); + + TEST_FAIL_COND(gl_size != 21, "Invalid glyph count."); + for (int j = 0; j < gl_size; j++) { + bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; + bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; + bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE; + bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; + bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; + if (j == 6 || j == 14) { + TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags."); + } else { + TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + } + } + + if (ts->has_feature(TextServer::FEATURE_KASHIDA_JUSTIFICATION)) { + ts->shaped_text_update_justification_ops(ctx); + + glyphs = ts->shaped_text_get_glyphs(ctx); + gl_size = ts->shaped_text_get_glyph_count(ctx); + + TEST_FAIL_COND(gl_size != 23, "Invalid glyph count."); + for (int j = 0; j < gl_size; j++) { + bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; + bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; + bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE; + bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; + bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; + if (j == 7 || j == 16) { + TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags."); + } else if (j == 3 || j == 9) { + TEST_FAIL_COND((soft || space || hard || !virt || !elo), "Invalid glyph flags."); + } else if (j == 18) { + TEST_FAIL_COND((soft || space || hard || virt || !elo), "Invalid glyph flags."); + } else { + TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + } + } + } + + ts->free(ctx); + } + + { + String test = U"เป็น ภาษา ราชà¸à¸²à¸£ à¹à¸¥à¸° ภาษา"; + RID ctx = ts->create_shaped_text(); + TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + bool ok = ts->shaped_text_add_string(ctx, test, font, 16); + TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + ts->shaped_text_update_breaks(ctx); + ts->shaped_text_update_justification_ops(ctx); + + const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); + int gl_size = ts->shaped_text_get_glyph_count(ctx); + + TEST_FAIL_COND(gl_size != 25, "Invalid glyph count."); + for (int j = 0; j < gl_size; j++) { + bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; + bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; + bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE; + bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; + bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; + if (j == 4 || j == 9 || j == 16 || j == 20) { + TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags."); + } else { + TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + } + } + ts->free(ctx); + } + + if (ts->has_feature(TextServer::FEATURE_BREAK_ITERATORS)) { + String test = U"เป็นภาษาราชà¸à¸²à¸£à¹à¸¥à¸°à¸ าษา"; + RID ctx = ts->create_shaped_text(); + TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + bool ok = ts->shaped_text_add_string(ctx, test, font, 16); + TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + ts->shaped_text_update_breaks(ctx); + ts->shaped_text_update_justification_ops(ctx); + + const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); + int gl_size = ts->shaped_text_get_glyph_count(ctx); + + TEST_FAIL_COND(gl_size != 25, "Invalid glyph count."); + for (int j = 0; j < gl_size; j++) { + bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; + bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; + bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE; + bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; + bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; + if (j == 4 || j == 9 || j == 16 || j == 20) { + TEST_FAIL_COND((!soft || !space || hard || !virt || elo), "Invalid glyph flags."); + } else { + TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + } + } + ts->free(ctx); + } + + for (int j = 0; j < font.size(); j++) { + ts->free(font[j]); + } + font.clear(); + } + } + SUBCASE("[TextServer] Text layout: Line breaking") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 2b2c89fbf1..3826c03cad 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -48,6 +48,10 @@ #include "tests/core/math/test_math.h" #include "tests/core/math/test_random_number_generator.h" #include "tests/core/math/test_rect2.h" +#include "tests/core/math/test_vector2.h" +#include "tests/core/math/test_vector2i.h" +#include "tests/core/math/test_vector3.h" +#include "tests/core/math/test_vector3i.h" #include "tests/core/object/test_class_db.h" #include "tests/core/object/test_method_bind.h" #include "tests/core/object/test_object.h" diff --git a/thirdparty/README.md b/thirdparty/README.md index 09f3d88845..cfefae5207 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -155,14 +155,14 @@ Files extracted from upstream source: ## freetype - Upstream: https://www.freetype.org -- Version: 2.10.4 (6a2b3e4007e794bfc6c91030d0ed987f925164a8, 2020) +- Version: 2.11.1 (3f83daeecb1a78d851b660eed025eeba362c0e4a, 2021) - License: FreeType License (BSD-like) Files extracted from upstream source: -- the `src/` folder, stripped of the `Jamfile` files and the `tools` subfolder -- the `include/` folder -- `docs/{FTL.TXT,LICENSE.TXT}` +- the `src/` folder, minus the `.mk` files and the `dlg` and `tools` subfolders +- the `include/` folder, minus the `dlg` subfolder +- `LICENSE.TXT` and `docs/FTL.TXT` ## glslang @@ -175,10 +175,14 @@ Version should be kept in sync with the one of the used Vulkan SDK (see `vulkan` section). Check Vulkan-ValidationLayers at the matching SDK tag for the known good glslang commit: https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/master/scripts/known_good.json +When updating, also review that our `modules/glslang/glslang_resource_limits.h` +copy of `DefaultTBuiltInResource` is in sync with the one defined upstream in +`StandAlone/ResourceLimits.cpp`. + Files extracted from upstream source: -- `glslang` (except `glslang/HLSL`), `OGLCompilersDLL`, `SPIRV` -- `StandAlone/{DirStackFileIncluder.h,ResourceLimits.{cpp,h}}` +- `glslang` (except `glslang/HLSL`), `OGLCompilersDLL`, `SPIRV`, + minus the `CInterface` folders (depends on `StandAlone`) - Run `cmake . && make` and copy generated `include/glslang/build_info.h` to `glslang/build_info.h` - `LICENSE.txt` @@ -201,7 +205,7 @@ Files extracted from upstream source: ## harfbuzz - Upstream: https://github.com/harfbuzz/harfbuzz -- Version: 3.1.2 (8aed5c21a31eece6a9f3cd775fda8facb6c28b9b, 2021) +- Version: 3.2.0 (be91d2917d9860326cb5fd1d03ffe1042a72f6d3, 2021) - License: MIT Files extracted from upstream source: @@ -473,19 +477,6 @@ Files extracted from the upstream source: - Files in `core/` folder. - `LICENSE.txt` and `CHANGELOG.md` - -## nanosvg - -- Upstream: https://github.com/memononen/nanosvg -- Version: git (ccdb1995134d340a93fb20e3a3d323ccb3838dd0, 2021) -- License: zlib - -Files extracted from the upstream source: - -- All .h files in `src/` -- LICENSE.txt - - ## oidn - Upstream: https://github.com/OpenImageDenoise/oidn @@ -624,6 +615,18 @@ The `tinyexr.cc` file was modified to include `zlib.h` which we provide, instead of `miniz.h` as an external dependency. +## thorvg + +- Upstream: https://github.com/Samsung/thorvg +- Version: 0.7.0 (e527f565b770f0a41df821e6618ccaeea94f465e, 2021) +- License: MIT + +Files extracted from upstream source: + +See `thorvg/update-thorvg.sh` for extraction instructions. Set the version +number and run the script. + + ## vhacd - Upstream: https://github.com/kmammou/v-hacd diff --git a/thirdparty/freetype/LICENSE.TXT b/thirdparty/freetype/LICENSE.TXT index af5a1c50f6..b1def65dd6 100644 --- a/thirdparty/freetype/LICENSE.TXT +++ b/thirdparty/freetype/LICENSE.TXT @@ -1,39 +1,42 @@ +FREETYPE LICENSES +----------------- -The FreeType 2 font engine is copyrighted work and cannot be used -legally without a software license. In order to make this project -usable to a vast majority of developers, we distribute it under two +The FreeType 2 font engine is copyrighted work and cannot be used +legally without a software license. In order to make this project +usable to a vast majority of developers, we distribute it under two mutually exclusive open-source licenses. -This means that *you* must choose *one* of the two licenses described -below, then obey all its terms and conditions when using FreeType 2 in +This means that *you* must choose *one* of the two licenses described +below, then obey all its terms and conditions when using FreeType 2 in any of your projects or products. - - The FreeType License, found in the file `FTL.TXT', which is similar - to the original BSD license *with* an advertising clause that forces - you to explicitly cite the FreeType project in your product's - documentation. All details are in the license file. This license - is suited to products which don't use the GNU General Public - License. + - The FreeType License, found in the file `docs/FTL.TXT`, which is + similar to the original BSD license *with* an advertising clause + that forces you to explicitly cite the FreeType project in your + product's documentation. All details are in the license file. + This license is suited to products which don't use the GNU General + Public License. - Note that this license is compatible to the GNU General Public + Note that this license is compatible to the GNU General Public License version 3, but not version 2. - - The GNU General Public License version 2, found in `GPLv2.TXT' (any - later version can be used also), for programs which already use the - GPL. Note that the FTL is incompatible with GPLv2 due to its - advertisement clause. + - The GNU General Public License version 2, found in + `docs/GPLv2.TXT` (any later version can be used also), for + programs which already use the GPL. Note that the FTL is + incompatible with GPLv2 due to its advertisement clause. -The contributed BDF and PCF drivers come with a license similar to that -of the X Window System. It is compatible to the above two licenses (see -file src/bdf/README and src/pcf/README). The same holds for the files -`fthash.c' and `fthash.h'; their code was part of the BDF driver in -earlier FreeType versions. +The contributed BDF and PCF drivers come with a license similar to +that of the X Window System. It is compatible to the above two +licenses (see files `src/bdf/README` and `src/pcf/README`). The same +holds for the source code files `src/base/fthash.c` and +`include/freetype/internal/fthash.h`; they wer part of the BDF driver +in earlier FreeType versions. -The gzip module uses the zlib license (see src/gzip/zlib.h) which too is -compatible to the above two licenses. +The gzip module uses the zlib license (see `src/gzip/zlib.h`) which +too is compatible to the above two licenses. -The MD5 checksum support (only used for debugging in development builds) -is in the public domain. +The MD5 checksum support (only used for debugging in development +builds) is in the public domain. --- end of LICENSE.TXT --- diff --git a/thirdparty/freetype/include/freetype/config/ftconfig.h b/thirdparty/freetype/include/freetype/config/ftconfig.h index b464e0b789..65effcbe63 100644 --- a/thirdparty/freetype/include/freetype/config/ftconfig.h +++ b/thirdparty/freetype/include/freetype/config/ftconfig.h @@ -4,7 +4,7 @@ * * ANSI-specific configuration file (specification only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/config/ftheader.h b/thirdparty/freetype/include/freetype/config/ftheader.h index 28b5cc60cf..e46d314e33 100644 --- a/thirdparty/freetype/include/freetype/config/ftheader.h +++ b/thirdparty/freetype/include/freetype/config/ftheader.h @@ -4,7 +4,7 @@ * * Build macros of the FreeType 2 library. * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/config/ftmodule.h b/thirdparty/freetype/include/freetype/config/ftmodule.h index b5c4b1ee58..d4ba3f784d 100644 --- a/thirdparty/freetype/include/freetype/config/ftmodule.h +++ b/thirdparty/freetype/include/freetype/config/ftmodule.h @@ -19,12 +19,14 @@ FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class ) FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class ) FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class ) FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class ) FT_USE_MODULE( FT_Module_Class, psaux_module_class ) FT_USE_MODULE( FT_Module_Class, psnames_module_class ) FT_USE_MODULE( FT_Module_Class, pshinter_module_class ) -FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class ) FT_USE_MODULE( FT_Module_Class, sfnt_module_class ) FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class ) -FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_sdf_renderer_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_bitmap_sdf_renderer_class ) /* EOF */ diff --git a/thirdparty/freetype/include/freetype/config/ftoption.h b/thirdparty/freetype/include/freetype/config/ftoption.h index 097f19b8a5..4227fd376e 100644 --- a/thirdparty/freetype/include/freetype/config/ftoption.h +++ b/thirdparty/freetype/include/freetype/config/ftoption.h @@ -4,7 +4,7 @@ * * User-selectable configuration macros (specification only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -105,8 +105,7 @@ FT_BEGIN_HEADER * * ``` * FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ - * cff:no-stem-darkening=1 \ - * autofitter:warping=1 + * cff:no-stem-darkening=1 * ``` * */ @@ -433,6 +432,23 @@ FT_BEGIN_HEADER /************************************************************************** * + * Logging + * + * Compiling FreeType in debug or trace mode makes FreeType write error + * and trace log messages to `stderr`. Enabling this macro + * automatically forces the `FT_DEBUG_LEVEL_ERROR` and + * `FT_DEBUG_LEVEL_TRACE` macros and allows FreeType to write error and + * trace log messages to a file instead of `stderr`. For writing logs + * to a file, FreeType uses an the external `dlg` library (the source + * code is in `src/dlg`). + * + * This option needs a C99 compiler. + */ +/* #define FT_DEBUG_LOGGING */ + + + /************************************************************************** + * * Autofitter debugging * * If `FT_DEBUG_AUTOFIT` is defined, FreeType provides some means to @@ -894,24 +910,6 @@ FT_BEGIN_HEADER /************************************************************************** * - * Compile 'autofit' module with warp hinting. The idea of the warping - * code is to slightly scale and shift a glyph within a single dimension so - * that as much of its segments are aligned (more or less) on the grid. To - * find out the optimal scaling and shifting value, various parameter - * combinations are tried and scored. - * - * You can switch warping on and off with the `warping` property of the - * auto-hinter (see file `ftdriver.h` for more information; by default it - * is switched off). - * - * This experimental option is not active if the rendering mode is - * `FT_RENDER_MODE_LIGHT`. - */ -#define AF_CONFIG_OPTION_USE_WARPER - - - /************************************************************************** - * * Use TrueType-like size metrics for 'light' auto-hinting. * * It is strongly recommended to avoid this option, which exists only to @@ -962,6 +960,21 @@ FT_BEGIN_HEADER /* + * The TT_SUPPORT_COLRV1 macro is defined to indicate to clients that this + * version of FreeType has support for 'COLR' v1 API. This definition is + * useful to FreeType clients that want to build in support for 'COLR' v1 + * depending on a tip-of-tree checkout before it is officially released in + * FreeType, and while the feature cannot yet be tested against using + * version macros. Don't change this macro. This may be removed once the + * feature is in a FreeType release version and version macros can be used + * to test for availability. + */ +#ifdef TT_CONFIG_OPTION_COLOR_LAYERS +#define TT_SUPPORT_COLRV1 +#endif + + + /* * Check CFF darkening parameters. The checks are the same as in function * `cff_property_set` in file `cffdrivr.c`. */ diff --git a/thirdparty/freetype/include/freetype/config/ftstdlib.h b/thirdparty/freetype/include/freetype/config/ftstdlib.h index d6091f8b3d..6ee412a074 100644 --- a/thirdparty/freetype/include/freetype/config/ftstdlib.h +++ b/thirdparty/freetype/include/freetype/config/ftstdlib.h @@ -5,7 +5,7 @@ * ANSI-specific library and header configuration file (specification * only). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -43,7 +43,8 @@ * * `UINT_MAX` and `ULONG_MAX` are used to automatically compute the size of * `int` and `long` in bytes at compile-time. So far, this works for all - * platforms the library has been tested on. + * platforms the library has been tested on. We also check `ULLONG_MAX` + * to see whether we can use 64-bit `long long` later on. * * Note that on the extremely rare platforms that do not provide integer * types that are _exactly_ 16 and 32~bits wide (e.g., some old Crays where @@ -66,6 +67,15 @@ #define FT_LONG_MIN LONG_MIN #define FT_LONG_MAX LONG_MAX #define FT_ULONG_MAX ULONG_MAX +#ifdef LLONG_MAX +#define FT_LLONG_MAX LLONG_MAX +#endif +#ifdef LLONG_MIN +#define FT_LLONG_MIN LLONG_MIN +#endif +#ifdef ULLONG_MAX +#define FT_ULLONG_MAX ULLONG_MAX +#endif /************************************************************************** diff --git a/thirdparty/freetype/include/freetype/config/integer-types.h b/thirdparty/freetype/include/freetype/config/integer-types.h index a0ca0c95e2..5ef09f1978 100644 --- a/thirdparty/freetype/include/freetype/config/integer-types.h +++ b/thirdparty/freetype/include/freetype/config/integer-types.h @@ -4,7 +4,7 @@ * * FreeType integer types definitions. * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -60,6 +60,18 @@ #endif /* !defined(FT_SIZEOF_LONG) */ +#ifndef FT_SIZEOF_LONG_LONG + + /* The size of a `long long` type if available */ +#if defined( FT_ULLONG_MAX ) && FT_ULLONG_MAX >= 0xFFFFFFFFFFFFFFFFULL +#define FT_SIZEOF_LONG_LONG ( 64 / FT_CHAR_BIT ) +#else +#define FT_SIZEOF_LONG_LONG 0 +#endif + +#endif /* !defined(FT_SIZEOF_LONG_LONG) */ + + /************************************************************************** * * @section: @@ -174,15 +186,17 @@ #endif - /* determine whether we have a 64-bit `int` type for platforms without */ - /* Autoconf */ + /* determine whether we have a 64-bit integer type */ #if FT_SIZEOF_LONG == ( 64 / FT_CHAR_BIT ) - /* `FT_LONG64` must be defined if a 64-bit type is available */ -#define FT_LONG64 #define FT_INT64 long #define FT_UINT64 unsigned long +#elif FT_SIZEOF_LONG_LONG >= ( 64 / FT_CHAR_BIT ) + +#define FT_INT64 long long int +#define FT_UINT64 unsigned long long int + /************************************************************************** * * A 64-bit data type may create compilation problems if you compile in @@ -192,16 +206,9 @@ */ #elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 ) -#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L - -#define FT_LONG64 -#define FT_INT64 long long int -#define FT_UINT64 unsigned long long int - -#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ +#if defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ /* this compiler provides the `__int64` type */ -#define FT_LONG64 #define FT_INT64 __int64 #define FT_UINT64 unsigned __int64 @@ -211,7 +218,6 @@ /* to test the compiler version. */ /* this compiler provides the `__int64` type */ -#define FT_LONG64 #define FT_INT64 __int64 #define FT_UINT64 unsigned __int64 @@ -221,22 +227,20 @@ #elif defined( __MWERKS__ ) /* Metrowerks CodeWarrior */ -#define FT_LONG64 #define FT_INT64 long long int #define FT_UINT64 unsigned long long int #elif defined( __GNUC__ ) /* GCC provides the `long long` type */ -#define FT_LONG64 #define FT_INT64 long long int #define FT_UINT64 unsigned long long int -#endif /* __STDC_VERSION__ >= 199901L */ +#endif /* !__STDC__ */ #endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ -#ifdef FT_LONG64 +#ifdef FT_INT64 typedef FT_INT64 FT_Int64; typedef FT_UINT64 FT_UInt64; #endif diff --git a/thirdparty/freetype/include/freetype/config/mac-support.h b/thirdparty/freetype/include/freetype/config/mac-support.h index 94867088e9..ef58d8b3f0 100644 --- a/thirdparty/freetype/include/freetype/config/mac-support.h +++ b/thirdparty/freetype/include/freetype/config/mac-support.h @@ -4,7 +4,7 @@ * * Mac/OS X support configuration header. * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/config/public-macros.h b/thirdparty/freetype/include/freetype/config/public-macros.h index 6aa673e807..9fbb3274a0 100644 --- a/thirdparty/freetype/include/freetype/config/public-macros.h +++ b/thirdparty/freetype/include/freetype/config/public-macros.h @@ -4,7 +4,7 @@ * * Define a set of compiler macros used in public FreeType headers. * - * Copyright (C) 2020 by + * Copyright (C) 2020-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -103,6 +103,7 @@ FT_BEGIN_HEADER */ #define FT_EXPORT( x ) FT_PUBLIC_FUNCTION_ATTRIBUTE extern x + /* * `FT_UNUSED` indicates that a given parameter is not used -- this is * only used to get rid of unpleasant compiler warnings. @@ -115,6 +116,23 @@ FT_BEGIN_HEADER #endif + /* + * Support for casts in both C and C++. + */ +#ifdef __cplusplus +#define FT_STATIC_CAST( type, var ) static_cast<type>(var) +#define FT_REINTERPRET_CAST( type, var ) reinterpret_cast<type>(var) + +#define FT_STATIC_BYTE_CAST( type, var ) \ + static_cast<type>( static_cast<unsigned char>( var ) ) +#else +#define FT_STATIC_CAST( type, var ) (type)(var) +#define FT_REINTERPRET_CAST( type, var ) (type)(var) + +#define FT_STATIC_BYTE_CAST( type, var ) (type)(unsigned char)(var) +#endif + + FT_END_HEADER #endif /* FREETYPE_CONFIG_PUBLIC_MACROS_H_ */ diff --git a/thirdparty/freetype/include/freetype/freetype.h b/thirdparty/freetype/include/freetype/freetype.h index be191f5aa0..f6c66b94ae 100644 --- a/thirdparty/freetype/include/freetype/freetype.h +++ b/thirdparty/freetype/include/freetype/freetype.h @@ -4,7 +4,7 @@ * * FreeType high-level API and common types (specification only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -33,6 +33,34 @@ FT_BEGIN_HEADER /************************************************************************** * * @section: + * preamble + * + * @title: + * Preamble + * + * @abstract: + * What FreeType is and isn't + * + * @description: + * FreeType is a library that provides access to glyphs in font files. It + * scales the glyph images and their metrics to a requested size, and it + * rasterizes the glyph images to produce pixel or subpixel alpha coverage + * bitmaps. + * + * Note that FreeType is _not_ a text layout engine. You have to use + * higher-level libraries like HarfBuzz, Pango, or ICU for that. + * + * Note also that FreeType does _not_ perform alpha blending or + * compositing the resulting bitmaps or pixmaps by itself. Use your + * favourite graphics library (for example, Cairo or Skia) to further + * process FreeType's output. + * + */ + + + /************************************************************************** + * + * @section: * header_inclusion * * @title: @@ -176,6 +204,7 @@ FT_BEGIN_HEADER * FT_Size_RequestRec * FT_Size_Request * FT_Set_Transform + * FT_Get_Transform * FT_Load_Glyph * FT_Get_Char_Index * FT_Get_First_Char @@ -587,11 +616,12 @@ FT_BEGIN_HEADER */ #ifndef FT_ENC_TAG -#define FT_ENC_TAG( value, a, b, c, d ) \ - value = ( ( (FT_UInt32)(a) << 24 ) | \ - ( (FT_UInt32)(b) << 16 ) | \ - ( (FT_UInt32)(c) << 8 ) | \ - (FT_UInt32)(d) ) + +#define FT_ENC_TAG( value, a, b, c, d ) \ + value = ( ( FT_STATIC_BYTE_CAST( FT_UInt32, a ) << 24 ) | \ + ( FT_STATIC_BYTE_CAST( FT_UInt32, b ) << 16 ) | \ + ( FT_STATIC_BYTE_CAST( FT_UInt32, c ) << 8 ) | \ + FT_STATIC_BYTE_CAST( FT_UInt32, d ) ) #endif /* FT_ENC_TAG */ @@ -701,11 +731,16 @@ FT_BEGIN_HEADER * Same as FT_ENCODING_JOHAB. Deprecated. * * @note: - * By default, FreeType enables a Unicode charmap and tags it with - * `FT_ENCODING_UNICODE` when it is either provided or can be generated - * from PostScript glyph name dictionaries in the font file. All other - * encodings are considered legacy and tagged only if explicitly defined - * in the font file. Otherwise, `FT_ENCODING_NONE` is used. + * When loading a font, FreeType makes a Unicode charmap active if + * possible (either if the font provides such a charmap, or if FreeType + * can synthesize one from PostScript glyph name dictionaries; in either + * case, the charmap is tagged with `FT_ENCODING_UNICODE`). If such a + * charmap is synthesized, it is placed at the first position of the + * charmap array. + * + * All other encodings are considered legacy and tagged only if + * explicitly defined in the font file. Otherwise, `FT_ENCODING_NONE` is + * used. * * `FT_ENCODING_NONE` is set by the BDF and PCF drivers if the charmap is * neither Unicode nor ISO-8859-1 (otherwise it is set to @@ -2065,7 +2100,8 @@ FT_BEGIN_HEADER * The size in bytes of the file in memory. * * pathname :: - * A pointer to an 8-bit file pathname. The pointer is not owned by + * A pointer to an 8-bit file pathname, which must be a C~string (i.e., + * no null bytes except at the very end). The pointer is not owned by * FreeType. * * stream :: @@ -2084,8 +2120,7 @@ FT_BEGIN_HEADER * Extra parameters passed to the font driver when opening a new face. * * @note: - * The stream type is determined by the contents of `flags` that are - * tested in the following order by @FT_Open_Face: + * The stream type is determined by the contents of `flags`: * * If the @FT_OPEN_MEMORY bit is set, assume that this is a memory file * of `memory_size` bytes, located at `memory_address`. The data are not @@ -2098,6 +2133,9 @@ FT_BEGIN_HEADER * Otherwise, if the @FT_OPEN_PATHNAME bit is set, assume that this is a * normal file and use `pathname` to open it. * + * If none of the above bits are set or if multiple are set at the same + * time, the flags are invalid and @FT_Open_Face fails. + * * If the @FT_OPEN_DRIVER bit is set, @FT_Open_Face only tries to open * the file with the driver whose handler is in `driver`. * @@ -2150,6 +2188,13 @@ FT_BEGIN_HEADER * FreeType error code. 0~means success. * * @note: + * The `pathname` string should be recognizable as such by a standard + * `fopen` call on your system; in particular, this means that `pathname` + * must not contain null bytes. If that is not sufficient to address all + * file name possibilities (for example, to handle wide character file + * names on Windows in UTF-16 encoding) you might use @FT_Open_Face to + * pass a memory array or a stream object instead. + * * Use @FT_Done_Face to destroy the created @FT_Face object (along with * its slot and sizes). */ @@ -2270,6 +2315,10 @@ FT_BEGIN_HEADER * See the discussion of reference counters in the description of * @FT_Reference_Face. * + * If `FT_OPEN_STREAM` is set in `args->flags`, the stream in + * `args->stream` is automatically closed before this function returns + * any error (including `FT_Err_Invalid_Argument`). + * * @example: * To loop over all faces, use code similar to the following snippet * (omitting the error handling). @@ -2428,6 +2477,7 @@ FT_BEGIN_HEADER * * @since: * 2.4.2 + * */ FT_EXPORT( FT_Error ) FT_Reference_Face( FT_Face face ); @@ -2874,7 +2924,7 @@ FT_BEGIN_HEADER * * If the font is 'tricky' (see @FT_FACE_FLAG_TRICKY for more), using * `FT_LOAD_NO_SCALE` usually yields meaningless outlines because the - * subglyphs must be scaled and positioned with hinting instructions. + * subglyphs must be scaled and positioned with hinting instructions. * This can be solved by loading the font without `FT_LOAD_NO_SCALE` * and setting the character size to `font->units_per_EM`. * @@ -3132,7 +3182,7 @@ FT_BEGIN_HEADER * necessary to empty the cache after a mode switch to avoid false hits. * */ -#define FT_LOAD_TARGET_( x ) ( (FT_Int32)( (x) & 15 ) << 16 ) +#define FT_LOAD_TARGET_( x ) ( FT_STATIC_CAST( FT_Int32, (x) & 15 ) << 16 ) #define FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL ) #define FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT ) @@ -3151,7 +3201,8 @@ FT_BEGIN_HEADER * @FT_LOAD_TARGET_XXX value. * */ -#define FT_LOAD_TARGET_MODE( x ) ( (FT_Render_Mode)( ( (x) >> 16 ) & 15 ) ) +#define FT_LOAD_TARGET_MODE( x ) \ + FT_STATIC_CAST( FT_Render_Mode, ( (x) >> 16 ) & 15 ) /************************************************************************** @@ -3172,11 +3223,12 @@ FT_BEGIN_HEADER * A pointer to the transformation's 2x2 matrix. Use `NULL` for the * identity matrix. * delta :: - * A pointer to the translation vector. Use `NULL` for the null vector. + * A pointer to the translation vector. Use `NULL` for the null + * vector. * * @note: * This function is provided as a convenience, but keep in mind that - * @FT_Matrix coefficients are only 16.16 fixed point values, which can + * @FT_Matrix coefficients are only 16.16 fixed-point values, which can * limit the accuracy of the results. Using floating-point computations * to perform the transform directly in client code instead will always * yield better numbers. @@ -3197,6 +3249,39 @@ FT_BEGIN_HEADER /************************************************************************** * + * @function: + * FT_Get_Transform + * + * @description: + * Return the transformation that is applied to glyph images when they + * are loaded into a glyph slot through @FT_Load_Glyph. See + * @FT_Set_Transform for more details. + * + * @input: + * face :: + * A handle to the source face object. + * + * @output: + * matrix :: + * A pointer to a transformation's 2x2 matrix. Set this to NULL if you + * are not interested in the value. + * + * delta :: + * A pointer a translation vector. Set this to NULL if you are not + * interested in the value. + * + * @since: + * 2.11 + * + */ + FT_EXPORT( void ) + FT_Get_Transform( FT_Face face, + FT_Matrix* matrix, + FT_Vector* delta ); + + + /************************************************************************** + * * @enum: * FT_Render_Mode * @@ -3213,6 +3298,10 @@ FT_BEGIN_HEADER * correction to correctly render non-monochrome glyph bitmaps onto a * surface; see @FT_Render_Glyph. * + * The @FT_RENDER_MODE_SDF is a special render mode that uses up to 256 + * distance values, indicating the signed distance from the grid position + * to the nearest outline. + * * @values: * FT_RENDER_MODE_NORMAL :: * Default render mode; it corresponds to 8-bit anti-aliased bitmaps. @@ -3238,11 +3327,49 @@ FT_BEGIN_HEADER * bitmaps that are 3~times the height of the original glyph outline in * pixels and use the @FT_PIXEL_MODE_LCD_V mode. * + * FT_RENDER_MODE_SDF :: + * This mode corresponds to 8-bit, single-channel signed distance field + * (SDF) bitmaps. Each pixel in the SDF grid is the value from the + * pixel's position to the nearest glyph's outline. The distances are + * calculated from the center of the pixel and are positive if they are + * filled by the outline (i.e., inside the outline) and negative + * otherwise. Check the note below on how to convert the output values + * to usable data. + * * @note: * The selected render mode only affects vector glyphs of a font. * Embedded bitmaps often have a different pixel mode like * @FT_PIXEL_MODE_MONO. You can use @FT_Bitmap_Convert to transform them * into 8-bit pixmaps. + * + * For @FT_RENDER_MODE_SDF the output bitmap buffer contains normalized + * distances that are packed into unsigned 8-bit values. To get pixel + * values in floating point representation use the following pseudo-C + * code for the conversion. + * + * ``` + * // Load glyph and render using FT_RENDER_MODE_SDF, + * // then use the output buffer as follows. + * + * ... + * FT_Byte buffer = glyph->bitmap->buffer; + * + * + * for pixel in buffer + * { + * // `sd` is the signed distance and `spread` is the current spread; + * // the default spread is 2 and can be changed. + * + * float sd = (float)pixel - 128.0f; + * + * + * // Convert to pixel values. + * sd = ( sd / 128.0f ) * spread; + * + * // Store `sd` in a buffer or use as required. + * } + * + * ``` */ typedef enum FT_Render_Mode_ { @@ -3251,6 +3378,7 @@ FT_BEGIN_HEADER FT_RENDER_MODE_MONO, FT_RENDER_MODE_LCD, FT_RENDER_MODE_LCD_V, + FT_RENDER_MODE_SDF, FT_RENDER_MODE_MAX @@ -3338,7 +3466,8 @@ FT_BEGIN_HEADER * * which is known as the OVER operator. * - * To correctly composite an antialiased pixel of a glyph onto a surface, + * To correctly composite an anti-aliased pixel of a glyph onto a + * surface, * * 1. take the foreground and background colors (e.g., in sRGB space) * and apply gamma to get them in a linear space, @@ -4018,168 +4147,6 @@ FT_BEGIN_HEADER /************************************************************************** * * @section: - * layer_management - * - * @title: - * Glyph Layer Management - * - * @abstract: - * Retrieving and manipulating OpenType's 'COLR' table data. - * - * @description: - * The functions described here allow access of colored glyph layer data - * in OpenType's 'COLR' tables. - */ - - - /************************************************************************** - * - * @struct: - * FT_LayerIterator - * - * @description: - * This iterator object is needed for @FT_Get_Color_Glyph_Layer. - * - * @fields: - * num_layers :: - * The number of glyph layers for the requested glyph index. Will be - * set by @FT_Get_Color_Glyph_Layer. - * - * layer :: - * The current layer. Will be set by @FT_Get_Color_Glyph_Layer. - * - * p :: - * An opaque pointer into 'COLR' table data. The caller must set this - * to `NULL` before the first call of @FT_Get_Color_Glyph_Layer. - */ - typedef struct FT_LayerIterator_ - { - FT_UInt num_layers; - FT_UInt layer; - FT_Byte* p; - - } FT_LayerIterator; - - - /************************************************************************** - * - * @function: - * FT_Get_Color_Glyph_Layer - * - * @description: - * This is an interface to the 'COLR' table in OpenType fonts to - * iteratively retrieve the colored glyph layers associated with the - * current glyph slot. - * - * https://docs.microsoft.com/en-us/typography/opentype/spec/colr - * - * The glyph layer data for a given glyph index, if present, provides an - * alternative, multi-color glyph representation: Instead of rendering - * the outline or bitmap with the given glyph index, glyphs with the - * indices and colors returned by this function are rendered layer by - * layer. - * - * The returned elements are ordered in the z~direction from bottom to - * top; the 'n'th element should be rendered with the associated palette - * color and blended on top of the already rendered layers (elements 0, - * 1, ..., n-1). - * - * @input: - * face :: - * A handle to the parent face object. - * - * base_glyph :: - * The glyph index the colored glyph layers are associated with. - * - * @inout: - * iterator :: - * An @FT_LayerIterator object. For the first call you should set - * `iterator->p` to `NULL`. For all following calls, simply use the - * same object again. - * - * @output: - * aglyph_index :: - * The glyph index of the current layer. - * - * acolor_index :: - * The color index into the font face's color palette of the current - * layer. The value 0xFFFF is special; it doesn't reference a palette - * entry but indicates that the text foreground color should be used - * instead (to be set up by the application outside of FreeType). - * - * The color palette can be retrieved with @FT_Palette_Select. - * - * @return: - * Value~1 if everything is OK. If there are no more layers (or if there - * are no layers at all), value~0 gets returned. In case of an error, - * value~0 is returned also. - * - * @note: - * This function is necessary if you want to handle glyph layers by - * yourself. In particular, functions that operate with @FT_GlyphRec - * objects (like @FT_Get_Glyph or @FT_Glyph_To_Bitmap) don't have access - * to this information. - * - * Note that @FT_Render_Glyph is able to handle colored glyph layers - * automatically if the @FT_LOAD_COLOR flag is passed to a previous call - * to @FT_Load_Glyph. [This is an experimental feature.] - * - * @example: - * ``` - * FT_Color* palette; - * FT_LayerIterator iterator; - * - * FT_Bool have_layers; - * FT_UInt layer_glyph_index; - * FT_UInt layer_color_index; - * - * - * error = FT_Palette_Select( face, palette_index, &palette ); - * if ( error ) - * palette = NULL; - * - * iterator.p = NULL; - * have_layers = FT_Get_Color_Glyph_Layer( face, - * glyph_index, - * &layer_glyph_index, - * &layer_color_index, - * &iterator ); - * - * if ( palette && have_layers ) - * { - * do - * { - * FT_Color layer_color; - * - * - * if ( layer_color_index == 0xFFFF ) - * layer_color = text_foreground_color; - * else - * layer_color = palette[layer_color_index]; - * - * // Load and render glyph `layer_glyph_index', then - * // blend resulting pixmap (using color `layer_color') - * // with previously created pixmaps. - * - * } while ( FT_Get_Color_Glyph_Layer( face, - * glyph_index, - * &layer_glyph_index, - * &layer_color_index, - * &iterator ) ); - * } - * ``` - */ - FT_EXPORT( FT_Bool ) - FT_Get_Color_Glyph_Layer( FT_Face face, - FT_UInt base_glyph, - FT_UInt *aglyph_index, - FT_UInt *acolor_index, - FT_LayerIterator* iterator ); - - - /************************************************************************** - * - * @section: * base_interface * */ @@ -4267,6 +4234,7 @@ FT_BEGIN_HEADER * * @since: * 2.3.8 + * */ FT_EXPORT( FT_UShort ) FT_Get_FSType_Flags( FT_Face face ); @@ -4360,6 +4328,7 @@ FT_BEGIN_HEADER * * @since: * 2.3.6 + * */ FT_EXPORT( FT_UInt ) FT_Face_GetCharVariantIndex( FT_Face face, @@ -4396,6 +4365,7 @@ FT_BEGIN_HEADER * * @since: * 2.3.6 + * */ FT_EXPORT( FT_Int ) FT_Face_GetCharVariantIsDefault( FT_Face face, @@ -4427,6 +4397,7 @@ FT_BEGIN_HEADER * * @since: * 2.3.6 + * */ FT_EXPORT( FT_UInt32* ) FT_Face_GetVariantSelectors( FT_Face face ); @@ -4460,6 +4431,7 @@ FT_BEGIN_HEADER * * @since: * 2.3.6 + * */ FT_EXPORT( FT_UInt32* ) FT_Face_GetVariantsOfChar( FT_Face face, @@ -4494,6 +4466,7 @@ FT_BEGIN_HEADER * * @since: * 2.3.6 + * */ FT_EXPORT( FT_UInt32* ) FT_Face_GetCharsOfVariant( FT_Face face, @@ -4766,8 +4739,8 @@ FT_BEGIN_HEADER * */ #define FREETYPE_MAJOR 2 -#define FREETYPE_MINOR 10 -#define FREETYPE_PATCH 4 +#define FREETYPE_MINOR 11 +#define FREETYPE_PATCH 1 /************************************************************************** @@ -4829,6 +4802,7 @@ FT_BEGIN_HEADER * * @since: * 2.3.5 + * */ FT_EXPORT( FT_Bool ) FT_Face_CheckTrueTypePatents( FT_Face face ); @@ -4857,6 +4831,7 @@ FT_BEGIN_HEADER * * @since: * 2.3.5 + * */ FT_EXPORT( FT_Bool ) FT_Face_SetUnpatentedHinting( FT_Face face, diff --git a/thirdparty/freetype/include/freetype/ftadvanc.h b/thirdparty/freetype/include/freetype/ftadvanc.h index f166bc6f99..3a13bd3de4 100644 --- a/thirdparty/freetype/include/freetype/ftadvanc.h +++ b/thirdparty/freetype/include/freetype/ftadvanc.h @@ -4,7 +4,7 @@ * * Quick computation of advance widths (specification only). * - * Copyright (C) 2008-2020 by + * Copyright (C) 2008-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftbbox.h b/thirdparty/freetype/include/freetype/ftbbox.h index fda1ad94a5..713aedb15f 100644 --- a/thirdparty/freetype/include/freetype/ftbbox.h +++ b/thirdparty/freetype/include/freetype/ftbbox.h @@ -4,7 +4,7 @@ * * FreeType exact bbox computation (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftbdf.h b/thirdparty/freetype/include/freetype/ftbdf.h index 2e1daeeaaf..c428506405 100644 --- a/thirdparty/freetype/include/freetype/ftbdf.h +++ b/thirdparty/freetype/include/freetype/ftbdf.h @@ -4,7 +4,7 @@ * * FreeType API for accessing BDF-specific strings (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftbitmap.h b/thirdparty/freetype/include/freetype/ftbitmap.h index 282c22e1cf..11c45b0ed2 100644 --- a/thirdparty/freetype/include/freetype/ftbitmap.h +++ b/thirdparty/freetype/include/freetype/ftbitmap.h @@ -4,7 +4,7 @@ * * FreeType utility functions for bitmaps (specification). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftbzip2.h b/thirdparty/freetype/include/freetype/ftbzip2.h index eb6a5a55d1..afd2a82afb 100644 --- a/thirdparty/freetype/include/freetype/ftbzip2.h +++ b/thirdparty/freetype/include/freetype/ftbzip2.h @@ -4,7 +4,7 @@ * * Bzip2-compressed stream support. * - * Copyright (C) 2010-2020 by + * Copyright (C) 2010-2021 by * Joel Klinghed. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftcache.h b/thirdparty/freetype/include/freetype/ftcache.h index 6047275205..70399a328a 100644 --- a/thirdparty/freetype/include/freetype/ftcache.h +++ b/thirdparty/freetype/include/freetype/ftcache.h @@ -4,7 +4,7 @@ * * FreeType Cache subsystem (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -86,8 +86,8 @@ FT_BEGIN_HEADER * later use @FTC_CMapCache_Lookup to perform the equivalent of * @FT_Get_Char_Index, only much faster. * - * If you want to use the @FT_Glyph caching, call @FTC_ImageCache, then - * later use @FTC_ImageCache_Lookup to retrieve the corresponding + * If you want to use the @FT_Glyph caching, call @FTC_ImageCache_New, + * then later use @FTC_ImageCache_Lookup to retrieve the corresponding * @FT_Glyph objects from the cache. * * If you need lots of small bitmaps, it is much more memory efficient to diff --git a/thirdparty/freetype/include/freetype/ftchapters.h b/thirdparty/freetype/include/freetype/ftchapters.h index 2ee26973e4..4f32cc88c8 100644 --- a/thirdparty/freetype/include/freetype/ftchapters.h +++ b/thirdparty/freetype/include/freetype/ftchapters.h @@ -15,6 +15,7 @@ * General Remarks * * @sections: + * preamble * header_inclusion * user_allocation * @@ -123,6 +124,7 @@ * gzip * lzw * bzip2 + * debugging_apis * */ diff --git a/thirdparty/freetype/include/freetype/ftcid.h b/thirdparty/freetype/include/freetype/ftcid.h index a29fb33306..9a415bd98b 100644 --- a/thirdparty/freetype/include/freetype/ftcid.h +++ b/thirdparty/freetype/include/freetype/ftcid.h @@ -4,7 +4,7 @@ * * FreeType API for accessing CID font information (specification). * - * Copyright (C) 2007-2020 by + * Copyright (C) 2007-2021 by * Dereg Clegg and Michael Toftdal. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftcolor.h b/thirdparty/freetype/include/freetype/ftcolor.h index ecc6485e5a..08dbac0ccc 100644 --- a/thirdparty/freetype/include/freetype/ftcolor.h +++ b/thirdparty/freetype/include/freetype/ftcolor.h @@ -4,7 +4,7 @@ * * FreeType's glyph color management (specification). * - * Copyright (C) 2018-2020 by + * Copyright (C) 2018-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -302,6 +302,1411 @@ FT_BEGIN_HEADER FT_Palette_Set_Foreground_Color( FT_Face face, FT_Color foreground_color ); + + /************************************************************************** + * + * @section: + * layer_management + * + * @title: + * Glyph Layer Management + * + * @abstract: + * Retrieving and manipulating OpenType's 'COLR' table data. + * + * @description: + * The functions described here allow access of colored glyph layer data + * in OpenType's 'COLR' tables. + */ + + + /************************************************************************** + * + * @struct: + * FT_LayerIterator + * + * @description: + * This iterator object is needed for @FT_Get_Color_Glyph_Layer. + * + * @fields: + * num_layers :: + * The number of glyph layers for the requested glyph index. Will be + * set by @FT_Get_Color_Glyph_Layer. + * + * layer :: + * The current layer. Will be set by @FT_Get_Color_Glyph_Layer. + * + * p :: + * An opaque pointer into 'COLR' table data. The caller must set this + * to `NULL` before the first call of @FT_Get_Color_Glyph_Layer. + */ + typedef struct FT_LayerIterator_ + { + FT_UInt num_layers; + FT_UInt layer; + FT_Byte* p; + + } FT_LayerIterator; + + + /************************************************************************** + * + * @function: + * FT_Get_Color_Glyph_Layer + * + * @description: + * This is an interface to the 'COLR' table in OpenType fonts to + * iteratively retrieve the colored glyph layers associated with the + * current glyph slot. + * + * https://docs.microsoft.com/en-us/typography/opentype/spec/colr + * + * The glyph layer data for a given glyph index, if present, provides an + * alternative, multi-color glyph representation: Instead of rendering + * the outline or bitmap with the given glyph index, glyphs with the + * indices and colors returned by this function are rendered layer by + * layer. + * + * The returned elements are ordered in the z~direction from bottom to + * top; the 'n'th element should be rendered with the associated palette + * color and blended on top of the already rendered layers (elements 0, + * 1, ..., n-1). + * + * @input: + * face :: + * A handle to the parent face object. + * + * base_glyph :: + * The glyph index the colored glyph layers are associated with. + * + * @inout: + * iterator :: + * An @FT_LayerIterator object. For the first call you should set + * `iterator->p` to `NULL`. For all following calls, simply use the + * same object again. + * + * @output: + * aglyph_index :: + * The glyph index of the current layer. + * + * acolor_index :: + * The color index into the font face's color palette of the current + * layer. The value 0xFFFF is special; it doesn't reference a palette + * entry but indicates that the text foreground color should be used + * instead (to be set up by the application outside of FreeType). + * + * The color palette can be retrieved with @FT_Palette_Select. + * + * @return: + * Value~1 if everything is OK. If there are no more layers (or if there + * are no layers at all), value~0 gets returned. In case of an error, + * value~0 is returned also. + * + * @note: + * This function is necessary if you want to handle glyph layers by + * yourself. In particular, functions that operate with @FT_GlyphRec + * objects (like @FT_Get_Glyph or @FT_Glyph_To_Bitmap) don't have access + * to this information. + * + * Note that @FT_Render_Glyph is able to handle colored glyph layers + * automatically if the @FT_LOAD_COLOR flag is passed to a previous call + * to @FT_Load_Glyph. [This is an experimental feature.] + * + * @example: + * ``` + * FT_Color* palette; + * FT_LayerIterator iterator; + * + * FT_Bool have_layers; + * FT_UInt layer_glyph_index; + * FT_UInt layer_color_index; + * + * + * error = FT_Palette_Select( face, palette_index, &palette ); + * if ( error ) + * palette = NULL; + * + * iterator.p = NULL; + * have_layers = FT_Get_Color_Glyph_Layer( face, + * glyph_index, + * &layer_glyph_index, + * &layer_color_index, + * &iterator ); + * + * if ( palette && have_layers ) + * { + * do + * { + * FT_Color layer_color; + * + * + * if ( layer_color_index == 0xFFFF ) + * layer_color = text_foreground_color; + * else + * layer_color = palette[layer_color_index]; + * + * // Load and render glyph `layer_glyph_index', then + * // blend resulting pixmap (using color `layer_color') + * // with previously created pixmaps. + * + * } while ( FT_Get_Color_Glyph_Layer( face, + * glyph_index, + * &layer_glyph_index, + * &layer_color_index, + * &iterator ) ); + * } + * ``` + */ + FT_EXPORT( FT_Bool ) + FT_Get_Color_Glyph_Layer( FT_Face face, + FT_UInt base_glyph, + FT_UInt *aglyph_index, + FT_UInt *acolor_index, + FT_LayerIterator* iterator ); + + + /************************************************************************** + * + * @enum: + * FT_PaintFormat + * + * @description: + * Enumeration describing the different paint format types of the v1 + * extensions to the 'COLR' table, see + * 'https://github.com/googlefonts/colr-gradients-spec'. + * + * The enumeration values losely correspond with the format numbers of + * the specification: FreeType always returns a fully specified 'Paint' + * structure for the 'Transform', 'Translate', 'Scale', 'Rotate', and + * 'Skew' table types even though the specification has different formats + * depending on whether or not a center is specified, whether the scale + * is uniform in x and y~direction or not, etc. Also, only non-variable + * format identifiers are listed in this enumeration; as soon as support + * for variable 'COLR' v1 fonts is implemented, interpolation is + * performed dependent on axis coordinates, which are configured on the + * @FT_Face through @FT_Set_Var_Design_Coordinates. This implies that + * always static, readily interpolated values are returned in the 'Paint' + * structures. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef enum FT_PaintFormat_ + { + FT_COLR_PAINTFORMAT_COLR_LAYERS = 1, + FT_COLR_PAINTFORMAT_SOLID = 2, + FT_COLR_PAINTFORMAT_LINEAR_GRADIENT = 4, + FT_COLR_PAINTFORMAT_RADIAL_GRADIENT = 6, + FT_COLR_PAINTFORMAT_SWEEP_GRADIENT = 8, + FT_COLR_PAINTFORMAT_GLYPH = 10, + FT_COLR_PAINTFORMAT_COLR_GLYPH = 11, + FT_COLR_PAINTFORMAT_TRANSFORM = 12, + FT_COLR_PAINTFORMAT_TRANSLATE = 14, + FT_COLR_PAINTFORMAT_SCALE = 16, + FT_COLR_PAINTFORMAT_ROTATE = 24, + FT_COLR_PAINTFORMAT_SKEW = 28, + FT_COLR_PAINTFORMAT_COMPOSITE = 32, + FT_COLR_PAINT_FORMAT_MAX = 33, + FT_COLR_PAINTFORMAT_UNSUPPORTED = 255 + + } FT_PaintFormat; + + + /************************************************************************** + * + * @struct: + * FT_ColorStopIterator + * + * @description: + * This iterator object is needed for @FT_Get_Colorline_Stops. It keeps + * state while iterating over the stops of an @FT_ColorLine, + * representing the `ColorLine` struct of the v1 extensions to 'COLR', + * see 'https://github.com/googlefonts/colr-gradients-spec'. + * + * @fields: + * num_color_stops :: + * The number of color stops for the requested glyph index. Set by + * @FT_Get_Colorline_Stops. + * + * current_color_stop :: + * The current color stop. Set by @FT_Get_Colorline_Stops. + * + * p :: + * An opaque pointer into 'COLR' table data. The caller must set this + * to `NULL` before the first call of @FT_Get_Colorline_Stops. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_ColorStopIterator_ + { + FT_UInt num_color_stops; + FT_UInt current_color_stop; + + FT_Byte* p; + + } FT_ColorStopIterator; + + + /************************************************************************** + * + * @struct: + * FT_ColorIndex + * + * @description: + * A structure representing a `ColorIndex` value of the 'COLR' v1 + * extensions, see 'https://github.com/googlefonts/colr-gradients-spec'. + * + * @fields: + * palette_index :: + * The palette index into a 'CPAL' palette. + * + * alpha :: + * Alpha transparency value multiplied with the value from 'CPAL'. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_ColorIndex_ + { + FT_UInt16 palette_index; + FT_F2Dot14 alpha; + + } FT_ColorIndex; + + + /************************************************************************** + * + * @struct: + * FT_ColorStop + * + * @description: + * A structure representing a `ColorStop` value of the 'COLR' v1 + * extensions, see 'https://github.com/googlefonts/colr-gradients-spec'. + * + * @fields: + * stop_offset :: + * The stop offset between 0 and 1 along the gradient. + * + * color :: + * The color information for this stop, see @FT_ColorIndex. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_ColorStop_ + { + FT_F2Dot14 stop_offset; + FT_ColorIndex color; + + } FT_ColorStop; + + + /************************************************************************** + * + * @enum: + * FT_PaintExtend + * + * @description: + * An enumeration representing the 'Extend' mode of the 'COLR' v1 + * extensions, see 'https://github.com/googlefonts/colr-gradients-spec'. + * It describes how the gradient fill continues at the other boundaries. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef enum FT_PaintExtend_ + { + FT_COLR_PAINT_EXTEND_PAD = 0, + FT_COLR_PAINT_EXTEND_REPEAT = 1, + FT_COLR_PAINT_EXTEND_REFLECT = 2 + + } FT_PaintExtend; + + + /************************************************************************** + * + * @struct: + * FT_ColorLine + * + * @description: + * A structure representing a `ColorLine` value of the 'COLR' v1 + * extensions, see 'https://github.com/googlefonts/colr-gradients-spec'. + * It describes a list of color stops along the defined gradient. + * + * @fields: + * extend :: + * The extend mode at the outer boundaries, see @FT_PaintExtend. + * + * color_stop_iterator :: + * The @FT_ColorStopIterator used to enumerate and retrieve the + * actual @FT_ColorStop's. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_ColorLine_ + { + FT_PaintExtend extend; + FT_ColorStopIterator color_stop_iterator; + + } FT_ColorLine; + + + /************************************************************************** + * + * @struct: + * FT_Affine23 + * + * @description: + * A structure used to store a 2x3 matrix. Coefficients are in + * 16.16 fixed-point format. The computation performed is + * + * ``` + * x' = x*xx + y*xy + dx + * y' = x*yx + y*yy + dy + * ``` + * + * @fields: + * xx :: + * Matrix coefficient. + * + * xy :: + * Matrix coefficient. + * + * dx :: + * x translation. + * + * yx :: + * Matrix coefficient. + * + * yy :: + * Matrix coefficient. + * + * dy :: + * y translation. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_Affine_23_ + { + FT_Fixed xx, xy, dx; + FT_Fixed yx, yy, dy; + + } FT_Affine23; + + + /************************************************************************** + * + * @enum: + * FT_Composite_Mode + * + * @description: + * An enumeration listing the 'COLR' v1 composite modes used in + * @FT_PaintComposite. For more details on each paint mode, see + * 'https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators'. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef enum FT_Composite_Mode_ + { + FT_COLR_COMPOSITE_CLEAR = 0, + FT_COLR_COMPOSITE_SRC = 1, + FT_COLR_COMPOSITE_DEST = 2, + FT_COLR_COMPOSITE_SRC_OVER = 3, + FT_COLR_COMPOSITE_DEST_OVER = 4, + FT_COLR_COMPOSITE_SRC_IN = 5, + FT_COLR_COMPOSITE_DEST_IN = 6, + FT_COLR_COMPOSITE_SRC_OUT = 7, + FT_COLR_COMPOSITE_DEST_OUT = 8, + FT_COLR_COMPOSITE_SRC_ATOP = 9, + FT_COLR_COMPOSITE_DEST_ATOP = 10, + FT_COLR_COMPOSITE_XOR = 11, + FT_COLR_COMPOSITE_PLUS = 12, + FT_COLR_COMPOSITE_SCREEN = 13, + FT_COLR_COMPOSITE_OVERLAY = 14, + FT_COLR_COMPOSITE_DARKEN = 15, + FT_COLR_COMPOSITE_LIGHTEN = 16, + FT_COLR_COMPOSITE_COLOR_DODGE = 17, + FT_COLR_COMPOSITE_COLOR_BURN = 18, + FT_COLR_COMPOSITE_HARD_LIGHT = 19, + FT_COLR_COMPOSITE_SOFT_LIGHT = 20, + FT_COLR_COMPOSITE_DIFFERENCE = 21, + FT_COLR_COMPOSITE_EXCLUSION = 22, + FT_COLR_COMPOSITE_MULTIPLY = 23, + FT_COLR_COMPOSITE_HSL_HUE = 24, + FT_COLR_COMPOSITE_HSL_SATURATION = 25, + FT_COLR_COMPOSITE_HSL_COLOR = 26, + FT_COLR_COMPOSITE_HSL_LUMINOSITY = 27, + FT_COLR_COMPOSITE_MAX = 28 + + } FT_Composite_Mode; + + + /************************************************************************** + * + * @struct: + * FT_OpaquePaint + * + * @description: + * A structure representing an offset to a `Paint` value stored in any + * of the paint tables of a 'COLR' v1 font. Compare Offset<24> there. + * When 'COLR' v1 paint tables represented by FreeType objects such as + * @FT_PaintColrLayers, @FT_PaintComposite, or @FT_PaintTransform + * reference downstream nested paint tables, we do not immediately + * retrieve them but encapsulate their location in this type. Use + * @FT_Get_Paint to retrieve the actual @FT_COLR_Paint object that + * describes the details of the respective paint table. + * + * @fields: + * p :: + * An internal offset to a Paint table, needs to be set to NULL before + * passing this struct as an argument to @FT_Get_Paint. + * + * insert_root_transform :: + * An internal boolean to track whether an initial root transform is + * to be provided. Do not set this value. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_Opaque_Paint_ + { + FT_Byte* p; + FT_Bool insert_root_transform; + } FT_OpaquePaint; + + + /************************************************************************** + * + * @struct: + * FT_PaintColrLayers + * + * @description: + * A structure representing a `PaintColrLayers` table of a 'COLR' v1 + * font. This table describes a set of layers that are to be composited + * with composite mode `FT_COLR_COMPOSITE_SRC_OVER`. The return value + * of this function is an @FT_LayerIterator initialized so that it can + * be used with @FT_Get_Paint_Layers to retrieve the @FT_OpaquePaint + * objects as references to each layer. + * + * @fields: + * layer_iterator :: + * The layer iterator that describes the layers of this paint. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_PaintColrLayers_ + { + FT_LayerIterator layer_iterator; + + } FT_PaintColrLayers; + + + /************************************************************************** + * + * @struct: + * FT_PaintSolid + * + * @description: + * A structure representing a `PaintSolid` value of the 'COLR' v1 + * extensions, see 'https://github.com/googlefonts/colr-gradients-spec'. + * Using a `PaintSolid` value means that the glyph layer filled with + * this paint is solid-colored and does not contain a gradient. + * + * @fields: + * color :: + * The color information for this solid paint, see @FT_ColorIndex. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_PaintSolid_ + { + FT_ColorIndex color; + + } FT_PaintSolid; + + + /************************************************************************** + * + * @struct: + * FT_PaintLinearGradient + * + * @description: + * A structure representing a `PaintLinearGradient` value of the 'COLR' + * v1 extensions, see + * 'https://github.com/googlefonts/colr-gradients-spec'. The glyph + * layer filled with this paint is drawn filled with a linear gradient. + * + * @fields: + * colorline :: + * The @FT_ColorLine information for this paint, i.e., the list of + * color stops along the gradient. + * + * p0 :: + * The starting point of the gradient definition in font units + * represented as a 16.16 fixed-point `FT_Vector`. + * + * p1 :: + * The end point of the gradient definition in font units + * represented as a 16.16 fixed-point `FT_Vector`. + * + * p2 :: + * Optional point~p2 to rotate the gradient in font units + * represented as a 16.16 fixed-point `FT_Vector`. + * Otherwise equal to~p0. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_PaintLinearGradient_ + { + FT_ColorLine colorline; + + /* TODO: Potentially expose those as x0, y0 etc. */ + FT_Vector p0; + FT_Vector p1; + FT_Vector p2; + + } FT_PaintLinearGradient; + + + /************************************************************************** + * + * @struct: + * FT_PaintRadialGradient + * + * @description: + * A structure representing a `PaintRadialGradient` value of the 'COLR' + * v1 extensions, see + * 'https://github.com/googlefonts/colr-gradients-spec'. The glyph + * layer filled with this paint is drawn filled filled with a radial + * gradient. + * + * @fields: + * colorline :: + * The @FT_ColorLine information for this paint, i.e., the list of + * color stops along the gradient. + * + * c0 :: + * The center of the starting point of the radial gradient in font + * units represented as a 16.16 fixed-point `FT_Vector`. + * + * r0 :: + * The radius of the starting circle of the radial gradient in font + * units represented as a 16.16 fixed-point value. + * + * c1 :: + * The center of the end point of the radial gradient in font units + * represented as a 16.16 fixed-point `FT_Vector`. + * + * r1 :: + * The radius of the end circle of the radial gradient in font + * units represented as a 16.16 fixed-point value. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_PaintRadialGradient_ + { + FT_ColorLine colorline; + + FT_Vector c0; + FT_Pos r0; + FT_Vector c1; + FT_Pos r1; + + } FT_PaintRadialGradient; + + + /************************************************************************** + * + * @struct: + * FT_PaintSweepGradient + * + * @description: + * A structure representing a `PaintSweepGradient` value of the 'COLR' + * v1 extensions, see + * 'https://github.com/googlefonts/colr-gradients-spec'. The glyph + * layer filled with this paint is drawn filled with a sweep gradient + * from `start_angle` to `end_angle`. + * + * @fields: + * colorline :: + * The @FT_ColorLine information for this paint, i.e., the list of + * color stops along the gradient. + * + * center :: + * The center of the sweep gradient in font units represented as a + * vector of 16.16 fixed-point values. + * + * start_angle :: + * The start angle of the sweep gradient in 16.16 fixed-point + * format specifying degrees divided by 180.0 (as in the + * spec). Multiply by 180.0f to receive degrees value. Values are + * given counter-clockwise, starting from the (positive) y~axis. + * + * end_angle :: + * The end angle of the sweep gradient in 16.16 fixed-point + * format specifying degrees divided by 180.0 (as in the + * spec). Multiply by 180.0f to receive degrees value. Values are + * given counter-clockwise, starting from the (positive) y~axis. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_PaintSweepGradient_ + { + FT_ColorLine colorline; + + FT_Vector center; + FT_Fixed start_angle; + FT_Fixed end_angle; + + } FT_PaintSweepGradient; + + + /************************************************************************** + * + * @struct: + * FT_PaintGlyph + * + * @description: + * A structure representing a 'COLR' v1 `PaintGlyph` paint table. + * + * @fields: + * paint :: + * An opaque paint object pointing to a `Paint` table that serves as + * the fill for the glyph ID. + * + * glyphID :: + * The glyph ID from the 'glyf' table, which serves as the contour + * information that is filled with paint. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_PaintGlyph_ + { + FT_OpaquePaint paint; + FT_UInt glyphID; + + } FT_PaintGlyph; + + + /************************************************************************** + * + * @struct: + * FT_PaintColrGlyph + * + * @description: + * A structure representing a 'COLR' v1 `PaintColorGlyph` paint table. + * + * @fields: + * glyphID :: + * The glyph ID from the `BaseGlyphV1List` table that is drawn for + * this paint. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_PaintColrGlyph_ + { + FT_UInt glyphID; + + } FT_PaintColrGlyph; + + + /************************************************************************** + * + * @struct: + * FT_PaintTransform + * + * @description: + * A structure representing a 'COLR' v1 `PaintTransform` paint table. + * + * @fields: + * paint :: + * An opaque paint that is subject to being transformed. + * + * affine :: + * A 2x3 transformation matrix in @FT_Affine23 format containing + * 16.16 fixed-point values. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_PaintTransform_ + { + FT_OpaquePaint paint; + FT_Affine23 affine; + + } FT_PaintTransform; + + + /************************************************************************** + * + * @struct: + * FT_PaintTranslate + * + * @description: + * A structure representing a 'COLR' v1 `PaintTranslate` paint table. + * Used for translating downstream paints by a given x and y~delta. + * + * @fields: + * paint :: + * An @FT_OpaquePaint object referencing the paint that is to be + * rotated. + * + * dx :: + * Translation in x~direction in font units represented as a + * 16.16 fixed-point value. + * + * dy :: + * Translation in y~direction in font units represented as a + * 16.16 fixed-point value. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_PaintTranslate_ + { + FT_OpaquePaint paint; + + FT_Fixed dx; + FT_Fixed dy; + + } FT_PaintTranslate; + + + /************************************************************************** + * + * @struct: + * FT_PaintScale + * + * @description: + * A structure representing all of the 'COLR' v1 'PaintScale*' paint + * tables. Used for scaling downstream paints by a given x and y~scale, + * with a given center. This structure is used for all 'PaintScale*' + * types that are part of specification; fields of this structure are + * filled accordingly. If there is a center, the center values are set, + * otherwise they are set to the zero coordinate. If the source font + * file has 'PaintScaleUniform*' set, the scale values are set + * accordingly to the same value. + * + * @fields: + * paint :: + * An @FT_OpaquePaint object referencing the paint that is to be + * scaled. + * + * scale_x :: + * Scale factor in x~direction represented as a + * 16.16 fixed-point value. + * + * scale_y :: + * Scale factor in y~direction represented as a + * 16.16 fixed-point value. + * + * center_x :: + * x~coordinate of center point to scale from represented as a + * 16.16 fixed-point value. + * + * center_y :: + * y~coordinate of center point to scale from represented as a + * 16.16 fixed-point value. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward-compatibility of both the API and ABI. + * + */ + typedef struct FT_PaintScale_ + { + FT_OpaquePaint paint; + + FT_Fixed scale_x; + FT_Fixed scale_y; + + FT_Fixed center_x; + FT_Fixed center_y; + + } FT_PaintScale; + + + /************************************************************************** + * + * @struct: + * FT_PaintRotate + * + * @description: + * A structure representing a 'COLR' v1 `PaintRotate` paint table. Used + * for rotating downstream paints with a given center and angle. + * + * @fields: + * paint :: + * An @FT_OpaquePaint object referencing the paint that is to be + * rotated. + * + * angle :: + * The rotation angle that is to be applied in degrees divided by + * 180.0 (as in the spec) represented as a 16.16 fixed-point + * value. Multiply by 180.0f to receive degrees value. + * + * center_x :: + * The x~coordinate of the pivot point of the rotation in font + * units) represented as a 16.16 fixed-point value. + * + * center_y :: + * The y~coordinate of the pivot point of the rotation in font + * units represented as a 16.16 fixed-point value. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + + typedef struct FT_PaintRotate_ + { + FT_OpaquePaint paint; + + FT_Fixed angle; + + FT_Fixed center_x; + FT_Fixed center_y; + + } FT_PaintRotate; + + + /************************************************************************** + * + * @struct: + * FT_PaintSkew + * + * @description: + * A structure representing a 'COLR' v1 `PaintSkew` paint table. Used + * for skewing or shearing downstream paints by a given center and + * angle. + * + * @fields: + * paint :: + * An @FT_OpaquePaint object referencing the paint that is to be + * skewed. + * + * x_skew_angle :: + * The skewing angle in x~direction in degrees divided by 180.0 + * (as in the spec) represented as a 16.16 fixed-point + * value. Multiply by 180.0f to receive degrees. + * + * y_skew_angle :: + * The skewing angle in y~direction in degrees divided by 180.0 + * (as in the spec) represented as a 16.16 fixed-point + * value. Multiply by 180.0f to receive degrees. + * + * center_x :: + * The x~coordinate of the pivot point of the skew in font units + * represented as a 16.16 fixed-point value. + * + * center_y :: + * The y~coordinate of the pivot point of the skew in font units + * represented as a 16.16 fixed-point value. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_PaintSkew_ + { + FT_OpaquePaint paint; + + FT_Fixed x_skew_angle; + FT_Fixed y_skew_angle; + + FT_Fixed center_x; + FT_Fixed center_y; + + } FT_PaintSkew; + + + /************************************************************************** + * + * @struct: + * FT_PaintComposite + * + * @description: + * A structure representing a 'COLR'v1 `PaintComposite` paint table. + * Used for compositing two paints in a 'COLR' v1 directed acycling + * graph. + * + * @fields: + * source_paint :: + * An @FT_OpaquePaint object referencing the source that is to be + * composited. + * + * composite_mode :: + * An @FT_Composite_Mode enum value determining the composition + * operation. + * + * backdrop_paint :: + * An @FT_OpaquePaint object referencing the backdrop paint that + * `source_paint` is composited onto. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_PaintComposite_ + { + FT_OpaquePaint source_paint; + FT_Composite_Mode composite_mode; + FT_OpaquePaint backdrop_paint; + + } FT_PaintComposite; + + + /************************************************************************** + * + * @union: + * FT_COLR_Paint + * + * @description: + * A union object representing format and details of a paint table of a + * 'COLR' v1 font, see + * 'https://github.com/googlefonts/colr-gradients-spec'. Use + * @FT_Get_Paint to retrieve a @FT_COLR_Paint for an @FT_OpaquePaint + * object. + * + * @fields: + * format :: + * The gradient format for this Paint structure. + * + * u :: + * Union of all paint table types: + * + * * @FT_PaintColrLayers + * * @FT_PaintGlyph + * * @FT_PaintSolid + * * @FT_PaintLinearGradient + * * @FT_PaintRadialGradient + * * @FT_PaintSweepGradient + * * @FT_PaintTransform + * * @FT_PaintTranslate + * * @FT_PaintRotate + * * @FT_PaintSkew + * * @FT_PaintComposite + * * @FT_PaintColrGlyph + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_COLR_Paint_ + { + FT_PaintFormat format; + + union + { + FT_PaintColrLayers colr_layers; + FT_PaintGlyph glyph; + FT_PaintSolid solid; + FT_PaintLinearGradient linear_gradient; + FT_PaintRadialGradient radial_gradient; + FT_PaintSweepGradient sweep_gradient; + FT_PaintTransform transform; + FT_PaintTranslate translate; + FT_PaintScale scale; + FT_PaintRotate rotate; + FT_PaintSkew skew; + FT_PaintComposite composite; + FT_PaintColrGlyph colr_glyph; + + } u; + + } FT_COLR_Paint; + + + /************************************************************************** + * + * @enum: + * FT_Color_Root_Transform + * + * @description: + * An enumeration to specify whether @FT_Get_Color_Glyph_Paint is to + * return a root transform to configure the client's graphics context + * matrix. + * + * @values: + * FT_COLOR_INCLUDE_ROOT_TRANSFORM :: + * Do include the root transform as the initial @FT_COLR_Paint object. + * + * FT_COLOR_NO_ROOT_TRANSFORM :: + * Do not output an initial root transform. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef enum FT_Color_Root_Transform_ + { + FT_COLOR_INCLUDE_ROOT_TRANSFORM, + FT_COLOR_NO_ROOT_TRANSFORM, + + FT_COLOR_ROOT_TRANSFORM_MAX + + } FT_Color_Root_Transform; + + + /************************************************************************** + * + * @struct: + * FT_ClipBox + * + * @description: + * A structure representing a 'COLR' v1 'ClipBox' table. 'COLR' v1 + * glyphs may optionally define a clip box for aiding allocation or + * defining a maximum drawable region. Use @FT_Get_Color_Glyph_ClipBox + * to retrieve it. + * + * @fields: + * bottom_left :: + * The bottom left corner of the clip box as an @FT_Vector with + * fixed-point coordinates in 26.6 format. + * + * top_left :: + * The top left corner of the clip box as an @FT_Vector with + * fixed-point coordinates in 26.6 format. + * + * top_right :: + * The top right corner of the clip box as an @FT_Vector with + * fixed-point coordinates in 26.6 format. + * + * bottom_right :: + * The bottom right corner of the clip box as an @FT_Vector with + * fixed-point coordinates in 26.6 format. + * + * @since: + * 2.12 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + typedef struct FT_ClipBox_ + { + FT_Vector bottom_left; + FT_Vector top_left; + FT_Vector top_right; + FT_Vector bottom_right; + + } FT_ClipBox; + + + /************************************************************************** + * + * @function: + * FT_Get_Color_Glyph_Paint + * + * @description: + * This is the starting point and interface to color gradient + * information in a 'COLR' v1 table in OpenType fonts to recursively + * retrieve the paint tables for the directed acyclic graph of a colored + * glyph, given a glyph ID. + * + * https://github.com/googlefonts/colr-gradients-spec + * + * In a 'COLR' v1 font, each color glyph defines a directed acyclic + * graph of nested paint tables, such as `PaintGlyph`, `PaintSolid`, + * `PaintLinearGradient`, `PaintRadialGradient`, and so on. Using this + * function and specifying a glyph ID, one retrieves the root paint + * table for this glyph ID. + * + * This function allows control whether an initial root transform is + * returned to configure scaling, transform, and translation correctly + * on the client's graphics context. The initial root transform is + * computed and returned according to the values configured for @FT_Size + * and @FT_Set_Transform on the @FT_Face object, see below for details + * of the `root_transform` parameter. This has implications for a + * client 'COLR' v1 implementation: When this function returns an + * initially computed root transform, at the time of executing the + * @FT_PaintGlyph operation, the contours should be retrieved using + * @FT_Load_Glyph at unscaled, untransformed size. This is because the + * root transform applied to the graphics context will take care of + * correct scaling. + * + * Alternatively, to allow hinting of contours, at the time of executing + * @FT_Load_Glyph, the current graphics context transformation matrix + * can be decomposed into a scaling matrix and a remainder, and + * @FT_Load_Glyph can be used to retrieve the contours at scaled size. + * Care must then be taken to blit or clip to the graphics context with + * taking this remainder transformation into account. + * + * @input: + * face :: + * A handle to the parent face object. + * + * base_glyph :: + * The glyph index for which to retrieve the root paint table. + * + * root_transform :: + * Specifies whether an initially computed root is returned by the + * @FT_PaintTransform operation to account for the activated size + * (see @FT_Activate_Size) and the configured transform and translate + * (see @FT_Set_Transform). + * + * This root transform is returned before nodes of the glyph graph of + * the font are returned. Subsequent @FT_COLR_Paint structures + * contain unscaled and untransformed values. The inserted root + * transform enables the client application to apply an initial + * transform to its graphics context. When executing subsequent + * FT_COLR_Paint operations, values from @FT_COLR_Paint operations + * will ultimately be correctly scaled because of the root transform + * applied to the graphics context. Use + * @FT_COLOR_INCLUDE_ROOT_TRANSFORM to include the root transform, use + * @FT_COLOR_NO_ROOT_TRANSFORM to not include it. The latter may be + * useful when traversing the 'COLR' v1 glyph graph and reaching a + * @FT_PaintColrGlyph. When recursing into @FT_PaintColrGlyph and + * painting that inline, no additional root transform is needed as it + * has already been applied to the graphics context at the beginning + * of drawing this glyph. + * + * @output: + * paint :: + * The @FT_OpaquePaint object that references the actual paint table. + * + * The respective actual @FT_COLR_Paint object is retrieved via + * @FT_Get_Paint. + * + * @return: + * Value~1 if everything is OK. If no color glyph is found, or the root + * paint could not be retrieved, value~0 gets returned. In case of an + * error, value~0 is returned also. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + FT_EXPORT( FT_Bool ) + FT_Get_Color_Glyph_Paint( FT_Face face, + FT_UInt base_glyph, + FT_Color_Root_Transform root_transform, + FT_OpaquePaint* paint ); + + + /************************************************************************** + * + * @function: + * FT_Get_Color_Glyph_ClipBox + * + * @description: + * Search for a 'COLR' v1 clip box for the specified `base_glyph` and + * fill the `clip_box` parameter with the 'COLR' v1 'ClipBox' information + * if one is found. + * + * @input: + * face :: + * A handle to the parent face object. + * + * base_glyph :: + * The glyph index for which to retrieve the clip box. + * + * @output: + * clip_box :: + * The clip box for the requested `base_glyph` if one is found. The + * clip box is computed taking scale and transformations configured on + * the @FT_Face into account. @FT_ClipBox contains @FT_Vector values + * in 26.6 format. + * + * @return: + * Value~1 if a clip box is found. If no clip box is found or an error + * occured, value~0 is returned. + * + * @note: + * To retrieve the clip box in font units, reset scale to units-per-em + * and remove transforms configured using @FT_Set_Transform. + * + * @since: + * 2.12 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + FT_EXPORT( FT_Bool ) + FT_Get_Color_Glyph_ClipBox( FT_Face face, + FT_UInt base_glyph, + FT_ClipBox* clip_box ); + + + /************************************************************************** + * + * @function: + * FT_Get_Paint_Layers + * + * @description: + * Access the layers of a `PaintColrLayers` table. + * + * If the root paint of a color glyph, or a nested paint of a 'COLR' + * glyph is a `PaintColrLayers` table, this function retrieves the + * layers of the `PaintColrLayers` table. + * + * The @FT_PaintColrLayers object contains an @FT_LayerIterator, which + * is used here to iterate over the layers. Each layer is returned as + * an @FT_OpaquePaint object, which then can be used with @FT_Get_Paint + * to retrieve the actual paint object. + * + * @input: + * face :: + * A handle to the parent face object. + * + * @inout: + * iterator :: + * The @FT_LayerIterator from an @FT_PaintColrLayers object, for which + * the layers are to be retrieved. The internal state of the iterator + * is incremented after one call to this function for retrieving one + * layer. + * + * @output: + * paint :: + * The @FT_OpaquePaint object that references the actual paint table. + * The respective actual @FT_COLR_Paint object is retrieved via + * @FT_Get_Paint. + * + * @return: + * Value~1 if everything is OK. Value~0 gets returned when the paint + * object can not be retrieved or any other error occurs. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + FT_EXPORT( FT_Bool ) + FT_Get_Paint_Layers( FT_Face face, + FT_LayerIterator* iterator, + FT_OpaquePaint* paint ); + + + /************************************************************************** + * + * @function: + * FT_Get_Colorline_Stops + * + * @description: + * This is an interface to color gradient information in a 'COLR' v1 + * table in OpenType fonts to iteratively retrieve the gradient and + * solid fill information for colored glyph layers for a specified glyph + * ID. + * + * https://github.com/googlefonts/colr-gradients-spec + * + * @input: + * face :: + * A handle to the parent face object. + * + * @inout: + * iterator :: + * The retrieved @FT_ColorStopIterator, configured on an @FT_ColorLine, + * which in turn got retrieved via paint information in + * @FT_PaintLinearGradient or @FT_PaintRadialGradient. + * + * @output: + * color_stop :: + * Color index and alpha value for the retrieved color stop. + * + * @return: + * Value~1 if everything is OK. If there are no more color stops, + * value~0 gets returned. In case of an error, value~0 is returned + * also. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + FT_EXPORT( FT_Bool ) + FT_Get_Colorline_Stops( FT_Face face, + FT_ColorStop* color_stop, + FT_ColorStopIterator* iterator ); + + + /************************************************************************** + * + * @function: + * FT_Get_Paint + * + * @description: + * Access the details of a paint using an @FT_OpaquePaint opaque paint + * object, which internally stores the offset to the respective `Paint` + * object in the 'COLR' table. + * + * @input: + * face :: + * A handle to the parent face object. + * + * opaque_paint :: + * The opaque paint object for which the underlying @FT_COLR_Paint + * data is to be retrieved. + * + * @output: + * paint :: + * The specific @FT_COLR_Paint object containing information coming + * from one of the font's `Paint*` tables. + * + * @return: + * Value~1 if everything is OK. Value~0 if no details can be found for + * this paint or any other error occured. + * + * @since: + * 2.11 -- **currently experimental only!** There might be changes + * without retaining backward compatibility of both the API and ABI. + * + */ + FT_EXPORT( FT_Bool ) + FT_Get_Paint( FT_Face face, + FT_OpaquePaint opaque_paint, + FT_COLR_Paint* paint ); + /* */ diff --git a/thirdparty/freetype/include/freetype/ftdriver.h b/thirdparty/freetype/include/freetype/ftdriver.h index 804ec34a39..4936639056 100644 --- a/thirdparty/freetype/include/freetype/ftdriver.h +++ b/thirdparty/freetype/include/freetype/ftdriver.h @@ -4,7 +4,7 @@ * * FreeType API for controlling driver modules (specification only). * - * Copyright (C) 2017-2020 by + * Copyright (C) 2017-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -53,10 +53,10 @@ FT_BEGIN_HEADER * reasons. * * Available properties are @increase-x-height, @no-stem-darkening - * (experimental), @darkening-parameters (experimental), @warping - * (experimental), @glyph-to-script-map (experimental), @fallback-script - * (experimental), and @default-script (experimental), as documented in - * the @properties section. + * (experimental), @darkening-parameters (experimental), + * @glyph-to-script-map (experimental), @fallback-script (experimental), + * and @default-script (experimental), as documented in the @properties + * section. * */ @@ -84,15 +84,15 @@ FT_BEGIN_HEADER * @properties section. * * - * **Hinting and antialiasing principles of the new engine** + * **Hinting and anti-aliasing principles of the new engine** * * The rasterizer is positioning horizontal features (e.g., ascender * height & x-height, or crossbars) on the pixel grid and minimizing the - * amount of antialiasing applied to them, while placing vertical + * amount of anti-aliasing applied to them, while placing vertical * features (vertical stems) on the pixel grid without hinting, thus * representing the stem position and weight accurately. Sometimes the * vertical stems may be only partially black. In this context, - * 'antialiasing' means that stems are not positioned exactly on pixel + * 'anti-aliasing' means that stems are not positioned exactly on pixel * borders, causing a fuzzy appearance. * * There are two principles behind this approach. @@ -108,7 +108,7 @@ FT_BEGIN_HEADER * sizes are comparable to kerning values and thus would be noticeable * (and distracting) while reading if hinting were applied. * - * One of the reasons to not hint horizontally is antialiasing for LCD + * One of the reasons to not hint horizontally is anti-aliasing for LCD * screens: The pixel geometry of modern displays supplies three vertical * subpixels as the eye moves horizontally across each visible pixel. On * devices where we can be certain this characteristic is present a @@ -116,7 +116,7 @@ FT_BEGIN_HEADER * weight. In Western writing systems this turns out to be the more * critical direction anyway; the weights and spacing of vertical stems * (see above) are central to Armenian, Cyrillic, Greek, and Latin type - * designs. Even when the rasterizer uses greyscale antialiasing instead + * designs. Even when the rasterizer uses greyscale anti-aliasing instead * of color (a necessary compromise when one doesn't know the screen * characteristics), the unhinted vertical features preserve the design's * weight and spacing much better than aliased type would. @@ -362,12 +362,8 @@ FT_BEGIN_HEADER * The same holds for the Type~1 and CID modules if compiled with * `T1_CONFIG_OPTION_OLD_ENGINE`. * - * For the 'cff' module, the default engine is 'freetype' if - * `CFF_CONFIG_OPTION_OLD_ENGINE` is defined, and 'adobe' otherwise. - * - * For both the 'type1' and 't1cid' modules, the default engine is - * 'freetype' if `T1_CONFIG_OPTION_OLD_ENGINE` is defined, and 'adobe' - * otherwise. + * For the 'cff' module, the default engine is 'adobe'. For both the + * 'type1' and 't1cid' modules, the default engine is 'adobe', too. * * @note: * This property can be used with @FT_Property_Get also. @@ -1166,48 +1162,18 @@ FT_BEGIN_HEADER * warping * * @description: - * **Experimental only** + * **Obsolete** * - * If FreeType gets compiled with option `AF_CONFIG_OPTION_USE_WARPER` to - * activate the warp hinting code in the auto-hinter, this property - * switches warping on and off. + * This property was always experimental and probably never worked + * correctly. It was entirely removed from the FreeType~2 sources. This + * entry is only here for historical reference. * - * Warping only works in 'normal' auto-hinting mode replacing it. The - * idea of the code is to slightly scale and shift a glyph along the + * Warping only worked in 'normal' auto-hinting mode replacing it. The + * idea of the code was to slightly scale and shift a glyph along the * non-hinted dimension (which is usually the horizontal axis) so that as - * much of its segments are aligned (more or less) to the grid. To find + * much of its segments were aligned (more or less) to the grid. To find * out a glyph's optimal scaling and shifting value, various parameter - * combinations are tried and scored. - * - * By default, warping is off. - * - * @note: - * This property can be used with @FT_Property_Get also. - * - * This property can be set via the `FREETYPE_PROPERTIES` environment - * variable (using values 1 and 0 for 'on' and 'off', respectively). - * - * The warping code can also change advance widths. Have a look at the - * `lsb_delta` and `rsb_delta` fields in the @FT_GlyphSlotRec structure - * for details on improving inter-glyph distances while rendering. - * - * Since warping is a global property of the auto-hinter it is best to - * change its value before rendering any face. Otherwise, you should - * reload all faces that get auto-hinted in 'normal' hinting mode. - * - * @example: - * This example shows how to switch on warping (omitting the error - * handling). - * - * ``` - * FT_Library library; - * FT_Bool warping = 1; - * - * - * FT_Init_FreeType( &library ); - * - * FT_Property_Set( library, "autofitter", "warping", &warping ); - * ``` + * combinations were tried and scored. * * @since: * 2.6 diff --git a/thirdparty/freetype/include/freetype/fterrdef.h b/thirdparty/freetype/include/freetype/fterrdef.h index 895d2d4dc8..6e9c4ccb97 100644 --- a/thirdparty/freetype/include/freetype/fterrdef.h +++ b/thirdparty/freetype/include/freetype/fterrdef.h @@ -4,7 +4,7 @@ * * FreeType error codes (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/fterrors.h b/thirdparty/freetype/include/freetype/fterrors.h index 60a637c77c..151941dde0 100644 --- a/thirdparty/freetype/include/freetype/fterrors.h +++ b/thirdparty/freetype/include/freetype/fterrors.h @@ -4,7 +4,7 @@ * * FreeType error code handling (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -281,6 +281,8 @@ FT_BEGIN_HEADER FT_EXPORT( const char* ) FT_Error_String( FT_Error error_code ); + /* */ + FT_END_HEADER diff --git a/thirdparty/freetype/include/freetype/ftfntfmt.h b/thirdparty/freetype/include/freetype/ftfntfmt.h index f803349cd7..8e68a4a3ac 100644 --- a/thirdparty/freetype/include/freetype/ftfntfmt.h +++ b/thirdparty/freetype/include/freetype/ftfntfmt.h @@ -4,7 +4,7 @@ * * Support functions for font formats. * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftgasp.h b/thirdparty/freetype/include/freetype/ftgasp.h index 6b76882c74..76c45eb3b1 100644 --- a/thirdparty/freetype/include/freetype/ftgasp.h +++ b/thirdparty/freetype/include/freetype/ftgasp.h @@ -4,7 +4,7 @@ * * Access of TrueType's 'gasp' table (specification). * - * Copyright (C) 2007-2020 by + * Copyright (C) 2007-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftglyph.h b/thirdparty/freetype/include/freetype/ftglyph.h index 704619e3d0..26b32ed6be 100644 --- a/thirdparty/freetype/include/freetype/ftglyph.h +++ b/thirdparty/freetype/include/freetype/ftglyph.h @@ -4,7 +4,7 @@ * * FreeType convenience functions to handle glyphs (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -337,9 +337,9 @@ FT_BEGIN_HEADER * vector. */ FT_EXPORT( FT_Error ) - FT_Glyph_Transform( FT_Glyph glyph, - FT_Matrix* matrix, - FT_Vector* delta ); + FT_Glyph_Transform( FT_Glyph glyph, + const FT_Matrix* matrix, + const FT_Vector* delta ); /************************************************************************** @@ -569,10 +569,10 @@ FT_BEGIN_HEADER * ``` */ FT_EXPORT( FT_Error ) - FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, - FT_Render_Mode render_mode, - FT_Vector* origin, - FT_Bool destroy ); + FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, + FT_Render_Mode render_mode, + const FT_Vector* origin, + FT_Bool destroy ); /************************************************************************** diff --git a/thirdparty/freetype/include/freetype/ftgxval.h b/thirdparty/freetype/include/freetype/ftgxval.h index 354460a9a7..21bbbde2ae 100644 --- a/thirdparty/freetype/include/freetype/ftgxval.h +++ b/thirdparty/freetype/include/freetype/ftgxval.h @@ -4,7 +4,7 @@ * * FreeType API for validating TrueTypeGX/AAT tables (specification). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * Masatake YAMATO, Redhat K.K, * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/include/freetype/ftgzip.h b/thirdparty/freetype/include/freetype/ftgzip.h index ec5939a191..ba82baba64 100644 --- a/thirdparty/freetype/include/freetype/ftgzip.h +++ b/thirdparty/freetype/include/freetype/ftgzip.h @@ -4,7 +4,7 @@ * * Gzip-compressed stream support. * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftimage.h b/thirdparty/freetype/include/freetype/ftimage.h index 74911620d2..88533b8409 100644 --- a/thirdparty/freetype/include/freetype/ftimage.h +++ b/thirdparty/freetype/include/freetype/ftimage.h @@ -5,7 +5,7 @@ * FreeType glyph image formats and default raster interface * (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -28,11 +28,6 @@ #define FTIMAGE_H_ - /* STANDALONE_ is from ftgrays.c */ -#ifndef STANDALONE_ -#endif - - FT_BEGIN_HEADER @@ -201,6 +196,11 @@ FT_BEGIN_HEADER #define ft_pixel_mode_pal2 FT_PIXEL_MODE_GRAY2 #define ft_pixel_mode_pal4 FT_PIXEL_MODE_GRAY4 + /* */ + + /* For debugging, the @FT_Pixel_Mode enumeration must stay in sync */ + /* with the `pixel_modes` array in file `ftobjs.c`. */ + /************************************************************************** * @@ -695,11 +695,13 @@ FT_BEGIN_HEADER * to get a simple enumeration without assigning special numbers. */ #ifndef FT_IMAGE_TAG -#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) \ - value = ( ( (unsigned long)_x1 << 24 ) | \ - ( (unsigned long)_x2 << 16 ) | \ - ( (unsigned long)_x3 << 8 ) | \ - (unsigned long)_x4 ) + +#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) \ + value = ( ( FT_STATIC_BYTE_CAST( unsigned long, _x1 ) << 24 ) | \ + ( FT_STATIC_BYTE_CAST( unsigned long, _x2 ) << 16 ) | \ + ( FT_STATIC_BYTE_CAST( unsigned long, _x3 ) << 8 ) | \ + FT_STATIC_BYTE_CAST( unsigned long, _x4 ) ) + #endif /* FT_IMAGE_TAG */ @@ -772,17 +774,6 @@ FT_BEGIN_HEADER /*************************************************************************/ - /************************************************************************** - * - * A raster is a scan converter, in charge of rendering an outline into a - * bitmap. This section contains the public API for rasters. - * - * Note that in FreeType 2, all rasters are now encapsulated within - * specific modules called 'renderers'. See `ftrender.h` for more details - * on renderers. - * - */ - /************************************************************************** * @@ -796,16 +787,35 @@ FT_BEGIN_HEADER * How vectorial outlines are converted into bitmaps and pixmaps. * * @description: - * This section contains technical definitions. + * A raster or a rasterizer is a scan converter in charge of producing a + * pixel coverage bitmap that can be used as an alpha channel when + * compositing a glyph with a background. FreeType comes with two + * rasterizers: bilevel `raster1` and anti-aliased `smooth` are two + * separate modules. They are usually called from the high-level + * @FT_Load_Glyph or @FT_Render_Glyph functions and produce the entire + * coverage bitmap at once, while staying largely invisible to users. + * + * Instead of working with complete coverage bitmaps, it is also possible + * to intercept consecutive pixel runs on the same scanline with the same + * coverage, called _spans_, and process them individually. Only the + * `smooth` rasterizer permits this when calling @FT_Outline_Render with + * @FT_Raster_Params as described below. + * + * Working with either complete bitmaps or spans it is important to think + * of them as colorless coverage objects suitable as alpha channels to + * blend arbitrary colors with a background. For best results, it is + * recommended to use gamma correction, too. + * + * This section also describes the public API needed to set up alternative + * @FT_Renderer modules. * * @order: - * FT_Raster * FT_Span * FT_SpanFunc - * * FT_Raster_Params * FT_RASTER_FLAG_XXX * + * FT_Raster * FT_Raster_NewFunc * FT_Raster_DoneFunc * FT_Raster_ResetFunc @@ -818,24 +828,12 @@ FT_BEGIN_HEADER /************************************************************************** * - * @type: - * FT_Raster - * - * @description: - * An opaque handle (pointer) to a raster object. Each object can be - * used independently to convert an outline into a bitmap or pixmap. - */ - typedef struct FT_RasterRec_* FT_Raster; - - - /************************************************************************** - * * @struct: * FT_Span * * @description: - * A structure used to model a single span of gray pixels when rendering - * an anti-aliased bitmap. + * A structure to model a single span of consecutive pixels when + * rendering an anti-aliased bitmap. * * @fields: * x :: @@ -852,8 +850,8 @@ FT_BEGIN_HEADER * This structure is used by the span drawing callback type named * @FT_SpanFunc that takes the y~coordinate of the span as a parameter. * - * The coverage value is always between 0 and 255. If you want less gray - * values, the callback function has to reduce them. + * The anti-aliased rasterizer produces coverage values from 0 to 255, + * this is, from completely transparent to completely opaque. */ typedef struct FT_Span_ { @@ -871,8 +869,8 @@ FT_BEGIN_HEADER * * @description: * A function used as a call-back by the anti-aliased renderer in order - * to let client applications draw themselves the gray pixel spans on - * each scan line. + * to let client applications draw themselves the pixel spans on each + * scan line. * * @input: * y :: @@ -888,11 +886,12 @@ FT_BEGIN_HEADER * User-supplied data that is passed to the callback. * * @note: - * This callback allows client applications to directly render the gray - * spans of the anti-aliased bitmap to any kind of surfaces. + * This callback allows client applications to directly render the spans + * of the anti-aliased bitmap to any kind of surfaces. * * This can be used to write anti-aliased outlines directly to a given - * background bitmap, and even perform translucency. + * background bitmap using alpha compositing. It can also be used for + * oversampling and averaging. */ typedef void (*FT_SpanFunc)( int y, @@ -962,11 +961,17 @@ FT_BEGIN_HEADER * will be clipped to a box specified in the `clip_box` field of the * @FT_Raster_Params structure. Otherwise, the `clip_box` is * effectively set to the bounding box and all spans are generated. + * + * FT_RASTER_FLAG_SDF :: + * This flag is set to indicate that a signed distance field glyph + * image should be generated. This is only used while rendering with + * the @FT_RENDER_MODE_SDF render mode. */ #define FT_RASTER_FLAG_DEFAULT 0x0 #define FT_RASTER_FLAG_AA 0x1 #define FT_RASTER_FLAG_DIRECT 0x2 #define FT_RASTER_FLAG_CLIP 0x4 +#define FT_RASTER_FLAG_SDF 0x8 /* these constants are deprecated; use the corresponding */ /* `FT_RASTER_FLAG_XXX` values instead */ @@ -1049,6 +1054,23 @@ FT_BEGIN_HEADER /************************************************************************** * + * @type: + * FT_Raster + * + * @description: + * An opaque handle (pointer) to a raster object. Each object can be + * used independently to convert an outline into a bitmap or pixmap. + * + * @note: + * In FreeType 2, all rasters are now encapsulated within specific + * @FT_Renderer modules and only used in their context. + * + */ + typedef struct FT_RasterRec_* FT_Raster; + + + /************************************************************************** + * * @functype: * FT_Raster_NewFunc * diff --git a/thirdparty/freetype/include/freetype/ftincrem.h b/thirdparty/freetype/include/freetype/ftincrem.h index f67655eda0..229b947bd8 100644 --- a/thirdparty/freetype/include/freetype/ftincrem.h +++ b/thirdparty/freetype/include/freetype/ftincrem.h @@ -4,7 +4,7 @@ * * FreeType incremental loading (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -213,9 +213,14 @@ FT_BEGIN_HEADER * * @description: * A function used to retrieve the basic metrics of a given glyph index - * before accessing its data. This is necessary because, in certain - * formats like TrueType, the metrics are stored in a different place - * from the glyph images proper. + * before accessing its data. This allows for handling font types such + * as PCL~XL Format~1, Class~2 downloaded TrueType fonts, where the glyph + * metrics (`hmtx` and `vmtx` tables) are permitted to be omitted from + * the font, and the relevant metrics included in the header of the glyph + * outline data. Importantly, this is not intended to allow custom glyph + * metrics (for example, Postscript Metrics dictionaries), because that + * conflicts with the requirements of outline hinting. Such custom + * metrics must be handled separately, by the calling application. * * @input: * incremental :: @@ -235,7 +240,7 @@ FT_BEGIN_HEADER * * @output: * ametrics :: - * The replacement glyph metrics in font units. + * The glyph metrics in font units. * */ typedef FT_Error @@ -264,7 +269,7 @@ FT_BEGIN_HEADER * * get_glyph_metrics :: * The function to get glyph metrics. May be null if the font does not - * provide overriding glyph metrics. + * require it. * */ typedef struct FT_Incremental_FuncsRec_ diff --git a/thirdparty/freetype/include/freetype/ftlcdfil.h b/thirdparty/freetype/include/freetype/ftlcdfil.h index c6995f2ff7..18e2544175 100644 --- a/thirdparty/freetype/include/freetype/ftlcdfil.h +++ b/thirdparty/freetype/include/freetype/ftlcdfil.h @@ -5,7 +5,7 @@ * FreeType API for color filtering of subpixel bitmap glyphs * (specification). * - * Copyright (C) 2006-2020 by + * Copyright (C) 2006-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -44,7 +44,7 @@ FT_BEGIN_HEADER * API to control subpixel rendering. * * @description: - * FreeType provides two alternative subpixel rendering technologies. + * FreeType provides two alternative subpixel rendering technologies. * Should you define `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` in your * `ftoption.h` file, this enables ClearType-style rendering. * Otherwise, Harmony LCD rendering is enabled. These technologies are @@ -55,13 +55,12 @@ FT_BEGIN_HEADER * ClearType-style LCD rendering exploits the color-striped structure of * LCD pixels, increasing the available resolution in the direction of * the stripe (usually horizontal RGB) by a factor of~3. Using the - * subpixels coverages unfiltered can create severe color fringes + * subpixel coverages unfiltered can create severe color fringes * especially when rendering thin features. Indeed, to produce * black-on-white text, the nearby color subpixels must be dimmed - * equally. - * - * A good 5-tap FIR filter should be applied to subpixel coverages - * regardless of pixel boundaries and should have these properties: + * evenly. Therefore, an equalizing 5-tap FIR filter should be applied + * to subpixel coverages regardless of pixel boundaries and should have + * these properties: * * 1. It should be symmetrical, like {~a, b, c, b, a~}, to avoid * any shifts in appearance. @@ -84,7 +83,7 @@ FT_BEGIN_HEADER * Harmony LCD rendering is suitable to panels with any regular subpixel * structure, not just monitors with 3 color striped subpixels, as long * as the color subpixels have fixed positions relative to the pixel - * center. In this case, each color channel is then rendered separately + * center. In this case, each color channel can be rendered separately * after shifting the outline opposite to the subpixel shift so that the * coverage maps are aligned. This method is immune to color fringes * because the shifts do not change integral coverage. @@ -101,9 +100,9 @@ FT_BEGIN_HEADER * clockwise. Harmony with default LCD geometry is equivalent to * ClearType with light filter. * - * As a result of ClearType filtering or Harmony rendering, the - * dimensions of LCD bitmaps can be either wider or taller than the - * dimensions of the corresponding outline with regard to the pixel grid. + * As a result of ClearType filtering or Harmony shifts, the resulting + * dimensions of LCD bitmaps can be slightly wider or taller than the + * dimensions the original outline with regard to the pixel grid. * For example, for @FT_RENDER_MODE_LCD, the filter adds 2~subpixels to * the left, and 2~subpixels to the right. The bitmap offset values are * adjusted accordingly, so clients shouldn't need to modify their layout diff --git a/thirdparty/freetype/include/freetype/ftlist.h b/thirdparty/freetype/include/freetype/ftlist.h index 4588922706..55f015977a 100644 --- a/thirdparty/freetype/include/freetype/ftlist.h +++ b/thirdparty/freetype/include/freetype/ftlist.h @@ -4,7 +4,7 @@ * * Generic list support for FreeType (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftlogging.h b/thirdparty/freetype/include/freetype/ftlogging.h new file mode 100644 index 0000000000..a558b85faf --- /dev/null +++ b/thirdparty/freetype/include/freetype/ftlogging.h @@ -0,0 +1,184 @@ +/**************************************************************************** + * + * ftlogging.h + * + * Additional debugging APIs. + * + * Copyright (C) 2020-2021 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#ifndef FTLOGGING_H_ +#define FTLOGGING_H_ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * debugging_apis + * + * @title: + * External Debugging APIs + * + * @abstract: + * Public APIs to control the `FT_DEBUG_LOGGING` macro. + * + * @description: + * This section contains the declarations of public functions that + * enables fine control of what the `FT_DEBUG_LOGGING` macro outputs. + * + */ + + + /************************************************************************** + * + * @function: + * FT_Trace_Set_Level + * + * @description: + * Change the levels of tracing components of FreeType at run time. + * + * @input: + * tracing_level :: + * New tracing value. + * + * @example: + * The following call makes FreeType trace everything but the 'memory' + * component. + * + * ``` + * FT_Trace_Set_Level( "any:7 memory:0 ); + * ``` + * + * @note: + * This function does nothing if compilation option `FT_DEBUG_LOGGING` + * isn't set. + * + * @since: + * 2.11 + * + */ + FT_EXPORT( void ) + FT_Trace_Set_Level( const char* tracing_level ); + + + /************************************************************************** + * + * @function: + * FT_Trace_Set_Default_Level + * + * @description: + * Reset tracing value of FreeType's components to the default value + * (i.e., to the value of the `FT2_DEBUG` environment value or to NULL + * if `FT2_DEBUG` is not set). + * + * @note: + * This function does nothing if compilation option `FT_DEBUG_LOGGING` + * isn't set. + * + * @since: + * 2.11 + * + */ + FT_EXPORT( void ) + FT_Trace_Set_Default_Level( void ); + + + /************************************************************************** + * + * @functype: + * FT_Custom_Log_Handler + * + * @description: + * A function typedef that is used to handle the logging of tracing and + * debug messages on a file system. + * + * @input: + * ft_component :: + * The name of `FT_COMPONENT` from which the current debug or error + * message is produced. + * + * fmt :: + * Actual debug or tracing message. + * + * args:: + * Arguments of debug or tracing messages. + * + * @since: + * 2.11 + * + */ + typedef void + (*FT_Custom_Log_Handler)( const char* ft_component, + const char* fmt, + va_list args ); + + + /************************************************************************** + * + * @function: + * FT_Set_Log_Handler + * + * @description: + * A function to set a custom log handler. + * + * @input: + * handler :: + * New logging function. + * + * @note: + * This function does nothing if compilation option `FT_DEBUG_LOGGING` + * isn't set. + * + * @since: + * 2.11 + * + */ + FT_EXPORT( void ) + FT_Set_Log_Handler( FT_Custom_Log_Handler handler ); + + + /************************************************************************** + * + * @function: + * FT_Set_Default_Log_Handler + * + * @description: + * A function to undo the effect of @FT_Set_Log_Handler, resetting the + * log handler to FreeType's built-in version. + * + * @note: + * This function does nothing if compilation option `FT_DEBUG_LOGGING` + * isn't set. + * + * @since: + * 2.11 + * + */ + FT_EXPORT( void ) + FT_Set_Default_Log_Handler( void ); + + /* */ + + +FT_END_HEADER + +#endif /* FTLOGGING_H_ */ + + +/* END */ diff --git a/thirdparty/freetype/include/freetype/ftlzw.h b/thirdparty/freetype/include/freetype/ftlzw.h index ae46ad6021..fce1c9c4bb 100644 --- a/thirdparty/freetype/include/freetype/ftlzw.h +++ b/thirdparty/freetype/include/freetype/ftlzw.h @@ -4,7 +4,7 @@ * * LZW-compressed stream support. * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftmac.h b/thirdparty/freetype/include/freetype/ftmac.h index c9de981845..607af9b589 100644 --- a/thirdparty/freetype/include/freetype/ftmac.h +++ b/thirdparty/freetype/include/freetype/ftmac.h @@ -4,7 +4,7 @@ * * Additional Mac-specific API. * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftmm.h b/thirdparty/freetype/include/freetype/ftmm.h index d8781a8296..32579e997f 100644 --- a/thirdparty/freetype/include/freetype/ftmm.h +++ b/thirdparty/freetype/include/freetype/ftmm.h @@ -4,7 +4,7 @@ * * FreeType Multiple Master font interface (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftmodapi.h b/thirdparty/freetype/include/freetype/ftmodapi.h index 3f7ae82bab..b77d356de9 100644 --- a/thirdparty/freetype/include/freetype/ftmodapi.h +++ b/thirdparty/freetype/include/freetype/ftmodapi.h @@ -4,7 +4,7 @@ * * FreeType modules public interface (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -45,10 +45,12 @@ FT_BEGIN_HEADER * * @description: * The definitions below are used to manage modules within FreeType. - * Modules can be added, upgraded, and removed at runtime. Additionally, - * some module properties can be controlled also. + * Internal and external modules can be added, upgraded, and removed at + * runtime. For example, an alternative renderer or proprietary font + * driver can be registered and prioritized. Additionally, some module + * properties can also be controlled. * - * Here is a list of possible values of the `module_name` field in the + * Here is a list of existing values of the `module_name` field in the * @FT_Module_Class structure. * * ``` @@ -86,6 +88,7 @@ FT_BEGIN_HEADER * FT_Remove_Module * FT_Add_Default_Modules * + * FT_FACE_DRIVER_NAME * FT_Property_Set * FT_Property_Get * FT_Set_Default_Properties @@ -330,6 +333,27 @@ FT_BEGIN_HEADER /************************************************************************** * + * @macro: + * FT_FACE_DRIVER_NAME + * + * @description: + * A macro that retrieves the name of a font driver from a face object. + * + * @note: + * The font driver name is a valid `module_name` for @FT_Property_Set + * and @FT_Property_Get. This is not the same as @FT_Get_Font_Format. + * + * @since: + * 2.11 + * + */ +#define FT_FACE_DRIVER_NAME( face ) \ + ( ( *FT_REINTERPRET_CAST( FT_Module_Class**, \ + ( face )->driver ) )->module_name ) + + + /************************************************************************** + * * @function: * FT_Property_Set * @@ -485,8 +509,7 @@ FT_BEGIN_HEADER * * ``` * FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ - * cff:no-stem-darkening=0 \ - * autofitter:warping=1 + * cff:no-stem-darkening=0 * ``` * * @inout: diff --git a/thirdparty/freetype/include/freetype/ftmoderr.h b/thirdparty/freetype/include/freetype/ftmoderr.h index f05fc53aa3..b417cd5ab7 100644 --- a/thirdparty/freetype/include/freetype/ftmoderr.h +++ b/thirdparty/freetype/include/freetype/ftmoderr.h @@ -4,7 +4,7 @@ * * FreeType module error offsets (specification). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -171,6 +171,7 @@ FT_MODERRDEF( Type42, 0x1400, "Type 42 module" ) FT_MODERRDEF( Winfonts, 0x1500, "Windows FON/FNT module" ) FT_MODERRDEF( GXvalid, 0x1600, "GX validation module" ) + FT_MODERRDEF( Sdf, 0x1700, "Signed distance field raster module" ) #ifdef FT_MODERR_END_LIST diff --git a/thirdparty/freetype/include/freetype/ftotval.h b/thirdparty/freetype/include/freetype/ftotval.h index 9c00ad30b9..00f9727859 100644 --- a/thirdparty/freetype/include/freetype/ftotval.h +++ b/thirdparty/freetype/include/freetype/ftotval.h @@ -4,7 +4,7 @@ * * FreeType API for validating OpenType tables (specification). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftoutln.h b/thirdparty/freetype/include/freetype/ftoutln.h index 84e9b144c1..6bb5f809a9 100644 --- a/thirdparty/freetype/include/freetype/ftoutln.h +++ b/thirdparty/freetype/include/freetype/ftoutln.h @@ -5,7 +5,7 @@ * Support for the FT_Outline type used to store glyph shapes of * most scalable font formats (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftparams.h b/thirdparty/freetype/include/freetype/ftparams.h index 55ea2a3870..04a3f44126 100644 --- a/thirdparty/freetype/include/freetype/ftparams.h +++ b/thirdparty/freetype/include/freetype/ftparams.h @@ -4,7 +4,7 @@ * * FreeType API for possible FT_Parameter tags (specification only). * - * Copyright (C) 2017-2020 by + * Copyright (C) 2017-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftpfr.h b/thirdparty/freetype/include/freetype/ftpfr.h index 9a5383f918..fbdb14c202 100644 --- a/thirdparty/freetype/include/freetype/ftpfr.h +++ b/thirdparty/freetype/include/freetype/ftpfr.h @@ -4,7 +4,7 @@ * * FreeType API for accessing PFR-specific data (specification only). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftrender.h b/thirdparty/freetype/include/freetype/ftrender.h index 8007951b37..48d489d496 100644 --- a/thirdparty/freetype/include/freetype/ftrender.h +++ b/thirdparty/freetype/include/freetype/ftrender.h @@ -4,7 +4,7 @@ * * FreeType renderer modules public interface (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftsizes.h b/thirdparty/freetype/include/freetype/ftsizes.h index a8682a30fb..22366393b8 100644 --- a/thirdparty/freetype/include/freetype/ftsizes.h +++ b/thirdparty/freetype/include/freetype/ftsizes.h @@ -4,7 +4,7 @@ * * FreeType size objects management (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftsnames.h b/thirdparty/freetype/include/freetype/ftsnames.h index 729e6ab069..c7f6581cb3 100644 --- a/thirdparty/freetype/include/freetype/ftsnames.h +++ b/thirdparty/freetype/include/freetype/ftsnames.h @@ -7,7 +7,7 @@ * * This is _not_ used to retrieve glyph names! * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftstroke.h b/thirdparty/freetype/include/freetype/ftstroke.h index a759c94dde..88b2a8a4ed 100644 --- a/thirdparty/freetype/include/freetype/ftstroke.h +++ b/thirdparty/freetype/include/freetype/ftstroke.h @@ -4,7 +4,7 @@ * * FreeType path stroker (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftsynth.h b/thirdparty/freetype/include/freetype/ftsynth.h index bdb4c5753e..861dcb5ac5 100644 --- a/thirdparty/freetype/include/freetype/ftsynth.h +++ b/thirdparty/freetype/include/freetype/ftsynth.h @@ -5,7 +5,7 @@ * FreeType synthesizing code for emboldening and slanting * (specification). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/ftsystem.h b/thirdparty/freetype/include/freetype/ftsystem.h index 22aead7140..e5abb85a85 100644 --- a/thirdparty/freetype/include/freetype/ftsystem.h +++ b/thirdparty/freetype/include/freetype/ftsystem.h @@ -4,7 +4,7 @@ * * FreeType low-level system interface definition (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/fttrigon.h b/thirdparty/freetype/include/freetype/fttrigon.h index 2ce6b324c9..dbe7b0d388 100644 --- a/thirdparty/freetype/include/freetype/fttrigon.h +++ b/thirdparty/freetype/include/freetype/fttrigon.h @@ -4,7 +4,7 @@ * * FreeType trigonometric functions (specification). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/fttypes.h b/thirdparty/freetype/include/freetype/fttypes.h index aaeb9e8785..699bd003c0 100644 --- a/thirdparty/freetype/include/freetype/fttypes.h +++ b/thirdparty/freetype/include/freetype/fttypes.h @@ -4,7 +4,7 @@ * * FreeType simple types definitions (specification only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -413,7 +413,7 @@ FT_BEGIN_HEADER typedef struct FT_Data_ { const FT_Byte* pointer; - FT_Int length; + FT_UInt length; } FT_Data; @@ -479,18 +479,17 @@ FT_BEGIN_HEADER * * @description: * This macro converts four-letter tags that are used to label TrueType - * tables into an unsigned long, to be used within FreeType. + * tables into an `FT_Tag` type, to be used within FreeType. * * @note: * The produced values **must** be 32-bit integers. Don't redefine this * macro. */ -#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ - (FT_Tag) \ - ( ( (FT_ULong)_x1 << 24 ) | \ - ( (FT_ULong)_x2 << 16 ) | \ - ( (FT_ULong)_x3 << 8 ) | \ - (FT_ULong)_x4 ) +#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ + ( ( FT_STATIC_BYTE_CAST( FT_Tag, _x1 ) << 24 ) | \ + ( FT_STATIC_BYTE_CAST( FT_Tag, _x2 ) << 16 ) | \ + ( FT_STATIC_BYTE_CAST( FT_Tag, _x3 ) << 8 ) | \ + FT_STATIC_BYTE_CAST( FT_Tag, _x4 ) ) /*************************************************************************/ @@ -588,7 +587,7 @@ FT_BEGIN_HEADER #define FT_IS_EMPTY( list ) ( (list).head == 0 ) -#define FT_BOOL( x ) ( (FT_Bool)( (x) != 0 ) ) +#define FT_BOOL( x ) FT_STATIC_CAST( FT_Bool, (x) != 0 ) /* concatenate C tokens */ #define FT_ERR_XCAT( x, y ) x ## y diff --git a/thirdparty/freetype/include/freetype/ftwinfnt.h b/thirdparty/freetype/include/freetype/ftwinfnt.h index 786528c6ec..f30f447d84 100644 --- a/thirdparty/freetype/include/freetype/ftwinfnt.h +++ b/thirdparty/freetype/include/freetype/ftwinfnt.h @@ -4,7 +4,7 @@ * * FreeType API for accessing Windows fnt-specific data. * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -55,7 +55,7 @@ FT_BEGIN_HEADER * FT_WinFNT_ID_XXX * * @description: - * A list of valid values for the `charset` byte in @FT_WinFNT_HeaderRec. + * A list of valid values for the `charset` byte in @FT_WinFNT_HeaderRec. * Exact mapping tables for the various 'cpXXXX' encodings (except for * 'cp1361') can be found at 'ftp://ftp.unicode.org/Public/' in the * `MAPPINGS/VENDORS/MICSFT/WINDOWS` subdirectory. 'cp1361' is roughly a diff --git a/thirdparty/freetype/include/freetype/internal/autohint.h b/thirdparty/freetype/include/freetype/internal/autohint.h index 2a472e20b9..01585f5edf 100644 --- a/thirdparty/freetype/include/freetype/internal/autohint.h +++ b/thirdparty/freetype/include/freetype/internal/autohint.h @@ -4,7 +4,7 @@ * * High-level 'autohint' module-specific interface (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/cffotypes.h b/thirdparty/freetype/include/freetype/internal/cffotypes.h index a316fd1f30..a91dd556ca 100644 --- a/thirdparty/freetype/include/freetype/internal/cffotypes.h +++ b/thirdparty/freetype/include/freetype/internal/cffotypes.h @@ -4,7 +4,7 @@ * * Basic OpenType/CFF object type definitions (specification). * - * Copyright (C) 2017-2020 by + * Copyright (C) 2017-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/cfftypes.h b/thirdparty/freetype/include/freetype/internal/cfftypes.h index f21167b1e5..99e8d41368 100644 --- a/thirdparty/freetype/include/freetype/internal/cfftypes.h +++ b/thirdparty/freetype/include/freetype/internal/cfftypes.h @@ -5,7 +5,7 @@ * Basic OpenType/CFF type definitions and interface (specification * only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/compiler-macros.h b/thirdparty/freetype/include/freetype/internal/compiler-macros.h index 97c18d3a21..d8b61b3dc9 100644 --- a/thirdparty/freetype/include/freetype/internal/compiler-macros.h +++ b/thirdparty/freetype/include/freetype/internal/compiler-macros.h @@ -4,7 +4,7 @@ * * Compiler-specific macro definitions used internally by FreeType. * - * Copyright (C) 2020 by + * Copyright (C) 2020-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -71,12 +71,18 @@ FT_BEGIN_HEADER */ #define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT -#ifdef _WIN64 +#ifdef __UINTPTR_TYPE__ + /* + * GCC and Clang both provide a `__UINTPTR_TYPE__` that can be used to + * avoid a dependency on `stdint.h`. + */ +# define FT_UINT_TO_POINTER( x ) (void *)(__UINTPTR_TYPE__)(x) +#elif defined( _WIN64 ) /* only 64bit Windows uses the LLP64 data model, i.e., */ /* 32-bit integers, 64-bit pointers. */ -#define FT_UINT_TO_POINTER( x ) (void *)(unsigned __int64)(x) +# define FT_UINT_TO_POINTER( x ) (void *)(unsigned __int64)(x) #else -#define FT_UINT_TO_POINTER( x ) (void *)(unsigned long)(x) +# define FT_UINT_TO_POINTER( x ) (void *)(unsigned long)(x) #endif /* @@ -216,79 +222,91 @@ FT_BEGIN_HEADER #define FT_EXPORT_VAR( x ) FT_FUNCTION_DECLARATION( x ) #endif - /* When compiling FreeType as a DLL or DSO with hidden visibility, */ - /* some systems/compilers need a special attribute in front OR after */ - /* the return type of function declarations. */ - /* */ - /* Two macros are used within the FreeType source code to define */ - /* exported library functions: `FT_EXPORT` and `FT_EXPORT_DEF`. */ - /* */ - /* - `FT_EXPORT( return_type )` */ - /* */ - /* is used in a function declaration, as in */ - /* */ - /* ``` */ - /* FT_EXPORT( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ); */ - /* ``` */ - /* */ - /* - `FT_EXPORT_DEF( return_type )` */ - /* */ - /* is used in a function definition, as in */ - /* */ - /* ``` */ - /* FT_EXPORT_DEF( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ) */ - /* { */ - /* ... some code ... */ - /* return FT_Err_Ok; */ - /* } */ - /* ``` */ - /* */ - /* You can provide your own implementation of `FT_EXPORT` and */ - /* `FT_EXPORT_DEF` here if you want. */ - /* */ - /* To export a variable, use `FT_EXPORT_VAR`. */ - /* */ + /* + * When compiling FreeType as a DLL or DSO with hidden visibility, + * some systems/compilers need a special attribute in front OR after + * the return type of function declarations. + * + * Two macros are used within the FreeType source code to define + * exported library functions: `FT_EXPORT` and `FT_EXPORT_DEF`. + * + * - `FT_EXPORT( return_type )` + * + * is used in a function declaration, as in + * + * ``` + * FT_EXPORT( FT_Error ) + * FT_Init_FreeType( FT_Library* alibrary ); + * ``` + * + * - `FT_EXPORT_DEF( return_type )` + * + * is used in a function definition, as in + * + * ``` + * FT_EXPORT_DEF( FT_Error ) + * FT_Init_FreeType( FT_Library* alibrary ) + * { + * ... some code ... + * return FT_Err_Ok; + * } + * ``` + * + * You can provide your own implementation of `FT_EXPORT` and + * `FT_EXPORT_DEF` here if you want. + * + * To export a variable, use `FT_EXPORT_VAR`. + */ /* See `freetype/config/compiler_macros.h` for the `FT_EXPORT` definition */ #define FT_EXPORT_DEF( x ) FT_FUNCTION_DEFINITION( x ) - /* The following macros are needed to compile the library with a */ - /* C++ compiler and with 16bit compilers. */ - /* */ - - /* This is special. Within C++, you must specify `extern "C"` for */ - /* functions which are used via function pointers, and you also */ - /* must do that for structures which contain function pointers to */ - /* assure C linkage -- it's not possible to have (local) anonymous */ - /* functions which are accessed by (global) function pointers. */ - /* */ - /* */ - /* FT_CALLBACK_DEF is used to _define_ a callback function, */ - /* located in the same source code file as the structure that uses */ - /* it. */ - /* */ - /* FT_BASE_CALLBACK and FT_BASE_CALLBACK_DEF are used to declare */ - /* and define a callback function, respectively, in a similar way */ - /* as FT_BASE and FT_BASE_DEF work. */ - /* */ - /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */ - /* contains pointers to callback functions. */ - /* */ - /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable */ - /* that contains pointers to callback functions. */ - /* */ - /* */ - /* Some 16bit compilers have to redefine these macros to insert */ - /* the infamous `_cdecl` or `__fastcall` declarations. */ - /* */ + /* + * The following macros are needed to compile the library with a + * C++ compiler and with 16bit compilers. + */ + + /* + * This is special. Within C++, you must specify `extern "C"` for + * functions which are used via function pointers, and you also + * must do that for structures which contain function pointers to + * assure C linkage -- it's not possible to have (local) anonymous + * functions which are accessed by (global) function pointers. + * + * + * FT_CALLBACK_DEF is used to _define_ a callback function, + * located in the same source code file as the structure that uses + * it. FT_COMPARE_DEF, in addition, ensures the `cdecl` calling + * convention on x86, required by the C library function `qsort`. + * + * FT_BASE_CALLBACK and FT_BASE_CALLBACK_DEF are used to declare + * and define a callback function, respectively, in a similar way + * as FT_BASE and FT_BASE_DEF work. + * + * FT_CALLBACK_TABLE is used to _declare_ a constant variable that + * contains pointers to callback functions. + * + * FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable + * that contains pointers to callback functions. + * + * + * Some 16bit compilers have to redefine these macros to insert + * the infamous `_cdecl` or `__fastcall` declarations. + */ #ifdef __cplusplus #define FT_CALLBACK_DEF( x ) extern "C" x #else #define FT_CALLBACK_DEF( x ) static x #endif +#if defined( __i386__ ) +#define FT_COMPARE_DEF( x ) FT_CALLBACK_DEF( x ) __attribute__(( cdecl )) +#elif defined( _M_IX86 ) +#define FT_COMPARE_DEF( x ) FT_CALLBACK_DEF( x ) __cdecl +#else +#define FT_COMPARE_DEF( x ) FT_CALLBACK_DEF( x ) +#endif + #define FT_BASE_CALLBACK( x ) FT_FUNCTION_DECLARATION( x ) #define FT_BASE_CALLBACK_DEF( x ) FT_FUNCTION_DEFINITION( x ) diff --git a/thirdparty/freetype/include/freetype/internal/ftcalc.h b/thirdparty/freetype/include/freetype/internal/ftcalc.h index c65307472f..f88e055318 100644 --- a/thirdparty/freetype/include/freetype/internal/ftcalc.h +++ b/thirdparty/freetype/include/freetype/internal/ftcalc.h @@ -4,7 +4,7 @@ * * Arithmetic computations (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -359,8 +359,8 @@ FT_BEGIN_HEADER #ifndef FT_CONFIG_OPTION_NO_ASSEMBLER -#if defined( __GNUC__ ) && \ - ( __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 4 ) ) +#if defined( __clang__ ) || ( defined( __GNUC__ ) && \ + ( __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 4 ) ) ) #if FT_SIZEOF_INT == 4 @@ -370,12 +370,25 @@ FT_BEGIN_HEADER #define FT_MSB( x ) ( 31 - __builtin_clzl( x ) ) -#endif /* __GNUC__ */ +#endif +#elif defined( _MSC_VER ) && _MSC_VER >= 1400 -#elif defined( _MSC_VER ) && ( _MSC_VER >= 1400 ) +#if defined( _WIN32_WCE ) -#if FT_SIZEOF_INT == 4 +#include <cmnintrin.h> +#pragma intrinsic( _CountLeadingZeros ) + +#define FT_MSB( x ) ( 31 - _CountLeadingZeros( x ) ) + +#elif defined( _M_ARM64 ) || defined( _M_ARM ) + +#include <intrin.h> +#pragma intrinsic( _CountLeadingZeros ) + +#define FT_MSB( x ) ( 31 - _CountLeadingZeros( x ) ) + +#elif defined( _M_IX86 ) || defined( _M_AMD64 ) || defined( _M_IA64 ) #include <intrin.h> #pragma intrinsic( _BitScanReverse ) @@ -391,15 +404,27 @@ FT_BEGIN_HEADER return (FT_Int32)where; } -#define FT_MSB( x ) ( FT_MSB_i386( x ) ) +#define FT_MSB( x ) FT_MSB_i386( x ) #endif -#endif /* _MSC_VER */ +#elif defined( __DECC ) || defined( __DECCXX ) + +#include <builtins.h> + +#define FT_MSB( x ) (FT_Int)( 63 - _leadz( x ) ) +#elif defined( _CRAYC ) + +#include <intrinsics.h> + +#define FT_MSB( x ) (FT_Int)( 31 - _leadz32( x ) ) + +#endif /* FT_MSB macro definitions */ #endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ + #ifndef FT_MSB FT_BASE( FT_Int ) @@ -487,7 +512,7 @@ FT_BEGIN_HEADER #define NEG_INT32( a ) \ (FT_Int32)( (FT_UInt32)0 - (FT_UInt32)(a) ) -#ifdef FT_LONG64 +#ifdef FT_INT64 #define ADD_INT64( a, b ) \ (FT_Int64)( (FT_UInt64)(a) + (FT_UInt64)(b) ) @@ -498,7 +523,7 @@ FT_BEGIN_HEADER #define NEG_INT64( a ) \ (FT_Int64)( (FT_UInt64)0 - (FT_UInt64)(a) ) -#endif /* FT_LONG64 */ +#endif /* FT_INT64 */ FT_END_HEADER diff --git a/thirdparty/freetype/include/freetype/internal/ftdebug.h b/thirdparty/freetype/include/freetype/internal/ftdebug.h index df5357ad55..5e8d9294a2 100644 --- a/thirdparty/freetype/include/freetype/internal/ftdebug.h +++ b/thirdparty/freetype/include/freetype/internal/ftdebug.h @@ -4,7 +4,7 @@ * * Debugging and logging component (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -31,9 +31,24 @@ #include "compiler-macros.h" +#ifdef FT_DEBUG_LOGGING +#define DLG_STATIC +#include <dlg/output.h> +#include <dlg/dlg.h> + +#include <freetype/ftlogging.h> +#endif /* FT_DEBUG_LOGGING */ + FT_BEGIN_HEADER + /* force the definition of FT_DEBUG_LEVEL_TRACE if FT_DEBUG_LOGGING is */ + /* already defined. */ + /* */ +#ifdef FT_DEBUG_LOGGING +#undef FT_DEBUG_LEVEL_TRACE +#define FT_DEBUG_LEVEL_TRACE +#endif /* force the definition of FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE */ /* is already defined; this simplifies the following #ifdefs */ @@ -82,21 +97,67 @@ FT_BEGIN_HEADER * Each component must define the macro FT_COMPONENT to a valid FT_Trace * value before using any TRACE macro. * + * To get consistent logging output, there should be no newline character + * (i.e., '\n') or a single trailing one in the message string of + * `FT_TRACEx` and `FT_ERROR`. */ -#ifdef FT_DEBUG_LEVEL_TRACE - /* we need two macros here to make cpp expand `FT_COMPONENT' */ -#define FT_TRACE_COMP( x ) FT_TRACE_COMP_( x ) -#define FT_TRACE_COMP_( x ) trace_ ## x + /************************************************************************* + * + * If FT_DEBUG_LOGGING is enabled, tracing messages are sent to dlg's API. + * If FT_DEBUG_LOGGING is disabled, tracing messages are sent to + * `FT_Message` (defined in ftdebug.c). + */ +#ifdef FT_DEBUG_LOGGING + + /* we need two macros to convert the names of `FT_COMPONENT` to a string */ +#define FT_LOGGING_TAG( x ) FT_LOGGING_TAG_( x ) +#define FT_LOGGING_TAG_( x ) #x -#define FT_TRACE( level, varformat ) \ + /* we need two macros to convert the component and the trace level */ + /* to a string that combines them */ +#define FT_LOGGING_TAGX( x, y ) FT_LOGGING_TAGX_( x, y ) +#define FT_LOGGING_TAGX_( x, y ) #x ":" #y + + +#define FT_LOG( level, varformat ) \ + do \ + { \ + const char* dlg_tag = FT_LOGGING_TAGX( FT_COMPONENT, level ); \ + \ + \ + ft_add_tag( dlg_tag ); \ + if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] >= level ) \ + { \ + if ( custom_output_handler != NULL ) \ + FT_Logging_Callback varformat; \ + else \ + dlg_trace varformat; \ + } \ + ft_remove_tag( dlg_tag ); \ + } while( 0 ) + +#else /* !FT_DEBUG_LOGGING */ + +#define FT_LOG( level, varformat ) \ do \ { \ if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] >= level ) \ FT_Message varformat; \ } while ( 0 ) +#endif /* !FT_DEBUG_LOGGING */ + + +#ifdef FT_DEBUG_LEVEL_TRACE + + /* we need two macros here to make cpp expand `FT_COMPONENT' */ +#define FT_TRACE_COMP( x ) FT_TRACE_COMP_( x ) +#define FT_TRACE_COMP_( x ) trace_ ## x + +#define FT_TRACE( level, varformat ) FT_LOG( level, varformat ) + #else /* !FT_DEBUG_LEVEL_TRACE */ #define FT_TRACE( level, varformat ) do { } while ( 0 ) /* nothing */ @@ -204,7 +265,32 @@ FT_BEGIN_HEADER #ifdef FT_DEBUG_LEVEL_ERROR -#define FT_ERROR( varformat ) FT_Message varformat + /************************************************************************** + * + * If FT_DEBUG_LOGGING is enabled, error messages are sent to dlg's API. + * If FT_DEBUG_LOGGING is disabled, error messages are sent to `FT_Message` + * (defined in ftdebug.c). + * + */ +#ifdef FT_DEBUG_LOGGING + +#define FT_ERROR( varformat ) \ + do \ + { \ + const char* dlg_tag = FT_LOGGING_TAG( FT_COMPONENT ); \ + \ + \ + ft_add_tag( dlg_tag ); \ + dlg_trace varformat; \ + ft_remove_tag( dlg_tag ); \ + } while ( 0 ) + +#else /* !FT_DEBUG_LOGGING */ + +#define FT_ERROR( varformat ) FT_Message varformat + +#endif /* !FT_DEBUG_LOGGING */ + #else /* !FT_DEBUG_LEVEL_ERROR */ @@ -277,6 +363,77 @@ FT_BEGIN_HEADER FT_BASE( void ) ft_debug_init( void ); + +#ifdef FT_DEBUG_LOGGING + + /************************************************************************** + * + * 'dlg' uses output handlers to control how and where log messages are + * printed. Therefore we need to define a default output handler for + * FreeType. + */ + FT_BASE( void ) + ft_log_handler( const struct dlg_origin* origin, + const char* string, + void* data ); + + + /************************************************************************** + * + * 1. `ft_default_log_handler` stores the function pointer that is used + * internally by FreeType to print logs to a file. + * + * 2. `custom_output_handler` stores the function pointer to the callback + * function provided by the user. + * + * It is defined in `ftdebug.c`. + */ + extern dlg_handler ft_default_log_handler; + extern FT_Custom_Log_Handler custom_output_handler; + + + /************************************************************************** + * + * If FT_DEBUG_LOGGING macro is enabled, FreeType needs to initialize and + * un-initialize `FILE*`. + * + * These functions are defined in `ftdebug.c`. + */ + FT_BASE( void ) + ft_logging_init( void ); + + FT_BASE( void ) + ft_logging_deinit( void ); + + + /************************************************************************** + * + * For printing the name of `FT_COMPONENT` along with the actual log we + * need to add a tag with the name of `FT_COMPONENT`. + * + * These functions are defined in `ftdebug.c`. + */ + FT_BASE( void ) + ft_add_tag( const char* tag ); + + FT_BASE( void ) + ft_remove_tag( const char* tag ); + + + /************************************************************************** + * + * A function to print log data using a custom callback logging function + * (which is set using `FT_Set_Log_Handler`). + * + * This function is defined in `ftdebug.c`. + */ + FT_BASE( void ) + FT_Logging_Callback( const char* fmt, + ... ); + +#endif /* FT_DEBUG_LOGGING */ + + FT_END_HEADER #endif /* FTDEBUG_H_ */ diff --git a/thirdparty/freetype/include/freetype/internal/ftdrv.h b/thirdparty/freetype/include/freetype/internal/ftdrv.h index 7f22710eae..0db323d5ab 100644 --- a/thirdparty/freetype/include/freetype/internal/ftdrv.h +++ b/thirdparty/freetype/include/freetype/internal/ftdrv.h @@ -4,7 +4,7 @@ * * FreeType internal font driver interface (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/ftgloadr.h b/thirdparty/freetype/include/freetype/internal/ftgloadr.h index 27b8659f7c..fea931c3aa 100644 --- a/thirdparty/freetype/include/freetype/internal/ftgloadr.h +++ b/thirdparty/freetype/include/freetype/internal/ftgloadr.h @@ -4,7 +4,7 @@ * * The FreeType glyph loader (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg * * This file is part of the FreeType project, and may only be used, @@ -22,6 +22,7 @@ #include <freetype/freetype.h> +#include "compiler-macros.h" FT_BEGIN_HEADER diff --git a/thirdparty/freetype/include/freetype/internal/ftmemory.h b/thirdparty/freetype/include/freetype/internal/ftmemory.h index ddb18b0512..e20d949696 100644 --- a/thirdparty/freetype/include/freetype/internal/ftmemory.h +++ b/thirdparty/freetype/include/freetype/internal/ftmemory.h @@ -4,7 +4,7 @@ * * The FreeType memory management macros (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg * * This file is part of the FreeType project, and may only be used, @@ -344,14 +344,13 @@ extern "C++" #define FT_RENEW_ARRAY( ptr, curcnt, newcnt ) \ FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) ) -#define FT_QNEW( ptr ) \ - FT_MEM_SET_ERROR( FT_MEM_QNEW( ptr ) ) +#define FT_QNEW( ptr ) FT_MEM_SET_ERROR( FT_MEM_QNEW( ptr ) ) -#define FT_QNEW_ARRAY( ptr, count ) \ - FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) ) +#define FT_QNEW_ARRAY( ptr, count ) \ + FT_MEM_SET_ERROR( FT_MEM_QNEW_ARRAY( ptr, count ) ) -#define FT_QRENEW_ARRAY( ptr, curcnt, newcnt ) \ - FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) ) +#define FT_QRENEW_ARRAY( ptr, curcnt, newcnt ) \ + FT_MEM_SET_ERROR( FT_MEM_QRENEW_ARRAY( ptr, curcnt, newcnt ) ) FT_BASE( FT_Pointer ) diff --git a/thirdparty/freetype/include/freetype/internal/ftobjs.h b/thirdparty/freetype/include/freetype/internal/ftobjs.h index 25db2c494f..e52a26aa06 100644 --- a/thirdparty/freetype/include/freetype/internal/ftobjs.h +++ b/thirdparty/freetype/include/freetype/internal/ftobjs.h @@ -4,7 +4,7 @@ * * The FreeType private base classes (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -673,7 +673,7 @@ FT_BEGIN_HEADER /* Set the metrics according to a size request. */ - FT_BASE( void ) + FT_BASE( FT_Error ) FT_Request_Metrics( FT_Face face, FT_Size_Request req ); diff --git a/thirdparty/freetype/include/freetype/internal/ftpsprop.h b/thirdparty/freetype/include/freetype/internal/ftpsprop.h index 81ec29151c..d94d0d7e4b 100644 --- a/thirdparty/freetype/include/freetype/internal/ftpsprop.h +++ b/thirdparty/freetype/include/freetype/internal/ftpsprop.h @@ -4,7 +4,7 @@ * * Get and set properties of PostScript drivers (specification). * - * Copyright (C) 2017-2020 by + * Copyright (C) 2017-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/ftrfork.h b/thirdparty/freetype/include/freetype/internal/ftrfork.h index 1b7b25acbe..1c56d6ceb7 100644 --- a/thirdparty/freetype/include/freetype/internal/ftrfork.h +++ b/thirdparty/freetype/include/freetype/internal/ftrfork.h @@ -4,7 +4,7 @@ * * Embedded resource forks accessor (specification). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * Masatake YAMATO and Redhat K.K. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/ftserv.h b/thirdparty/freetype/include/freetype/internal/ftserv.h index 6e1a9472da..fa82c31fcd 100644 --- a/thirdparty/freetype/include/freetype/internal/ftserv.h +++ b/thirdparty/freetype/include/freetype/internal/ftserv.h @@ -4,7 +4,7 @@ * * The FreeType services (specification only). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/ftstream.h b/thirdparty/freetype/include/freetype/internal/ftstream.h index e7d922260f..7f3af120c2 100644 --- a/thirdparty/freetype/include/freetype/internal/ftstream.h +++ b/thirdparty/freetype/include/freetype/internal/ftstream.h @@ -4,7 +4,7 @@ * * Stream handling (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -196,9 +196,9 @@ FT_BEGIN_HEADER FT_BYTE_U32( p, 2, 8 ) | \ FT_BYTE_U32( p, 3, 0 ) ) -#define FT_PEEK_OFF3( p ) FT_INT32( FT_BYTE_U32( p, 0, 16 ) | \ - FT_BYTE_U32( p, 1, 8 ) | \ - FT_BYTE_U32( p, 2, 0 ) ) +#define FT_PEEK_OFF3( p ) ( FT_INT32( FT_BYTE_U32( p, 0, 24 ) | \ + FT_BYTE_U32( p, 1, 16 ) | \ + FT_BYTE_U32( p, 2, 8 ) ) >> 8 ) #define FT_PEEK_UOFF3( p ) FT_UINT32( FT_BYTE_U32( p, 0, 16 ) | \ FT_BYTE_U32( p, 1, 8 ) | \ @@ -220,9 +220,9 @@ FT_BEGIN_HEADER FT_BYTE_U32( p, 1, 8 ) | \ FT_BYTE_U32( p, 0, 0 ) ) -#define FT_PEEK_OFF3_LE( p ) FT_INT32( FT_BYTE_U32( p, 2, 16 ) | \ - FT_BYTE_U32( p, 1, 8 ) | \ - FT_BYTE_U32( p, 0, 0 ) ) +#define FT_PEEK_OFF3_LE( p ) ( FT_INT32( FT_BYTE_U32( p, 2, 24 ) | \ + FT_BYTE_U32( p, 1, 16 ) | \ + FT_BYTE_U32( p, 0, 8 ) ) >> 8 ) #define FT_PEEK_UOFF3_LE( p ) FT_UINT32( FT_BYTE_U32( p, 2, 16 ) | \ FT_BYTE_U32( p, 1, 8 ) | \ @@ -305,11 +305,10 @@ FT_BEGIN_HEADER #else #define FT_GET_MACRO( func, type ) ( (type)func( stream ) ) -#define FT_GET_CHAR() FT_GET_MACRO( FT_Stream_GetChar, FT_Char ) -#define FT_GET_BYTE() FT_GET_MACRO( FT_Stream_GetChar, FT_Byte ) +#define FT_GET_CHAR() FT_GET_MACRO( FT_Stream_GetByte, FT_Char ) +#define FT_GET_BYTE() FT_GET_MACRO( FT_Stream_GetByte, FT_Byte ) #define FT_GET_SHORT() FT_GET_MACRO( FT_Stream_GetUShort, FT_Short ) #define FT_GET_USHORT() FT_GET_MACRO( FT_Stream_GetUShort, FT_UShort ) -#define FT_GET_OFF3() FT_GET_MACRO( FT_Stream_GetUOffset, FT_Long ) #define FT_GET_UOFF3() FT_GET_MACRO( FT_Stream_GetUOffset, FT_ULong ) #define FT_GET_LONG() FT_GET_MACRO( FT_Stream_GetULong, FT_Long ) #define FT_GET_ULONG() FT_GET_MACRO( FT_Stream_GetULong, FT_ULong ) @@ -333,11 +332,10 @@ FT_BEGIN_HEADER * `FT_STREAM_POS'. They use the full machinery to check whether a read is * valid. */ -#define FT_READ_BYTE( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Byte, var ) -#define FT_READ_CHAR( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Char, var ) +#define FT_READ_BYTE( var ) FT_READ_MACRO( FT_Stream_ReadByte, FT_Byte, var ) +#define FT_READ_CHAR( var ) FT_READ_MACRO( FT_Stream_ReadByte, FT_Char, var ) #define FT_READ_SHORT( var ) FT_READ_MACRO( FT_Stream_ReadUShort, FT_Short, var ) #define FT_READ_USHORT( var ) FT_READ_MACRO( FT_Stream_ReadUShort, FT_UShort, var ) -#define FT_READ_OFF3( var ) FT_READ_MACRO( FT_Stream_ReadUOffset, FT_Long, var ) #define FT_READ_UOFF3( var ) FT_READ_MACRO( FT_Stream_ReadUOffset, FT_ULong, var ) #define FT_READ_LONG( var ) FT_READ_MACRO( FT_Stream_ReadULong, FT_Long, var ) #define FT_READ_ULONG( var ) FT_READ_MACRO( FT_Stream_ReadULong, FT_ULong, var ) @@ -457,8 +455,8 @@ FT_BEGIN_HEADER /* read a byte from an entered frame */ - FT_BASE( FT_Char ) - FT_Stream_GetChar( FT_Stream stream ); + FT_BASE( FT_Byte ) + FT_Stream_GetByte( FT_Stream stream ); /* read a 16-bit big-endian unsigned integer from an entered frame */ FT_BASE( FT_UShort ) @@ -482,8 +480,8 @@ FT_BEGIN_HEADER /* read a byte from a stream */ - FT_BASE( FT_Char ) - FT_Stream_ReadChar( FT_Stream stream, + FT_BASE( FT_Byte ) + FT_Stream_ReadByte( FT_Stream stream, FT_Error* error ); /* read a 16-bit big-endian unsigned integer from a stream */ diff --git a/thirdparty/freetype/include/freetype/internal/fttrace.h b/thirdparty/freetype/include/freetype/internal/fttrace.h index 58bd77413c..3307556bff 100644 --- a/thirdparty/freetype/include/freetype/internal/fttrace.h +++ b/thirdparty/freetype/include/freetype/internal/fttrace.h @@ -4,7 +4,7 @@ * * Tracing handling (specification only). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -18,6 +18,11 @@ /* definitions of trace levels for FreeType 2 */ + /* the maximum string length (if the argument to `FT_TRACE_DEF` */ + /* gets used as a string) plus one charachter for ':' plus */ + /* another one for the trace level */ +#define FT_MAX_TRACE_LEVEL_LENGTH (9 + 1 + 1) + /* the first level must always be `trace_any' */ FT_TRACE_DEF( any ) @@ -38,12 +43,14 @@ FT_TRACE_DEF( checksum ) /* bitmap checksum (ftobjs.c) */ FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */ FT_TRACE_DEF( psprops ) /* PS driver properties (ftpsprop.c) */ FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */ +FT_TRACE_DEF( synth ) /* bold/slant synthesizer (ftsynth.c) */ + + /* rasterizers */ FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */ FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */ -FT_TRACE_DEF( synth ) /* bold/slant synthesizer (ftsynth.c) */ - /* Cache sub-system */ -FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */ + /* cache sub-system */ +FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */ /* SFNT driver components */ FT_TRACE_DEF( sfdriver ) /* SFNT font driver (sfdriver.c) */ @@ -77,6 +84,7 @@ FT_TRACE_DEF( t1objs ) FT_TRACE_DEF( t1parse ) /* PostScript helper module `psaux' */ +FT_TRACE_DEF( afmparse ) FT_TRACE_DEF( cffdecode ) FT_TRACE_DEF( psconv ) FT_TRACE_DEF( psobjs ) @@ -151,8 +159,10 @@ FT_TRACE_DEF( afglobal ) FT_TRACE_DEF( afhints ) FT_TRACE_DEF( afmodule ) FT_TRACE_DEF( aflatin ) -FT_TRACE_DEF( aflatin2 ) FT_TRACE_DEF( afshaper ) -FT_TRACE_DEF( afwarp ) + + /* SDF components */ +FT_TRACE_DEF( sdf ) /* signed distance raster for outlines (ftsdf.c) */ +FT_TRACE_DEF( bsdf ) /* signed distance raster for bitmaps (ftbsdf.c) */ /* END */ diff --git a/thirdparty/freetype/include/freetype/internal/ftvalid.h b/thirdparty/freetype/include/freetype/internal/ftvalid.h index a5bc6c9b52..7bdfa62f32 100644 --- a/thirdparty/freetype/include/freetype/internal/ftvalid.h +++ b/thirdparty/freetype/include/freetype/internal/ftvalid.h @@ -4,7 +4,7 @@ * * FreeType validation support (specification). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/internal.h b/thirdparty/freetype/include/freetype/internal/internal.h deleted file mode 100644 index 766bf64c23..0000000000 --- a/thirdparty/freetype/include/freetype/internal/internal.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** - * - * internal.h - * - * Internal header files (specification only). - * - * Copyright (C) 1996-2020 by - * David Turner, Robert Wilhelm, and Werner Lemberg. - * - * This file is part of the FreeType project, and may only be used, - * modified, and distributed under the terms of the FreeType project - * license, LICENSE.TXT. By continuing to use, modify, or distribute - * this file you indicate that you have read the license and - * understand and accept it fully. - * - */ - - - /************************************************************************** - * - * This file is automatically included by `ft2build.h`. Do not include it - * manually! - * - */ - - -#define FT_INTERNAL_OBJECTS_H <freetype/internal/ftobjs.h> -#define FT_INTERNAL_STREAM_H <freetype/internal/ftstream.h> -#define FT_INTERNAL_MEMORY_H <freetype/internal/ftmemory.h> -#define FT_INTERNAL_DEBUG_H <freetype/internal/ftdebug.h> -#define FT_INTERNAL_CALC_H <freetype/internal/ftcalc.h> -#define FT_INTERNAL_HASH_H <freetype/internal/fthash.h> -#define FT_INTERNAL_DRIVER_H <freetype/internal/ftdrv.h> -#define FT_INTERNAL_TRACE_H <freetype/internal/fttrace.h> -#define FT_INTERNAL_GLYPH_LOADER_H <freetype/internal/ftgloadr.h> -#define FT_INTERNAL_SFNT_H <freetype/internal/sfnt.h> -#define FT_INTERNAL_SERVICE_H <freetype/internal/ftserv.h> -#define FT_INTERNAL_RFORK_H <freetype/internal/ftrfork.h> -#define FT_INTERNAL_VALIDATE_H <freetype/internal/ftvalid.h> - -#define FT_INTERNAL_TRUETYPE_TYPES_H <freetype/internal/tttypes.h> -#define FT_INTERNAL_TYPE1_TYPES_H <freetype/internal/t1types.h> -#define FT_INTERNAL_WOFF_TYPES_H <freetype/internal/wofftypes.h> - -#define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h> -#define FT_INTERNAL_POSTSCRIPT_HINTS_H <freetype/internal/pshints.h> -#define FT_INTERNAL_POSTSCRIPT_PROPS_H <freetype/internal/ftpsprop.h> - -#define FT_INTERNAL_AUTOHINT_H <freetype/internal/autohint.h> - -#define FT_INTERNAL_CFF_TYPES_H <freetype/internal/cfftypes.h> -#define FT_INTERNAL_CFF_OBJECTS_TYPES_H <freetype/internal/cffotypes.h> - - -#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ - - /* We disable the warning `conditional expression is constant' here */ - /* in order to compile cleanly with the maximum level of warnings. */ - /* In particular, the warning complains about stuff like `while(0)' */ - /* which is very useful in macro definitions. There is no benefit */ - /* in having it enabled. */ -#pragma warning( disable : 4127 ) - -#endif /* _MSC_VER */ - - -/* END */ diff --git a/thirdparty/freetype/include/freetype/internal/psaux.h b/thirdparty/freetype/include/freetype/internal/psaux.h index 8e0a262fd5..6c6399aa16 100644 --- a/thirdparty/freetype/include/freetype/internal/psaux.h +++ b/thirdparty/freetype/include/freetype/internal/psaux.h @@ -5,7 +5,7 @@ * Auxiliary functions and data structures related to PostScript fonts * (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/pshints.h b/thirdparty/freetype/include/freetype/internal/pshints.h index 663e9d3488..9dbb0776b0 100644 --- a/thirdparty/freetype/include/freetype/internal/pshints.h +++ b/thirdparty/freetype/include/freetype/internal/pshints.h @@ -6,7 +6,7 @@ * recorders (specification only). These are used to support native * T1/T2 hints in the 'type1', 'cid', and 'cff' font drivers. * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svbdf.h b/thirdparty/freetype/include/freetype/internal/services/svbdf.h index 81f5a06b62..879aa61383 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svbdf.h +++ b/thirdparty/freetype/include/freetype/internal/services/svbdf.h @@ -4,7 +4,7 @@ * * The FreeType BDF services (specification). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svcfftl.h b/thirdparty/freetype/include/freetype/internal/services/svcfftl.h index 1d2dbb6a8e..f6424e424d 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svcfftl.h +++ b/thirdparty/freetype/include/freetype/internal/services/svcfftl.h @@ -4,7 +4,7 @@ * * The FreeType CFF tables loader service (specification). * - * Copyright (C) 2017-2020 by + * Copyright (C) 2017-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svcid.h b/thirdparty/freetype/include/freetype/internal/services/svcid.h index bd49f3270a..7ef5afd0b7 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svcid.h +++ b/thirdparty/freetype/include/freetype/internal/services/svcid.h @@ -4,7 +4,7 @@ * * The FreeType CID font services (specification). * - * Copyright (C) 2007-2020 by + * Copyright (C) 2007-2021 by * Derek Clegg and Michael Toftdal. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svfntfmt.h b/thirdparty/freetype/include/freetype/internal/services/svfntfmt.h index 6114d638af..cc87fc122d 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svfntfmt.h +++ b/thirdparty/freetype/include/freetype/internal/services/svfntfmt.h @@ -4,7 +4,7 @@ * * The FreeType font format service (specification only). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svgldict.h b/thirdparty/freetype/include/freetype/internal/services/svgldict.h index f9443e40d6..4256f14a04 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svgldict.h +++ b/thirdparty/freetype/include/freetype/internal/services/svgldict.h @@ -4,7 +4,7 @@ * * The FreeType glyph dictionary services (specification). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svgxval.h b/thirdparty/freetype/include/freetype/internal/services/svgxval.h index 83c2f26cee..f36d55602a 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svgxval.h +++ b/thirdparty/freetype/include/freetype/internal/services/svgxval.h @@ -4,7 +4,7 @@ * * FreeType API for validating TrueTypeGX/AAT tables (specification). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/include/freetype/internal/services/svkern.h b/thirdparty/freetype/include/freetype/internal/services/svkern.h index 13cfb32722..99dc2d97a3 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svkern.h +++ b/thirdparty/freetype/include/freetype/internal/services/svkern.h @@ -4,7 +4,7 @@ * * The FreeType Kerning service (specification). * - * Copyright (C) 2006-2020 by + * Copyright (C) 2006-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svmetric.h b/thirdparty/freetype/include/freetype/internal/services/svmetric.h index 2b30edaabe..b9c95a7c9c 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svmetric.h +++ b/thirdparty/freetype/include/freetype/internal/services/svmetric.h @@ -4,7 +4,7 @@ * * The FreeType services for metrics variations (specification). * - * Copyright (C) 2016-2020 by + * Copyright (C) 2016-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svmm.h b/thirdparty/freetype/include/freetype/internal/services/svmm.h index 5a807636a6..8eac3a3fe3 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svmm.h +++ b/thirdparty/freetype/include/freetype/internal/services/svmm.h @@ -4,7 +4,7 @@ * * The FreeType Multiple Masters and GX var services (specification). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svotval.h b/thirdparty/freetype/include/freetype/internal/services/svotval.h index 763fb2efbe..7afb49e824 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svotval.h +++ b/thirdparty/freetype/include/freetype/internal/services/svotval.h @@ -4,7 +4,7 @@ * * The FreeType OpenType validation service (specification). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svpfr.h b/thirdparty/freetype/include/freetype/internal/services/svpfr.h index bdeba0785c..98442bf83d 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svpfr.h +++ b/thirdparty/freetype/include/freetype/internal/services/svpfr.h @@ -4,7 +4,7 @@ * * Internal PFR service functions (specification). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svpostnm.h b/thirdparty/freetype/include/freetype/internal/services/svpostnm.h index 8ef62c5f92..5a25c5a58a 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svpostnm.h +++ b/thirdparty/freetype/include/freetype/internal/services/svpostnm.h @@ -4,7 +4,7 @@ * * The FreeType PostScript name services (specification). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svprop.h b/thirdparty/freetype/include/freetype/internal/services/svprop.h index 8f755436a1..9b71000c52 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svprop.h +++ b/thirdparty/freetype/include/freetype/internal/services/svprop.h @@ -4,7 +4,7 @@ * * The FreeType property service (specification). * - * Copyright (C) 2012-2020 by + * Copyright (C) 2012-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svpscmap.h b/thirdparty/freetype/include/freetype/internal/services/svpscmap.h index b4dcd80759..346f5e2a7c 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svpscmap.h +++ b/thirdparty/freetype/include/freetype/internal/services/svpscmap.h @@ -4,7 +4,7 @@ * * The FreeType PostScript charmap service (specification). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svpsinfo.h b/thirdparty/freetype/include/freetype/internal/services/svpsinfo.h index 1e7276ff43..49aa4d565d 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svpsinfo.h +++ b/thirdparty/freetype/include/freetype/internal/services/svpsinfo.h @@ -4,7 +4,7 @@ * * The FreeType PostScript info service (specification). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svsfnt.h b/thirdparty/freetype/include/freetype/internal/services/svsfnt.h index 39c8b5e19d..4306cbc1b7 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svsfnt.h +++ b/thirdparty/freetype/include/freetype/internal/services/svsfnt.h @@ -4,7 +4,7 @@ * * The FreeType SFNT table loading service (specification). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svttcmap.h b/thirdparty/freetype/include/freetype/internal/services/svttcmap.h index c18bb2336f..775b6bcf20 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svttcmap.h +++ b/thirdparty/freetype/include/freetype/internal/services/svttcmap.h @@ -4,7 +4,7 @@ * * The FreeType TrueType/sfnt cmap extra information service. * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * Masatake YAMATO, Redhat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/include/freetype/internal/services/svtteng.h b/thirdparty/freetype/include/freetype/internal/services/svtteng.h index 7a17e4a755..964934284d 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svtteng.h +++ b/thirdparty/freetype/include/freetype/internal/services/svtteng.h @@ -4,7 +4,7 @@ * * The FreeType TrueType engine query service (specification). * - * Copyright (C) 2006-2020 by + * Copyright (C) 2006-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svttglyf.h b/thirdparty/freetype/include/freetype/internal/services/svttglyf.h index 90a81dd40e..4268467b75 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svttglyf.h +++ b/thirdparty/freetype/include/freetype/internal/services/svttglyf.h @@ -4,7 +4,7 @@ * * The FreeType TrueType glyph service. * - * Copyright (C) 2007-2020 by + * Copyright (C) 2007-2021 by * David Turner. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/services/svwinfnt.h b/thirdparty/freetype/include/freetype/internal/services/svwinfnt.h index 8c915f5257..aa70aa44db 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svwinfnt.h +++ b/thirdparty/freetype/include/freetype/internal/services/svwinfnt.h @@ -4,7 +4,7 @@ * * The FreeType Windows FNT/FONT service (specification). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/sfnt.h b/thirdparty/freetype/include/freetype/internal/sfnt.h index b4c12dbb26..bf4c7e09fe 100644 --- a/thirdparty/freetype/include/freetype/internal/sfnt.h +++ b/thirdparty/freetype/include/freetype/internal/sfnt.h @@ -4,7 +4,7 @@ * * High-level 'sfnt' driver interface (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -527,6 +527,170 @@ FT_BEGIN_HEADER /************************************************************************** * * @functype: + * TT_Get_Color_Glyph_Paint_Func + * + * @description: + * Find the root @FT_OpaquePaint object for a given glyph ID. + * + * @input: + * face :: + * The target face object. + * + * base_glyph :: + * The glyph index the colored glyph layers are associated with. + * + * @output: + * paint :: + * The root @FT_OpaquePaint object. + * + * @return: + * Value~1 if everything is OK. If no color glyph is found, or the root + * paint could not be retrieved, value~0 gets returned. In case of an + * error, value~0 is returned also. + */ + typedef FT_Bool + ( *TT_Get_Color_Glyph_Paint_Func )( TT_Face face, + FT_UInt base_glyph, + FT_Color_Root_Transform root_transform, + FT_OpaquePaint *paint ); + + + /************************************************************************** + * + * @functype: + * TT_Get_Color_Glyph_ClipBox_Func + * + * @description: + * Search for a 'COLR' v1 clip box for the specified `base_glyph` and + * fill the `clip_box` parameter with the 'COLR' v1 'ClipBox' information + * if one is found. + * + * @input: + * face :: + * A handle to the parent face object. + * + * base_glyph :: + * The glyph index for which to retrieve the clip box. + * + * @output: + * clip_box :: + * The clip box for the requested `base_glyph` if one is found. The + * clip box is computed taking scale and transformations configured on + * the @FT_Face into account. @FT_ClipBox contains @FT_Vector values + * in 26.6 format. + * + * @note: + * To retrieve the clip box in font units, reset scale to units-per-em + * and remove transforms configured using @FT_Set_Transform. + * + * @return: + * Value~1 if a ClipBox is found. If no clip box is found or an + * error occured, value~0 is returned. + */ + typedef FT_Bool + ( *TT_Get_Color_Glyph_ClipBox_Func )( TT_Face face, + FT_UInt base_glyph, + FT_ClipBox* clip_box ); + + + /************************************************************************** + * + * @functype: + * TT_Get_Paint_Layers_Func + * + * @description: + * Access the layers of a `PaintColrLayers` table. + * + * @input: + * face :: + * The target face object. + * + * @inout: + * iterator :: + * The @FT_LayerIterator from an @FT_PaintColrLayers object, for which + * the layers are to be retrieved. The internal state of the iterator + * is incremented after one call to this function for retrieving one + * layer. + * + * @output: + * paint :: + * The root @FT_OpaquePaint object referencing the actual paint table. + * + * @return: + * Value~1 if everything is OK. Value~0 gets returned when the paint + * object can not be retrieved or any other error occurs. + */ + typedef FT_Bool + ( *TT_Get_Paint_Layers_Func )( TT_Face face, + FT_LayerIterator* iterator, + FT_OpaquePaint *paint ); + + + /************************************************************************** + * + * @functype: + * TT_Get_Colorline_Stops_Func + * + * @description: + * Get the gradient and solid fill information for a given glyph. + * + * @input: + * face :: + * The target face object. + * + * @inout: + * iterator :: + * An @FT_ColorStopIterator object. For the first call you should set + * `iterator->p` to `NULL`. For all following calls, simply use the + * same object again. + * + * @output: + * color_stop :: + * Color index and alpha value for the retrieved color stop. + * + * @return: + * Value~1 if everything is OK. If there are no more color stops, + * value~0 gets returned. In case of an error, value~0 is returned + * also. + */ + typedef FT_Bool + ( *TT_Get_Colorline_Stops_Func )( TT_Face face, + FT_ColorStop *color_stop, + FT_ColorStopIterator* iterator ); + + + /************************************************************************** + * + * @functype: + * TT_Get_Paint_Func + * + * @description: + * Get the paint details for a given @FT_OpaquePaint object. + * + * @input: + * face :: + * The target face object. + * + * opaque_paint :: + * The @FT_OpaquePaint object. + * + * @output: + * paint :: + * An @FT_COLR_Paint object holding the details on `opaque_paint`. + * + * @return: + * Value~1 if everything is OK. Value~0 if no details can be found for + * this paint or any other error occured. + */ + typedef FT_Bool + ( *TT_Get_Paint_Func )( TT_Face face, + FT_OpaquePaint opaque_paint, + FT_COLR_Paint *paint ); + + + /************************************************************************** + * + * @functype: * TT_Blend_Colr_Func * * @description: @@ -709,73 +873,78 @@ FT_BEGIN_HEADER */ typedef struct SFNT_Interface_ { - TT_Loader_GotoTableFunc goto_table; + TT_Loader_GotoTableFunc goto_table; - TT_Init_Face_Func init_face; - TT_Load_Face_Func load_face; - TT_Done_Face_Func done_face; - FT_Module_Requester get_interface; + TT_Init_Face_Func init_face; + TT_Load_Face_Func load_face; + TT_Done_Face_Func done_face; + FT_Module_Requester get_interface; - TT_Load_Any_Func load_any; + TT_Load_Any_Func load_any; /* these functions are called by `load_face' but they can also */ /* be called from external modules, if there is a need to do so */ - TT_Load_Table_Func load_head; - TT_Load_Metrics_Func load_hhea; - TT_Load_Table_Func load_cmap; - TT_Load_Table_Func load_maxp; - TT_Load_Table_Func load_os2; - TT_Load_Table_Func load_post; + TT_Load_Table_Func load_head; + TT_Load_Metrics_Func load_hhea; + TT_Load_Table_Func load_cmap; + TT_Load_Table_Func load_maxp; + TT_Load_Table_Func load_os2; + TT_Load_Table_Func load_post; - TT_Load_Table_Func load_name; - TT_Free_Table_Func free_name; + TT_Load_Table_Func load_name; + TT_Free_Table_Func free_name; /* this field was called `load_kerning' up to version 2.1.10 */ - TT_Load_Table_Func load_kern; + TT_Load_Table_Func load_kern; - TT_Load_Table_Func load_gasp; - TT_Load_Table_Func load_pclt; + TT_Load_Table_Func load_gasp; + TT_Load_Table_Func load_pclt; /* see `ttload.h'; this field was called `load_bitmap_header' up to */ /* version 2.1.10 */ - TT_Load_Table_Func load_bhed; + TT_Load_Table_Func load_bhed; - TT_Load_SBit_Image_Func load_sbit_image; + TT_Load_SBit_Image_Func load_sbit_image; /* see `ttpost.h' */ - TT_Get_PS_Name_Func get_psname; - TT_Free_Table_Func free_psnames; + TT_Get_PS_Name_Func get_psname; + TT_Free_Table_Func free_psnames; /* starting here, the structure differs from version 2.1.7 */ /* this field was introduced in version 2.1.8, named `get_psname' */ - TT_Face_GetKerningFunc get_kerning; + TT_Face_GetKerningFunc get_kerning; /* new elements introduced after version 2.1.10 */ /* load the font directory, i.e., the offset table and */ /* the table directory */ - TT_Load_Table_Func load_font_dir; - TT_Load_Metrics_Func load_hmtx; + TT_Load_Table_Func load_font_dir; + TT_Load_Metrics_Func load_hmtx; - TT_Load_Table_Func load_eblc; - TT_Free_Table_Func free_eblc; + TT_Load_Table_Func load_eblc; + TT_Free_Table_Func free_eblc; TT_Set_SBit_Strike_Func set_sbit_strike; TT_Load_Strike_Metrics_Func load_strike_metrics; - TT_Load_Table_Func load_cpal; - TT_Load_Table_Func load_colr; - TT_Free_Table_Func free_cpal; - TT_Free_Table_Func free_colr; - TT_Set_Palette_Func set_palette; - TT_Get_Colr_Layer_Func get_colr_layer; - TT_Blend_Colr_Func colr_blend; + TT_Load_Table_Func load_cpal; + TT_Load_Table_Func load_colr; + TT_Free_Table_Func free_cpal; + TT_Free_Table_Func free_colr; + TT_Set_Palette_Func set_palette; + TT_Get_Colr_Layer_Func get_colr_layer; + TT_Get_Color_Glyph_Paint_Func get_colr_glyph_paint; + TT_Get_Color_Glyph_ClipBox_Func get_color_glyph_clipbox; + TT_Get_Paint_Layers_Func get_paint_layers; + TT_Get_Colorline_Stops_Func get_colorline_stops; + TT_Get_Paint_Func get_paint; + TT_Blend_Colr_Func colr_blend; - TT_Get_Metrics_Func get_metrics; + TT_Get_Metrics_Func get_metrics; - TT_Get_Name_Func get_name; - TT_Get_Name_ID_Func get_name_id; + TT_Get_Name_Func get_name; + TT_Get_Name_ID_Func get_name_id; } SFNT_Interface; @@ -820,6 +989,11 @@ FT_BEGIN_HEADER free_colr_, \ set_palette_, \ get_colr_layer_, \ + get_colr_glyph_paint_, \ + get_color_glyph_clipbox, \ + get_paint_layers_, \ + get_colorline_stops_, \ + get_paint_, \ colr_blend_, \ get_metrics_, \ get_name_, \ @@ -860,6 +1034,11 @@ FT_BEGIN_HEADER free_colr_, \ set_palette_, \ get_colr_layer_, \ + get_colr_glyph_paint_, \ + get_color_glyph_clipbox, \ + get_paint_layers_, \ + get_colorline_stops_, \ + get_paint_, \ colr_blend_, \ get_metrics_, \ get_name_, \ diff --git a/thirdparty/freetype/include/freetype/internal/t1types.h b/thirdparty/freetype/include/freetype/internal/t1types.h index 6a0fe5e97d..023c5d08a2 100644 --- a/thirdparty/freetype/include/freetype/internal/t1types.h +++ b/thirdparty/freetype/include/freetype/internal/t1types.h @@ -5,7 +5,7 @@ * Basic Type1/Type2 type definitions and interface (specification * only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/internal/tttypes.h b/thirdparty/freetype/include/freetype/internal/tttypes.h index c36342c93a..651131c8d3 100644 --- a/thirdparty/freetype/include/freetype/internal/tttypes.h +++ b/thirdparty/freetype/include/freetype/internal/tttypes.h @@ -5,7 +5,7 @@ * Basic SFNT/TrueType type definitions and interface (specification * only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -1372,7 +1372,7 @@ FT_BEGIN_HEADER * * num_locations :: * The number of glyph locations in this TrueType file. This should be - * identical to the number of glyphs. Ignored for Type 2 fonts. + * one more than the number of glyphs. Ignored for Type 2 fonts. * * glyph_locations :: * An array of longs. These are offsets to glyph data within the @@ -1598,7 +1598,7 @@ FT_BEGIN_HEADER FT_ULong horz_metrics_size; FT_ULong vert_metrics_size; - FT_ULong num_locations; /* in broken TTF, gid > 0xFFFF */ + FT_ULong num_locations; /* up to 0xFFFF + 1 */ FT_Byte* glyph_locations; FT_Byte* hdmx_table; @@ -1734,7 +1734,7 @@ FT_BEGIN_HEADER FT_UInt glyph_index; FT_Stream stream; - FT_Int byte_len; + FT_UInt byte_len; FT_Short n_contours; FT_BBox bbox; diff --git a/thirdparty/freetype/include/freetype/internal/wofftypes.h b/thirdparty/freetype/include/freetype/internal/wofftypes.h index 1874a138a0..c460107c4d 100644 --- a/thirdparty/freetype/include/freetype/internal/wofftypes.h +++ b/thirdparty/freetype/include/freetype/internal/wofftypes.h @@ -5,7 +5,7 @@ * Basic WOFF/WOFF2 type definitions and interface (specification * only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -92,7 +92,7 @@ FT_BEGIN_HEADER */ typedef struct WOFF_TableRec_ { - FT_ULong Tag; /* table ID */ + FT_Tag Tag; /* table ID */ FT_ULong Offset; /* table file offset */ FT_ULong CompLength; /* compressed table length */ FT_ULong OrigLength; /* uncompressed table length */ @@ -191,7 +191,7 @@ FT_BEGIN_HEADER typedef struct WOFF2_TableRec_ { FT_Byte FlagByte; /* table type and flags */ - FT_ULong Tag; /* table file offset */ + FT_Tag Tag; /* table file offset */ FT_ULong dst_length; /* uncompressed table length */ FT_ULong TransformLength; /* transformed length */ diff --git a/thirdparty/freetype/include/freetype/t1tables.h b/thirdparty/freetype/include/freetype/t1tables.h index 426e14024e..a5f6ae7210 100644 --- a/thirdparty/freetype/include/freetype/t1tables.h +++ b/thirdparty/freetype/include/freetype/t1tables.h @@ -5,7 +5,7 @@ * Basic Type 1/Type 2 tables definitions and interface (specification * only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -360,7 +360,7 @@ FT_BEGIN_HEADER FT_UInt num_subrs; FT_ULong subrmap_offset; - FT_Int sd_bytes; + FT_UInt sd_bytes; } CID_FaceDictRec; @@ -415,11 +415,11 @@ FT_BEGIN_HEADER FT_ULong xuid[16]; FT_ULong cidmap_offset; - FT_Int fd_bytes; - FT_Int gd_bytes; + FT_UInt fd_bytes; + FT_UInt gd_bytes; FT_ULong cid_count; - FT_Int num_dicts; + FT_UInt num_dicts; CID_FaceDict font_dicts; FT_ULong data_offset; diff --git a/thirdparty/freetype/include/freetype/ttnameid.h b/thirdparty/freetype/include/freetype/ttnameid.h index 2b2ed4c613..a09950f542 100644 --- a/thirdparty/freetype/include/freetype/ttnameid.h +++ b/thirdparty/freetype/include/freetype/ttnameid.h @@ -4,7 +4,7 @@ * * TrueType name ID definitions (specification only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -591,7 +591,7 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_MALAY_MALAYSIA 0x043E #define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM 0x083E #define TT_MS_LANGID_KAZAKH_KAZAKHSTAN 0x043F -#define TT_MS_LANGID_KYRGYZ_KYRGYZSTAN /* Cyrillic*/ 0x0440 +#define TT_MS_LANGID_KYRGYZ_KYRGYZSTAN /* Cyrillic */ 0x0440 #define TT_MS_LANGID_KISWAHILI_KENYA 0x0441 #define TT_MS_LANGID_TURKMEN_TURKMENISTAN 0x0442 #define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN 0x0443 diff --git a/thirdparty/freetype/include/freetype/tttables.h b/thirdparty/freetype/include/freetype/tttables.h index c8fa35ef8e..c33d99059d 100644 --- a/thirdparty/freetype/include/freetype/tttables.h +++ b/thirdparty/freetype/include/freetype/tttables.h @@ -5,7 +5,7 @@ * Basic SFNT/TrueType tables definitions and interface * (specification only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/freetype/tttags.h b/thirdparty/freetype/include/freetype/tttags.h index 3c9fbd59d7..47ccc6ddf4 100644 --- a/thirdparty/freetype/include/freetype/tttags.h +++ b/thirdparty/freetype/include/freetype/tttags.h @@ -4,7 +4,7 @@ * * Tags for TrueType and OpenType tables (specification only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/include/ft2build.h b/thirdparty/freetype/include/ft2build.h index b4fd1f8c3e..62686b1b20 100644 --- a/thirdparty/freetype/include/ft2build.h +++ b/thirdparty/freetype/include/ft2build.h @@ -4,7 +4,7 @@ * * FreeType 2 build and setup macros. * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/afangles.c b/thirdparty/freetype/src/autofit/afangles.c deleted file mode 100644 index a2d45eb72c..0000000000 --- a/thirdparty/freetype/src/autofit/afangles.c +++ /dev/null @@ -1,285 +0,0 @@ -/**************************************************************************** - * - * afangles.c - * - * Routines used to compute vector angles with limited accuracy - * and very high speed. It also contains sorting routines (body). - * - * Copyright (C) 2003-2020 by - * David Turner, Robert Wilhelm, and Werner Lemberg. - * - * This file is part of the FreeType project, and may only be used, - * modified, and distributed under the terms of the FreeType project - * license, LICENSE.TXT. By continuing to use, modify, or distribute - * this file you indicate that you have read the license and - * understand and accept it fully. - * - */ - - -#include "aftypes.h" - - - /* - * We are not using `af_angle_atan' anymore, but we keep the source - * code below just in case... - */ - - -#if 0 - - - /* - * The trick here is to realize that we don't need a very accurate angle - * approximation. We are going to use the result of `af_angle_atan' to - * only compare the sign of angle differences, or check whether its - * magnitude is very small. - * - * The approximation - * - * dy * PI / (|dx|+|dy|) - * - * should be enough, and much faster to compute. - */ - FT_LOCAL_DEF( AF_Angle ) - af_angle_atan( FT_Fixed dx, - FT_Fixed dy ) - { - AF_Angle angle; - FT_Fixed ax = dx; - FT_Fixed ay = dy; - - - if ( ax < 0 ) - ax = -ax; - if ( ay < 0 ) - ay = -ay; - - ax += ay; - - if ( ax == 0 ) - angle = 0; - else - { - angle = ( AF_ANGLE_PI2 * dy ) / ( ax + ay ); - if ( dx < 0 ) - { - if ( angle >= 0 ) - angle = AF_ANGLE_PI - angle; - else - angle = -AF_ANGLE_PI - angle; - } - } - - return angle; - } - - -#elif 0 - - - /* the following table has been automatically generated with */ - /* the `mather.py' Python script */ - -#define AF_ATAN_BITS 8 - - static const FT_Byte af_arctan[1L << AF_ATAN_BITS] = - { - 0, 0, 1, 1, 1, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 5, - 5, 5, 6, 6, 6, 7, 7, 7, - 8, 8, 8, 9, 9, 9, 10, 10, - 10, 10, 11, 11, 11, 12, 12, 12, - 13, 13, 13, 14, 14, 14, 14, 15, - 15, 15, 16, 16, 16, 17, 17, 17, - 18, 18, 18, 18, 19, 19, 19, 20, - 20, 20, 21, 21, 21, 21, 22, 22, - 22, 23, 23, 23, 24, 24, 24, 24, - 25, 25, 25, 26, 26, 26, 26, 27, - 27, 27, 28, 28, 28, 28, 29, 29, - 29, 30, 30, 30, 30, 31, 31, 31, - 31, 32, 32, 32, 33, 33, 33, 33, - 34, 34, 34, 34, 35, 35, 35, 35, - 36, 36, 36, 36, 37, 37, 37, 38, - 38, 38, 38, 39, 39, 39, 39, 40, - 40, 40, 40, 41, 41, 41, 41, 42, - 42, 42, 42, 42, 43, 43, 43, 43, - 44, 44, 44, 44, 45, 45, 45, 45, - 46, 46, 46, 46, 46, 47, 47, 47, - 47, 48, 48, 48, 48, 48, 49, 49, - 49, 49, 50, 50, 50, 50, 50, 51, - 51, 51, 51, 51, 52, 52, 52, 52, - 52, 53, 53, 53, 53, 53, 54, 54, - 54, 54, 54, 55, 55, 55, 55, 55, - 56, 56, 56, 56, 56, 57, 57, 57, - 57, 57, 57, 58, 58, 58, 58, 58, - 59, 59, 59, 59, 59, 59, 60, 60, - 60, 60, 60, 61, 61, 61, 61, 61, - 61, 62, 62, 62, 62, 62, 62, 63, - 63, 63, 63, 63, 63, 64, 64, 64 - }; - - - FT_LOCAL_DEF( AF_Angle ) - af_angle_atan( FT_Fixed dx, - FT_Fixed dy ) - { - AF_Angle angle; - - - /* check trivial cases */ - if ( dy == 0 ) - { - angle = 0; - if ( dx < 0 ) - angle = AF_ANGLE_PI; - return angle; - } - else if ( dx == 0 ) - { - angle = AF_ANGLE_PI2; - if ( dy < 0 ) - angle = -AF_ANGLE_PI2; - return angle; - } - - angle = 0; - if ( dx < 0 ) - { - dx = -dx; - dy = -dy; - angle = AF_ANGLE_PI; - } - - if ( dy < 0 ) - { - FT_Pos tmp; - - - tmp = dx; - dx = -dy; - dy = tmp; - angle -= AF_ANGLE_PI2; - } - - if ( dx == 0 && dy == 0 ) - return 0; - - if ( dx == dy ) - angle += AF_ANGLE_PI4; - else if ( dx > dy ) - angle += af_arctan[FT_DivFix( dy, dx ) >> ( 16 - AF_ATAN_BITS )]; - else - angle += AF_ANGLE_PI2 - - af_arctan[FT_DivFix( dx, dy ) >> ( 16 - AF_ATAN_BITS )]; - - if ( angle > AF_ANGLE_PI ) - angle -= AF_ANGLE_2PI; - - return angle; - } - - -#endif /* 0 */ - - - FT_LOCAL_DEF( void ) - af_sort_pos( FT_UInt count, - FT_Pos* table ) - { - FT_UInt i, j; - FT_Pos swap; - - - for ( i = 1; i < count; i++ ) - { - for ( j = i; j > 0; j-- ) - { - if ( table[j] >= table[j - 1] ) - break; - - swap = table[j]; - table[j] = table[j - 1]; - table[j - 1] = swap; - } - } - } - - - FT_LOCAL_DEF( void ) - af_sort_and_quantize_widths( FT_UInt* count, - AF_Width table, - FT_Pos threshold ) - { - FT_UInt i, j; - FT_UInt cur_idx; - FT_Pos cur_val; - FT_Pos sum; - AF_WidthRec swap; - - - if ( *count == 1 ) - return; - - /* sort */ - for ( i = 1; i < *count; i++ ) - { - for ( j = i; j > 0; j-- ) - { - if ( table[j].org >= table[j - 1].org ) - break; - - swap = table[j]; - table[j] = table[j - 1]; - table[j - 1] = swap; - } - } - - cur_idx = 0; - cur_val = table[cur_idx].org; - - /* compute and use mean values for clusters not larger than */ - /* `threshold'; this is very primitive and might not yield */ - /* the best result, but normally, using reference character */ - /* `o', `*count' is 2, so the code below is fully sufficient */ - for ( i = 1; i < *count; i++ ) - { - if ( table[i].org - cur_val > threshold || - i == *count - 1 ) - { - sum = 0; - - /* fix loop for end of array */ - if ( table[i].org - cur_val <= threshold && - i == *count - 1 ) - i++; - - for ( j = cur_idx; j < i; j++ ) - { - sum += table[j].org; - table[j].org = 0; - } - table[cur_idx].org = sum / (FT_Pos)j; - - if ( i < *count - 1 ) - { - cur_idx = i + 1; - cur_val = table[cur_idx].org; - } - } - } - - cur_idx = 1; - - /* compress array to remove zero values */ - for ( i = 1; i < *count; i++ ) - { - if ( table[i].org ) - table[cur_idx++] = table[i]; - } - - *count = cur_idx; - } - - -/* END */ diff --git a/thirdparty/freetype/src/autofit/afangles.h b/thirdparty/freetype/src/autofit/afangles.h deleted file mode 100644 index 18d7dae3a6..0000000000 --- a/thirdparty/freetype/src/autofit/afangles.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * afangles.h - * - * This is a dummy file, used to please the build system. It is never - * included by the auto-fitter sources. - * - */ diff --git a/thirdparty/freetype/src/autofit/afblue.c b/thirdparty/freetype/src/autofit/afblue.c index 9ebffdd099..c9e8045c18 100644 --- a/thirdparty/freetype/src/autofit/afblue.c +++ b/thirdparty/freetype/src/autofit/afblue.c @@ -7,7 +7,7 @@ * * Auto-fitter data for blue strings (body). * - * Copyright (C) 2013-2020 by + * Copyright (C) 2013-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/afblue.cin b/thirdparty/freetype/src/autofit/afblue.cin index c6a697fee0..071e80b031 100644 --- a/thirdparty/freetype/src/autofit/afblue.cin +++ b/thirdparty/freetype/src/autofit/afblue.cin @@ -4,7 +4,7 @@ * * Auto-fitter data for blue strings (body). * - * Copyright (C) 2013-2020 by + * Copyright (C) 2013-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/afblue.dat b/thirdparty/freetype/src/autofit/afblue.dat index b19b8df0f4..1aa9b26de9 100644 --- a/thirdparty/freetype/src/autofit/afblue.dat +++ b/thirdparty/freetype/src/autofit/afblue.dat @@ -2,7 +2,7 @@ // // Auto-fitter data for blue strings. // -// Copyright (C) 2013-2020 by +// Copyright (C) 2013-2021 by // David Turner, Robert Wilhelm, and Werner Lemberg. // // This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/afblue.h b/thirdparty/freetype/src/autofit/afblue.h index 486d663b6c..311c9e3afd 100644 --- a/thirdparty/freetype/src/autofit/afblue.h +++ b/thirdparty/freetype/src/autofit/afblue.h @@ -7,7 +7,7 @@ * * Auto-fitter data for blue strings (specification). * - * Copyright (C) 2013-2020 by + * Copyright (C) 2013-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/afblue.hin b/thirdparty/freetype/src/autofit/afblue.hin index 3957027091..5186914937 100644 --- a/thirdparty/freetype/src/autofit/afblue.hin +++ b/thirdparty/freetype/src/autofit/afblue.hin @@ -4,7 +4,7 @@ * * Auto-fitter data for blue strings (specification). * - * Copyright (C) 2013-2020 by + * Copyright (C) 2013-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/afcjk.c b/thirdparty/freetype/src/autofit/afcjk.c index 3b340cd5ed..7e46b6b1ef 100644 --- a/thirdparty/freetype/src/autofit/afcjk.c +++ b/thirdparty/freetype/src/autofit/afcjk.c @@ -4,7 +4,7 @@ * * Auto-fitter hinting routines for CJK writing system (body). * - * Copyright (C) 2006-2020 by + * Copyright (C) 2006-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -37,11 +37,6 @@ #include "aferrors.h" -#ifdef AF_CONFIG_OPTION_USE_WARPER -#include "afwarp.h" -#endif - - /************************************************************************** * * The macro FT_COMPONENT is used in trace mode. It is an implicit @@ -72,11 +67,11 @@ AF_GlyphHintsRec hints[1]; - FT_TRACE5(( "\n" - "cjk standard widths computation (style `%s')\n" - "===================================================\n" - "\n", + FT_TRACE5(( "\n" )); + FT_TRACE5(( "cjk standard widths computation (style `%s')\n", af_style_names[metrics->root.style_class->style] )); + FT_TRACE5(( "===================================================\n" )); + FT_TRACE5(( "\n" )); af_glyph_hints_init( hints, face->memory ); @@ -314,9 +309,9 @@ /* style's entry in the `af_blue_stringset' array, computing its */ /* extremum points (depending on the string properties) */ - FT_TRACE5(( "cjk blue zones computation\n" - "==========================\n" - "\n" )); + FT_TRACE5(( "cjk blue zones computation\n" )); + FT_TRACE5(( "==========================\n" )); + FT_TRACE5(( "\n" )); #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ shaper_buf = af_shaper_buf_create( face ); @@ -555,9 +550,8 @@ if ( AF_CJK_IS_TOP_BLUE( bs ) ) blue->flags |= AF_CJK_BLUE_TOP; - FT_TRACE5(( " -> reference = %ld\n" - " overshoot = %ld\n", - *blue_ref, *blue_shoot )); + FT_TRACE5(( " -> reference = %ld\n", *blue_ref )); + FT_TRACE5(( " overshoot = %ld\n", *blue_shoot )); } /* end for loop */ @@ -743,12 +737,12 @@ blue->shoot.fit = blue->ref.fit - delta2; - FT_TRACE5(( ">> active cjk blue zone %c%d[%ld/%ld]:\n" - " ref: cur=%.2f fit=%.2f\n" - " shoot: cur=%.2f fit=%.2f\n", + FT_TRACE5(( ">> active cjk blue zone %c%d[%ld/%ld]:\n", ( dim == AF_DIMENSION_HORZ ) ? 'H' : 'V', - nn, blue->ref.org, blue->shoot.org, - blue->ref.cur / 64.0, blue->ref.fit / 64.0, + nn, blue->ref.org, blue->shoot.org )); + FT_TRACE5(( " ref: cur=%.2f fit=%.2f\n", + blue->ref.cur / 64.0, blue->ref.fit / 64.0 )); + FT_TRACE5(( " shoot: cur=%.2f fit=%.2f\n", blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 )); blue->flags |= AF_CJK_BLUE_ACTIVE; @@ -1401,11 +1395,6 @@ /* compute flags depending on render mode, etc. */ mode = metrics->root.scaler.render_mode; -#if 0 /* AF_CONFIG_OPTION_USE_WARPER */ - if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) - metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; -#endif - scaler_flags = hints->scaler_flags; other_flags = 0; @@ -1434,12 +1423,6 @@ scaler_flags |= AF_SCALER_FLAG_NO_ADVANCE; -#ifdef AF_CONFIG_OPTION_USE_WARPER - /* get (global) warper flag */ - if ( !metrics->root.globals->module->warping ) - scaler_flags |= AF_SCALER_FLAG_NO_WARPER; -#endif - hints->scaler_flags = scaler_flags; hints->other_flags = other_flags; @@ -2322,25 +2305,6 @@ if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) { - -#ifdef AF_CONFIG_OPTION_USE_WARPER - if ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL && - AF_HINTS_DO_WARP( hints ) ) - { - AF_WarperRec warper; - FT_Fixed scale; - FT_Pos delta; - - - af_warper_compute( &warper, hints, (AF_Dimension)dim, - &scale, &delta ); - af_glyph_hints_scale_dim( hints, (AF_Dimension)dim, - scale, delta ); - continue; - } -#endif /* AF_CONFIG_OPTION_USE_WARPER */ - af_cjk_hint_edges( hints, (AF_Dimension)dim ); af_cjk_align_edge_points( hints, (AF_Dimension)dim ); af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim ); diff --git a/thirdparty/freetype/src/autofit/afcjk.h b/thirdparty/freetype/src/autofit/afcjk.h index fd0f451aa8..58aa298dad 100644 --- a/thirdparty/freetype/src/autofit/afcjk.h +++ b/thirdparty/freetype/src/autofit/afcjk.h @@ -4,7 +4,7 @@ * * Auto-fitter hinting routines for CJK writing system (specification). * - * Copyright (C) 2006-2020 by + * Copyright (C) 2006-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/afcover.h b/thirdparty/freetype/src/autofit/afcover.h index 03085ad07e..c7ae1e9a8a 100644 --- a/thirdparty/freetype/src/autofit/afcover.h +++ b/thirdparty/freetype/src/autofit/afcover.h @@ -4,7 +4,7 @@ * * Auto-fitter coverages (specification only). * - * Copyright (C) 2013-2020 by + * Copyright (C) 2013-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/afdummy.c b/thirdparty/freetype/src/autofit/afdummy.c index 77d31df974..a36b56f784 100644 --- a/thirdparty/freetype/src/autofit/afdummy.c +++ b/thirdparty/freetype/src/autofit/afdummy.c @@ -5,7 +5,7 @@ * Auto-fitter dummy routines to be used if no hinting should be * performed (body). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/afdummy.h b/thirdparty/freetype/src/autofit/afdummy.h index efd799e84b..b58849fe50 100644 --- a/thirdparty/freetype/src/autofit/afdummy.h +++ b/thirdparty/freetype/src/autofit/afdummy.h @@ -5,7 +5,7 @@ * Auto-fitter dummy routines to be used if no hinting should be * performed (specification). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/aferrors.h b/thirdparty/freetype/src/autofit/aferrors.h index f90899944b..09bed66395 100644 --- a/thirdparty/freetype/src/autofit/aferrors.h +++ b/thirdparty/freetype/src/autofit/aferrors.h @@ -4,7 +4,7 @@ * * Autofitter error codes (specification only). * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/afglobal.c b/thirdparty/freetype/src/autofit/afglobal.c index d5129423d5..b805b3b0e5 100644 --- a/thirdparty/freetype/src/autofit/afglobal.c +++ b/thirdparty/freetype/src/autofit/afglobal.c @@ -4,7 +4,7 @@ * * Auto-fitter routines to compute global hinting values (body). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -19,6 +19,7 @@ #include "afglobal.h" #include "afranges.h" #include "afshaper.h" +#include "afws-decl.h" #include <freetype/internal/ftdebug.h> @@ -32,11 +33,6 @@ #define FT_COMPONENT afglobal - /* get writing system specific header files */ -#undef WRITING_SYSTEM -#define WRITING_SYSTEM( ws, WS ) /* empty */ -#include "afwrtsys.h" - #include "aferrors.h" @@ -74,7 +70,7 @@ af_writing_system_classes[] = { -#include "afwrtsys.h" +#include "afws-iter.h" NULL /* do not remove */ }; @@ -285,10 +281,10 @@ #ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE4(( "\n" - "style coverage\n" - "==============\n" - "\n" )); + FT_TRACE4(( "\n" )); + FT_TRACE4(( "style coverage\n" )); + FT_TRACE4(( "==============\n" )); + FT_TRACE4(( "\n" )); for ( ss = 0; af_style_classes[ss]; ss++ ) { @@ -478,6 +474,10 @@ { style = (AF_Style)( globals->glyph_styles[gindex] & AF_STYLE_UNASSIGNED ); + /* IMPORTANT: Clear the error code, see + * https://gitlab.freedesktop.org/freetype/freetype/-/issues/1063 + */ + error = FT_Err_Ok; goto Again; } diff --git a/thirdparty/freetype/src/autofit/afglobal.h b/thirdparty/freetype/src/autofit/afglobal.h index fecf7af977..cd97e716c4 100644 --- a/thirdparty/freetype/src/autofit/afglobal.h +++ b/thirdparty/freetype/src/autofit/afglobal.h @@ -5,7 +5,7 @@ * Auto-fitter routines to compute global hinting values * (specification). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/afhints.c b/thirdparty/freetype/src/autofit/afhints.c index a8e00890ef..5506afda22 100644 --- a/thirdparty/freetype/src/autofit/afhints.c +++ b/thirdparty/freetype/src/autofit/afhints.c @@ -4,7 +4,7 @@ * * Auto-fitter hinting routines (body). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -32,6 +32,104 @@ #define FT_COMPONENT afhints + FT_LOCAL_DEF( void ) + af_sort_pos( FT_UInt count, + FT_Pos* table ) + { + FT_UInt i, j; + FT_Pos swap; + + + for ( i = 1; i < count; i++ ) + { + for ( j = i; j > 0; j-- ) + { + if ( table[j] >= table[j - 1] ) + break; + + swap = table[j]; + table[j] = table[j - 1]; + table[j - 1] = swap; + } + } + } + + + FT_LOCAL_DEF( void ) + af_sort_and_quantize_widths( FT_UInt* count, + AF_Width table, + FT_Pos threshold ) + { + FT_UInt i, j; + FT_UInt cur_idx; + FT_Pos cur_val; + FT_Pos sum; + AF_WidthRec swap; + + + if ( *count == 1 ) + return; + + /* sort */ + for ( i = 1; i < *count; i++ ) + { + for ( j = i; j > 0; j-- ) + { + if ( table[j].org >= table[j - 1].org ) + break; + + swap = table[j]; + table[j] = table[j - 1]; + table[j - 1] = swap; + } + } + + cur_idx = 0; + cur_val = table[cur_idx].org; + + /* compute and use mean values for clusters not larger than */ + /* `threshold'; this is very primitive and might not yield */ + /* the best result, but normally, using reference character */ + /* `o', `*count' is 2, so the code below is fully sufficient */ + for ( i = 1; i < *count; i++ ) + { + if ( table[i].org - cur_val > threshold || + i == *count - 1 ) + { + sum = 0; + + /* fix loop for end of array */ + if ( table[i].org - cur_val <= threshold && + i == *count - 1 ) + i++; + + for ( j = cur_idx; j < i; j++ ) + { + sum += table[j].org; + table[j].org = 0; + } + table[cur_idx].org = sum / (FT_Pos)j; + + if ( i < *count - 1 ) + { + cur_idx = i + 1; + cur_val = table[cur_idx].org; + } + } + } + + cur_idx = 1; + + /* compress array to remove zero values */ + for ( i = 1; i < *count; i++ ) + { + if ( table[i].org ) + table[cur_idx++] = table[i]; + } + + *count = cur_idx; + } + /* Get new segment for given axis. */ FT_LOCAL_DEF( FT_Error ) @@ -764,7 +862,7 @@ { FT_Error error = FT_Err_Ok; AF_Point points; - FT_UInt old_max, new_max; + FT_Int old_max, new_max; FT_Fixed x_scale = hints->x_scale; FT_Fixed y_scale = hints->y_scale; FT_Pos x_delta = hints->x_delta; @@ -781,8 +879,8 @@ hints->axis[1].num_edges = 0; /* first of all, reallocate the contours array if necessary */ - new_max = (FT_UInt)outline->n_contours; - old_max = (FT_UInt)hints->max_contours; + new_max = outline->n_contours; + old_max = hints->max_contours; if ( new_max <= AF_CONTOURS_EMBEDDED ) { @@ -797,12 +895,12 @@ if ( hints->contours == hints->embedded.contours ) hints->contours = NULL; - new_max = ( new_max + 3 ) & ~3U; /* round up to a multiple of 4 */ + new_max = ( new_max + 3 ) & ~3; /* round up to a multiple of 4 */ if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) goto Exit; - hints->max_contours = (FT_Int)new_max; + hints->max_contours = new_max; } /* @@ -810,8 +908,8 @@ * note that we reserve two additional point positions, used to * hint metrics appropriately */ - new_max = (FT_UInt)( outline->n_points + 2 ); - old_max = (FT_UInt)hints->max_points; + new_max = outline->n_points + 2; + old_max = hints->max_points; if ( new_max <= AF_POINTS_EMBEDDED ) { @@ -826,12 +924,12 @@ if ( hints->points == hints->embedded.points ) hints->points = NULL; - new_max = ( new_max + 2 + 7 ) & ~7U; /* round up to a multiple of 8 */ + new_max = ( new_max + 2 + 7 ) & ~7; /* round up to a multiple of 8 */ if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) ) goto Exit; - hints->max_points = (FT_Int)new_max; + hints->max_points = new_max; } hints->num_points = outline->n_points; @@ -855,9 +953,6 @@ hints->x_delta = x_delta; hints->y_delta = y_delta; - hints->xmin_delta = 0; - hints->xmax_delta = 0; - points = hints->points; if ( hints->num_points == 0 ) goto Exit; @@ -1688,33 +1783,4 @@ } -#ifdef AF_CONFIG_OPTION_USE_WARPER - - /* Apply (small) warp scale and warp delta for given dimension. */ - - FT_LOCAL_DEF( void ) - af_glyph_hints_scale_dim( AF_GlyphHints hints, - AF_Dimension dim, - FT_Fixed scale, - FT_Pos delta ) - { - AF_Point points = hints->points; - AF_Point points_limit = points + hints->num_points; - AF_Point point; - - - if ( dim == AF_DIMENSION_HORZ ) - { - for ( point = points; point < points_limit; point++ ) - point->x = FT_MulFix( point->fx, scale ) + delta; - } - else - { - for ( point = points; point < points_limit; point++ ) - point->y = FT_MulFix( point->fy, scale ) + delta; - } - } - -#endif /* AF_CONFIG_OPTION_USE_WARPER */ - /* END */ diff --git a/thirdparty/freetype/src/autofit/afhints.h b/thirdparty/freetype/src/autofit/afhints.h index 6397f098f0..38d2847d71 100644 --- a/thirdparty/freetype/src/autofit/afhints.h +++ b/thirdparty/freetype/src/autofit/afhints.h @@ -4,7 +4,7 @@ * * Auto-fitter hinting routines (specification). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -362,9 +362,6 @@ FT_BEGIN_HEADER /* implementations */ AF_StyleMetrics metrics; - FT_Pos xmin_delta; /* used for warping */ - FT_Pos xmax_delta; - /* Two arrays to avoid allocation penalty. */ /* The `embedded' structure must be the last element! */ struct @@ -408,10 +405,6 @@ FT_BEGIN_HEADER #define AF_HINTS_DO_ADVANCE( h ) \ !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE ) -#define AF_HINTS_DO_WARP( h ) \ - !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_WARPER ) - - FT_LOCAL( AF_Direction ) af_direction_compute( FT_Pos dx, @@ -459,14 +452,6 @@ FT_BEGIN_HEADER af_glyph_hints_align_weak_points( AF_GlyphHints hints, AF_Dimension dim ); -#ifdef AF_CONFIG_OPTION_USE_WARPER - FT_LOCAL( void ) - af_glyph_hints_scale_dim( AF_GlyphHints hints, - AF_Dimension dim, - FT_Fixed scale, - FT_Pos delta ); -#endif - FT_LOCAL( void ) af_glyph_hints_done( AF_GlyphHints hints ); diff --git a/thirdparty/freetype/src/autofit/afindic.c b/thirdparty/freetype/src/autofit/afindic.c index bc2837a26d..064c300ed7 100644 --- a/thirdparty/freetype/src/autofit/afindic.c +++ b/thirdparty/freetype/src/autofit/afindic.c @@ -4,7 +4,7 @@ * * Auto-fitter hinting routines for Indic writing system (body). * - * Copyright (C) 2007-2020 by + * Copyright (C) 2007-2021 by * Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. * * This file is part of the FreeType project, and may only be used, @@ -27,11 +27,6 @@ #include "aferrors.h" -#ifdef AF_CONFIG_OPTION_USE_WARPER -#include "afwarp.h" -#endif - - static FT_Error af_indic_metrics_init( AF_CJKMetrics metrics, FT_Face face ) diff --git a/thirdparty/freetype/src/autofit/afindic.h b/thirdparty/freetype/src/autofit/afindic.h index 088b88b19d..3e46724112 100644 --- a/thirdparty/freetype/src/autofit/afindic.h +++ b/thirdparty/freetype/src/autofit/afindic.h @@ -5,7 +5,7 @@ * Auto-fitter hinting routines for Indic writing system * (specification). * - * Copyright (C) 2007-2020 by + * Copyright (C) 2007-2021 by * Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/aflatin.c b/thirdparty/freetype/src/autofit/aflatin.c index 21ec02ebd2..5e81d771a4 100644 --- a/thirdparty/freetype/src/autofit/aflatin.c +++ b/thirdparty/freetype/src/autofit/aflatin.c @@ -4,7 +4,7 @@ * * Auto-fitter hinting routines for latin writing system (body). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -24,11 +24,6 @@ #include "aferrors.h" -#ifdef AF_CONFIG_OPTION_USE_WARPER -#include "afwarp.h" -#endif - - /************************************************************************** * * The macro FT_COMPONENT is used in trace mode. It is an implicit @@ -63,11 +58,11 @@ AF_GlyphHintsRec hints[1]; - FT_TRACE5(( "\n" - "latin standard widths computation (style `%s')\n" - "=====================================================\n" - "\n", + FT_TRACE5(( "\n" )); + FT_TRACE5(( "latin standard widths computation (style `%s')\n", af_style_names[metrics->root.style_class->style] )); + FT_TRACE5(( "=====================================================\n" )); + FT_TRACE5(( "\n" )); af_glyph_hints_init( hints, face->memory ); @@ -350,9 +345,9 @@ /* we walk over the blue character strings as specified in the */ /* style's entry in the `af_blue_stringset' array */ - FT_TRACE5(( "latin blue zones computation\n" - "============================\n" - "\n" )); + FT_TRACE5(( "latin blue zones computation\n" )); + FT_TRACE5(( "============================\n" )); + FT_TRACE5(( "\n" )); #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ shaper_buf = af_shaper_buf_create( face ); @@ -976,9 +971,8 @@ if ( AF_LATIN_IS_X_HEIGHT_BLUE( bs ) ) blue->flags |= AF_LATIN_BLUE_ADJUSTMENT; - FT_TRACE5(( " -> reference = %ld\n" - " overshoot = %ld\n", - *blue_ref, *blue_shoot )); + FT_TRACE5(( " -> reference = %ld\n", *blue_ref )); + FT_TRACE5(( " overshoot = %ld\n", *blue_shoot )); } /* end for loop */ @@ -1275,29 +1269,28 @@ if ( dist == 0 ) { - FT_TRACE5(( - "af_latin_metrics_scale_dim:" - " x height alignment (style `%s'):\n" - " " - " vertical scaling changed from %.5f to %.5f (by %ld%%)\n" - "\n", - af_style_names[metrics->root.style_class->style], - scale / 65536.0, - new_scale / 65536.0, - ( fitted - scaled ) * 100 / scaled )); + FT_TRACE5(( "af_latin_metrics_scale_dim:" + " x height alignment (style `%s'):\n", + af_style_names[metrics->root.style_class->style] )); + FT_TRACE5(( " " + " vertical scaling changed" + " from %.5f to %.5f (by %ld%%)\n", + scale / 65536.0, + new_scale / 65536.0, + ( fitted - scaled ) * 100 / scaled )); + FT_TRACE5(( "\n" )); scale = new_scale; } #ifdef FT_DEBUG_LEVEL_TRACE else { - FT_TRACE5(( - "af_latin_metrics_scale_dim:" - " x height alignment (style `%s'):\n" - " " - " excessive vertical scaling abandoned\n" - "\n", - af_style_names[metrics->root.style_class->style] )); + FT_TRACE5(( "af_latin_metrics_scale_dim:" + " x height alignment (style `%s'):\n", + af_style_names[metrics->root.style_class->style] )); + FT_TRACE5(( " " + " excessive vertical scaling abandoned\n" )); + FT_TRACE5(( "\n" )); } #endif } @@ -1346,9 +1339,11 @@ #ifdef FT_DEBUG_LEVEL_TRACE if ( axis->extra_light ) - FT_TRACE5(( "`%s' style is extra light (at current resolution)\n" - "\n", + { + FT_TRACE5(( "`%s' style is extra light (at current resolution)\n", af_style_names[metrics->root.style_class->style] )); + FT_TRACE5(( "\n" )); + } #endif if ( dim == AF_DIMENSION_VERT ) @@ -1473,13 +1468,13 @@ AF_LatinBlue blue = &axis->blues[nn]; - FT_TRACE5(( " reference %d: %ld scaled to %.2f%s\n" - " overshoot %d: %ld scaled to %.2f%s\n", + FT_TRACE5(( " reference %d: %ld scaled to %.2f%s\n", nn, blue->ref.org, blue->ref.fit / 64.0, ( blue->flags & AF_LATIN_BLUE_ACTIVE ) ? "" - : " (inactive)", + : " (inactive)" )); + FT_TRACE5(( " overshoot %d: %ld scaled to %.2f%s\n", nn, blue->shoot.org, blue->shoot.fit / 64.0, @@ -1847,6 +1842,31 @@ ( FT_ABS( point->out_dir ) == major_dir || point == point->prev ) ) { + /* + * For efficiency, we restrict the number of segments to 1000, + * which is a heuristic value: it is very unlikely that a glyph + * with so many segments can be hinted in a sensible way. + * Reasons: + * + * - The glyph has really 1000 segments; this implies that it has + * at least 2000 outline points. Assuming 'normal' fonts that + * have superfluous points optimized away, viewing such a glyph + * only makes sense at large magnifications where hinting + * isn't applied anyway. + * + * - We have a broken glyph. Hinting doesn't make sense in this + * case either. + */ + if ( axis->num_segments > 1000 ) + { + FT_TRACE0(( "af_latin_hints_compute_segments:" + " more than 1000 segments in this glyph;\n" )); + FT_TRACE0(( " " + " hinting is suppressed\n" )); + axis->num_segments = 0; + return FT_Err_Ok; + } + /* this is the start of a new segment! */ segment_dir = (AF_Direction)point->out_dir; @@ -2089,7 +2109,7 @@ { if ( seg2->link != seg1 ) { - seg1->link = 0; + seg1->link = NULL; seg1->serif = seg2->link; } } @@ -2611,11 +2631,6 @@ /* compute flags depending on render mode, etc. */ mode = metrics->root.scaler.render_mode; -#if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */ - if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) - metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; -#endif - scaler_flags = hints->scaler_flags; other_flags = 0; @@ -2653,12 +2668,6 @@ ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL; -#ifdef AF_CONFIG_OPTION_USE_WARPER - /* get (global) warper flag */ - if ( !metrics->root.globals->module->warping ) - scaler_flags |= AF_SCALER_FLAG_NO_WARPER; -#endif - hints->scaler_flags = scaler_flags; hints->other_flags = other_flags; @@ -3575,24 +3584,6 @@ /* grid-fit the outline */ for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { -#ifdef AF_CONFIG_OPTION_USE_WARPER - if ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL && - AF_HINTS_DO_WARP( hints ) ) - { - AF_WarperRec warper; - FT_Fixed scale; - FT_Pos delta; - - - af_warper_compute( &warper, hints, (AF_Dimension)dim, - &scale, &delta ); - af_glyph_hints_scale_dim( hints, (AF_Dimension)dim, - scale, delta ); - continue; - } -#endif /* AF_CONFIG_OPTION_USE_WARPER */ - if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) { diff --git a/thirdparty/freetype/src/autofit/aflatin.h b/thirdparty/freetype/src/autofit/aflatin.h index 62bc4c8d44..d6b919ef84 100644 --- a/thirdparty/freetype/src/autofit/aflatin.h +++ b/thirdparty/freetype/src/autofit/aflatin.h @@ -5,7 +5,7 @@ * Auto-fitter hinting routines for latin writing system * (specification). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/aflatin2.c b/thirdparty/freetype/src/autofit/aflatin2.c deleted file mode 100644 index 902f3982e0..0000000000 --- a/thirdparty/freetype/src/autofit/aflatin2.c +++ /dev/null @@ -1,2428 +0,0 @@ -/* ATTENTION: This file doesn't compile. It is only here as a reference */ -/* of an alternative latin hinting algorithm that was always */ -/* marked as experimental. */ - - -/**************************************************************************** - * - * aflatin2.c - * - * Auto-fitter hinting routines for latin writing system (body). - * - * Copyright (C) 2003-2020 by - * David Turner, Robert Wilhelm, and Werner Lemberg. - * - * This file is part of the FreeType project, and may only be used, - * modified, and distributed under the terms of the FreeType project - * license, LICENSE.TXT. By continuing to use, modify, or distribute - * this file you indicate that you have read the license and - * understand and accept it fully. - * - */ - - -#include <freetype/ftadvanc.h> - - -#ifdef FT_OPTION_AUTOFIT2 - -#include "afglobal.h" -#include "aflatin.h" -#include "aflatin2.h" -#include "aferrors.h" - - -#ifdef AF_CONFIG_OPTION_USE_WARPER -#include "afwarp.h" -#endif - - - /************************************************************************** - * - * The macro FT_COMPONENT is used in trace mode. It is an implicit - * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log - * messages during execution. - */ -#undef FT_COMPONENT -#define FT_COMPONENT aflatin2 - - - FT_LOCAL_DEF( FT_Error ) - af_latin2_hints_compute_segments( AF_GlyphHints hints, - AF_Dimension dim ); - - FT_LOCAL_DEF( void ) - af_latin2_hints_link_segments( AF_GlyphHints hints, - AF_Dimension dim ); - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** L A T I N G L O B A L M E T R I C S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_LOCAL_DEF( void ) - af_latin2_metrics_init_widths( AF_LatinMetrics metrics, - FT_Face face ) - { - /* scan the array of segments in each direction */ - AF_GlyphHintsRec hints[1]; - - - af_glyph_hints_init( hints, face->memory ); - - metrics->axis[AF_DIMENSION_HORZ].width_count = 0; - metrics->axis[AF_DIMENSION_VERT].width_count = 0; - - { - FT_Error error; - FT_UInt glyph_index; - int dim; - AF_LatinMetricsRec dummy[1]; - AF_Scaler scaler = &dummy->root.scaler; - - - glyph_index = FT_Get_Char_Index( - face, - metrics->root.style_class->standard_char ); - if ( glyph_index == 0 ) - goto Exit; - - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); - if ( error || face->glyph->outline.n_points <= 0 ) - goto Exit; - - FT_ZERO( dummy ); - - dummy->units_per_em = metrics->units_per_em; - scaler->x_scale = scaler->y_scale = 0x10000L; - scaler->x_delta = scaler->y_delta = 0; - scaler->face = face; - scaler->render_mode = FT_RENDER_MODE_NORMAL; - scaler->flags = 0; - - af_glyph_hints_rescale( hints, (AF_StyleMetrics)dummy ); - - error = af_glyph_hints_reload( hints, &face->glyph->outline ); - if ( error ) - goto Exit; - - for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) - { - AF_LatinAxis axis = &metrics->axis[dim]; - AF_AxisHints axhints = &hints->axis[dim]; - AF_Segment seg, limit, link; - FT_UInt num_widths = 0; - - - error = af_latin2_hints_compute_segments( hints, - (AF_Dimension)dim ); - if ( error ) - goto Exit; - - af_latin2_hints_link_segments( hints, - (AF_Dimension)dim ); - - seg = axhints->segments; - limit = seg + axhints->num_segments; - - for ( ; seg < limit; seg++ ) - { - link = seg->link; - - /* we only consider stem segments there! */ - if ( link && link->link == seg && link > seg ) - { - FT_Pos dist; - - - dist = seg->pos - link->pos; - if ( dist < 0 ) - dist = -dist; - - if ( num_widths < AF_LATIN_MAX_WIDTHS ) - axis->widths[num_widths++].org = dist; - } - } - - af_sort_widths( num_widths, axis->widths ); - axis->width_count = num_widths; - } - - Exit: - for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) - { - AF_LatinAxis axis = &metrics->axis[dim]; - FT_Pos stdw; - - - stdw = ( axis->width_count > 0 ) - ? axis->widths[0].org - : AF_LATIN_CONSTANT( metrics, 50 ); - - /* let's try 20% of the smallest width */ - axis->edge_distance_threshold = stdw / 5; - axis->standard_width = stdw; - axis->extra_light = 0; - } - } - - af_glyph_hints_done( hints ); - } - - - -#define AF_LATIN_MAX_TEST_CHARACTERS 12 - - - static const char af_latin2_blue_chars[AF_LATIN_MAX_BLUES] - [AF_LATIN_MAX_TEST_CHARACTERS+1] = - { - "THEZOCQS", - "HEZLOCUS", - "fijkdbh", - "xzroesc", - "xzroesc", - "pqgjy" - }; - - - static void - af_latin2_metrics_init_blues( AF_LatinMetrics metrics, - FT_Face face ) - { - FT_Pos flats [AF_LATIN_MAX_TEST_CHARACTERS]; - FT_Pos rounds[AF_LATIN_MAX_TEST_CHARACTERS]; - FT_Int num_flats; - FT_Int num_rounds; - FT_Int bb; - AF_LatinBlue blue; - FT_Error error; - AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT]; - FT_GlyphSlot glyph = face->glyph; - - - /* we compute the blues simply by loading each character from the */ - /* 'af_latin2_blue_chars[blues]' string, then compute its top-most or */ - /* bottom-most points (depending on `AF_IS_TOP_BLUE') */ - - FT_TRACE5(( "blue zones computation\n" - "======================\n\n" )); - - for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) - { - const char* p = af_latin2_blue_chars[bb]; - const char* limit = p + AF_LATIN_MAX_TEST_CHARACTERS; - FT_Pos* blue_ref; - FT_Pos* blue_shoot; - - - FT_TRACE5(( "blue zone %d:\n", bb )); - - num_flats = 0; - num_rounds = 0; - - for ( ; p < limit && *p; p++ ) - { - FT_UInt glyph_index; - FT_Int best_point, best_y, best_first, best_last; - FT_Vector* points; - FT_Bool round; - - - /* load the character in the face -- skip unknown or empty ones */ - glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p ); - if ( glyph_index == 0 ) - continue; - - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); - if ( error || glyph->outline.n_points <= 0 ) - continue; - - /* now compute min or max point indices and coordinates */ - points = glyph->outline.points; - best_point = -1; - best_y = 0; /* make compiler happy */ - best_first = 0; /* ditto */ - best_last = 0; /* ditto */ - - { - FT_Int nn; - FT_Int first = 0; - FT_Int last = -1; - - - for ( nn = 0; nn < glyph->outline.n_contours; first = last+1, nn++ ) - { - FT_Int old_best_point = best_point; - FT_Int pp; - - - last = glyph->outline.contours[nn]; - - /* Avoid single-point contours since they are never rasterized. */ - /* In some fonts, they correspond to mark attachment points */ - /* which are way outside of the glyph's real outline. */ - if ( last <= first ) - continue; - - if ( AF_LATIN_IS_TOP_BLUE( bb ) ) - { - for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y > best_y ) - { - best_point = pp; - best_y = points[pp].y; - } - } - else - { - for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y < best_y ) - { - best_point = pp; - best_y = points[pp].y; - } - } - - if ( best_point != old_best_point ) - { - best_first = first; - best_last = last; - } - } - FT_TRACE5(( " %c %d", *p, best_y )); - } - - /* now check whether the point belongs to a straight or round */ - /* segment; we first need to find in which contour the extremum */ - /* lies, then inspect its previous and next points */ - if ( best_point >= 0 ) - { - FT_Pos best_x = points[best_point].x; - FT_Int start, end, prev, next; - FT_Pos dist; - - - /* now look for the previous and next points that are not on the */ - /* same Y coordinate. Threshold the `closeness'... */ - start = end = best_point; - - do - { - prev = start - 1; - if ( prev < best_first ) - prev = best_last; - - dist = FT_ABS( points[prev].y - best_y ); - /* accept a small distance or a small angle (both values are */ - /* heuristic; value 20 corresponds to approx. 2.9 degrees) */ - if ( dist > 5 ) - if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist ) - break; - - start = prev; - - } while ( start != best_point ); - - do - { - next = end + 1; - if ( next > best_last ) - next = best_first; - - dist = FT_ABS( points[next].y - best_y ); - if ( dist > 5 ) - if ( FT_ABS( points[next].x - best_x ) <= 20 * dist ) - break; - - end = next; - - } while ( end != best_point ); - - /* now, set the `round' flag depending on the segment's kind */ - round = FT_BOOL( - FT_CURVE_TAG( glyph->outline.tags[start] ) != FT_CURVE_TAG_ON || - FT_CURVE_TAG( glyph->outline.tags[ end ] ) != FT_CURVE_TAG_ON ); - - FT_TRACE5(( " (%s)\n", round ? "round" : "flat" )); - } - - if ( round ) - rounds[num_rounds++] = best_y; - else - flats[num_flats++] = best_y; - } - - if ( num_flats == 0 && num_rounds == 0 ) - { - /* - * we couldn't find a single glyph to compute this blue zone, - * we will simply ignore it then - */ - FT_TRACE5(( " empty\n" )); - continue; - } - - /* we have computed the contents of the `rounds' and `flats' tables, */ - /* now determine the reference and overshoot position of the blue -- */ - /* we simply take the median value after a simple sort */ - af_sort_pos( num_rounds, rounds ); - af_sort_pos( num_flats, flats ); - - blue = & axis->blues[axis->blue_count]; - blue_ref = & blue->ref.org; - blue_shoot = & blue->shoot.org; - - axis->blue_count++; - - if ( num_flats == 0 ) - { - *blue_ref = - *blue_shoot = rounds[num_rounds / 2]; - } - else if ( num_rounds == 0 ) - { - *blue_ref = - *blue_shoot = flats[num_flats / 2]; - } - else - { - *blue_ref = flats[num_flats / 2]; - *blue_shoot = rounds[num_rounds / 2]; - } - - /* there are sometimes problems: if the overshoot position of top */ - /* zones is under its reference position, or the opposite for bottom */ - /* zones. We must thus check everything there and correct the errors */ - if ( *blue_shoot != *blue_ref ) - { - FT_Pos ref = *blue_ref; - FT_Pos shoot = *blue_shoot; - FT_Bool over_ref = FT_BOOL( shoot > ref ); - - - if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref ) - { - *blue_ref = - *blue_shoot = ( shoot + ref ) / 2; - - FT_TRACE5(( " [overshoot smaller than reference," - " taking mean value]\n" )); - } - } - - blue->flags = 0; - if ( AF_LATIN_IS_TOP_BLUE( bb ) ) - blue->flags |= AF_LATIN_BLUE_TOP; - - /* - * The following flag is used later to adjust the y and x scales - * in order to optimize the pixel grid alignment of the top of small - * letters. - */ - if ( AF_LATIN_IS_X_HEIGHT_BLUE( bb ) ) - blue->flags |= AF_LATIN_BLUE_ADJUSTMENT; - - FT_TRACE5(( " -> reference = %ld\n" - " overshoot = %ld\n", - *blue_ref, *blue_shoot )); - } - - return; - } - - - FT_LOCAL_DEF( void ) - af_latin2_metrics_check_digits( AF_LatinMetrics metrics, - FT_Face face ) - { - FT_UInt i; - FT_Bool started = 0, same_width = 1; - FT_Fixed advance, old_advance = 0; - - - /* check whether all ASCII digits have the same advance width; */ - /* digit `0' is 0x30 in all supported charmaps */ - for ( i = 0x30; i <= 0x39; i++ ) - { - FT_UInt glyph_index; - - - glyph_index = FT_Get_Char_Index( face, i ); - if ( glyph_index == 0 ) - continue; - - if ( FT_Get_Advance( face, glyph_index, - FT_LOAD_NO_SCALE | - FT_LOAD_NO_HINTING | - FT_LOAD_IGNORE_TRANSFORM, - &advance ) ) - continue; - - if ( started ) - { - if ( advance != old_advance ) - { - same_width = 0; - break; - } - } - else - { - old_advance = advance; - started = 1; - } - } - - metrics->root.digits_have_same_width = same_width; - } - - - FT_LOCAL_DEF( FT_Error ) - af_latin2_metrics_init( AF_LatinMetrics metrics, - FT_Face face ) - { - FT_Error error = FT_Err_Ok; - FT_CharMap oldmap = face->charmap; - FT_UInt ee; - - static const FT_Encoding latin_encodings[] = - { - FT_ENCODING_UNICODE, - FT_ENCODING_APPLE_ROMAN, - FT_ENCODING_ADOBE_STANDARD, - FT_ENCODING_ADOBE_LATIN_1, - FT_ENCODING_NONE /* end of list */ - }; - - - metrics->units_per_em = face->units_per_EM; - - /* do we have a latin charmap in there? */ - for ( ee = 0; latin_encodings[ee] != FT_ENCODING_NONE; ee++ ) - { - error = FT_Select_Charmap( face, latin_encodings[ee] ); - if ( !error ) - break; - } - - if ( !error ) - { - af_latin2_metrics_init_widths( metrics, face ); - af_latin2_metrics_init_blues( metrics, face ); - af_latin2_metrics_check_digits( metrics, face ); - } - - FT_Set_Charmap( face, oldmap ); - return FT_Err_Ok; - } - - - static void - af_latin2_metrics_scale_dim( AF_LatinMetrics metrics, - AF_Scaler scaler, - AF_Dimension dim ) - { - FT_Fixed scale; - FT_Pos delta; - AF_LatinAxis axis; - FT_UInt nn; - - - if ( dim == AF_DIMENSION_HORZ ) - { - scale = scaler->x_scale; - delta = scaler->x_delta; - } - else - { - scale = scaler->y_scale; - delta = scaler->y_delta; - } - - axis = &metrics->axis[dim]; - - if ( axis->org_scale == scale && axis->org_delta == delta ) - return; - - axis->org_scale = scale; - axis->org_delta = delta; - - /* - * correct Y scale to optimize the alignment of the top of small - * letters to the pixel grid - */ - if ( dim == AF_DIMENSION_VERT ) - { - AF_LatinAxis vaxis = &metrics->axis[AF_DIMENSION_VERT]; - AF_LatinBlue blue = NULL; - - - for ( nn = 0; nn < vaxis->blue_count; nn++ ) - { - if ( vaxis->blues[nn].flags & AF_LATIN_BLUE_ADJUSTMENT ) - { - blue = &vaxis->blues[nn]; - break; - } - } - - if ( blue ) - { - FT_Pos scaled; - FT_Pos threshold; - FT_Pos fitted; - FT_UInt limit; - FT_UInt ppem; - - - scaled = FT_MulFix( blue->shoot.org, scaler->y_scale ); - ppem = metrics->root.scaler.face->size->metrics.x_ppem; - limit = metrics->root.globals->increase_x_height; - threshold = 40; - - /* if the `increase-x-height' property is active, */ - /* we round up much more often */ - if ( limit && - ppem <= limit && - ppem >= AF_PROP_INCREASE_X_HEIGHT_MIN ) - threshold = 52; - - fitted = ( scaled + threshold ) & ~63; - -#if 1 - if ( scaled != fitted ) - { - scale = FT_MulDiv( scale, fitted, scaled ); - FT_TRACE5(( "== scaled x-top = %.2g" - " fitted = %.2g, scaling = %.4g\n", - scaled / 64.0, fitted / 64.0, - ( fitted * 1.0 ) / scaled )); - } -#endif - } - } - - axis->scale = scale; - axis->delta = delta; - - if ( dim == AF_DIMENSION_HORZ ) - { - metrics->root.scaler.x_scale = scale; - metrics->root.scaler.x_delta = delta; - } - else - { - metrics->root.scaler.y_scale = scale; - metrics->root.scaler.y_delta = delta; - } - - /* scale the standard widths */ - for ( nn = 0; nn < axis->width_count; nn++ ) - { - AF_Width width = axis->widths + nn; - - - width->cur = FT_MulFix( width->org, scale ); - width->fit = width->cur; - } - - /* an extra-light axis corresponds to a standard width that is */ - /* smaller than 5/8 pixels */ - axis->extra_light = - FT_BOOL( FT_MulFix( axis->standard_width, scale ) < 32 + 8 ); - - if ( dim == AF_DIMENSION_VERT ) - { - /* scale the blue zones */ - for ( nn = 0; nn < axis->blue_count; nn++ ) - { - AF_LatinBlue blue = &axis->blues[nn]; - FT_Pos dist; - - - blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta; - blue->ref.fit = blue->ref.cur; - blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta; - blue->shoot.fit = blue->shoot.cur; - blue->flags &= ~AF_LATIN_BLUE_ACTIVE; - - /* a blue zone is only active if it is less than 3/4 pixels tall */ - dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale ); - if ( dist <= 48 && dist >= -48 ) - { - FT_Pos delta1, delta2; - - delta1 = blue->shoot.org - blue->ref.org; - delta2 = delta1; - if ( delta1 < 0 ) - delta2 = -delta2; - - delta2 = FT_MulFix( delta2, scale ); - - if ( delta2 < 32 ) - delta2 = 0; - else if ( delta2 < 64 ) - delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 ); - else - delta2 = FT_PIX_ROUND( delta2 ); - - if ( delta1 < 0 ) - delta2 = -delta2; - - blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); - blue->shoot.fit = blue->ref.fit + delta2; - - FT_TRACE5(( ">> activating blue zone %d:" - " ref.cur=%.2g ref.fit=%.2g" - " shoot.cur=%.2g shoot.fit=%.2g\n", - nn, blue->ref.cur / 64.0, blue->ref.fit / 64.0, - blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 )); - - blue->flags |= AF_LATIN_BLUE_ACTIVE; - } - } - } - } - - - FT_LOCAL_DEF( void ) - af_latin2_metrics_scale( AF_LatinMetrics metrics, - AF_Scaler scaler ) - { - metrics->root.scaler.render_mode = scaler->render_mode; - metrics->root.scaler.face = scaler->face; - metrics->root.scaler.flags = scaler->flags; - - af_latin2_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); - af_latin2_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT ); - } - - - /* Extract standard_width from writing system/script specific */ - /* metrics class. */ - - FT_LOCAL_DEF( void ) - af_latin2_get_standard_widths( AF_LatinMetrics metrics, - FT_Pos* stdHW, - FT_Pos* stdVW ) - { - if ( stdHW ) - *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width; - - if ( stdVW ) - *stdVW = metrics->axis[AF_DIMENSION_HORZ].standard_width; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** L A T I N G L Y P H A N A L Y S I S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define SORT_SEGMENTS - - FT_LOCAL_DEF( FT_Error ) - af_latin2_hints_compute_segments( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - FT_Memory memory = hints->memory; - FT_Error error = FT_Err_Ok; - AF_Segment segment = NULL; - AF_SegmentRec seg0; - AF_Point* contour = hints->contours; - AF_Point* contour_limit = contour + hints->num_contours; - AF_Direction major_dir, segment_dir; - - - FT_ZERO( &seg0 ); - seg0.score = 32000; - seg0.flags = AF_EDGE_NORMAL; - - major_dir = (AF_Direction)FT_ABS( axis->major_dir ); - segment_dir = major_dir; - - axis->num_segments = 0; - - /* set up (u,v) in each point */ - if ( dim == AF_DIMENSION_HORZ ) - { - AF_Point point = hints->points; - AF_Point limit = point + hints->num_points; - - - for ( ; point < limit; point++ ) - { - point->u = point->fx; - point->v = point->fy; - } - } - else - { - AF_Point point = hints->points; - AF_Point limit = point + hints->num_points; - - - for ( ; point < limit; point++ ) - { - point->u = point->fy; - point->v = point->fx; - } - } - - /* do each contour separately */ - for ( ; contour < contour_limit; contour++ ) - { - AF_Point point = contour[0]; - AF_Point start = point; - AF_Point last = point->prev; - - - if ( point == last ) /* skip singletons -- just in case */ - continue; - - /* already on an edge ?, backtrack to find its start */ - if ( FT_ABS( point->in_dir ) == major_dir ) - { - point = point->prev; - - while ( point->in_dir == start->in_dir ) - point = point->prev; - } - else /* otherwise, find first segment start, if any */ - { - while ( FT_ABS( point->out_dir ) != major_dir ) - { - point = point->next; - - if ( point == start ) - goto NextContour; - } - } - - start = point; - - for (;;) - { - AF_Point first; - FT_Pos min_u, min_v, max_u, max_v; - - /* we're at the start of a new segment */ - FT_ASSERT( FT_ABS( point->out_dir ) == major_dir && - point->in_dir != point->out_dir ); - first = point; - - min_u = max_u = point->u; - min_v = max_v = point->v; - - point = point->next; - - while ( point->out_dir == first->out_dir ) - { - point = point->next; - - if ( point->u < min_u ) - min_u = point->u; - - if ( point->u > max_u ) - max_u = point->u; - } - - if ( point->v < min_v ) - min_v = point->v; - - if ( point->v > max_v ) - max_v = point->v; - - /* record new segment */ - error = af_axis_hints_new_segment( axis, memory, &segment ); - if ( error ) - goto Exit; - - segment[0] = seg0; - segment->dir = first->out_dir; - segment->first = first; - segment->last = point; - segment->pos = (FT_Short)( ( min_u + max_u ) >> 1 ); - segment->min_coord = (FT_Short) min_v; - segment->max_coord = (FT_Short) max_v; - segment->height = (FT_Short)( max_v - min_v ); - - /* a segment is round if it doesn't have successive */ - /* on-curve points. */ - { - AF_Point pt = first; - AF_Point last = point; - FT_UInt f0 = pt->flags & AF_FLAG_CONTROL; - FT_UInt f1; - - - segment->flags &= ~AF_EDGE_ROUND; - - for ( ; pt != last; f0 = f1 ) - { - pt = pt->next; - f1 = pt->flags & AF_FLAG_CONTROL; - - if ( !f0 && !f1 ) - break; - - if ( pt == last ) - segment->flags |= AF_EDGE_ROUND; - } - } - - /* this can happen in the case of a degenerate contour - * e.g. a 2-point vertical contour - */ - if ( point == start ) - break; - - /* jump to the start of the next segment, if any */ - while ( FT_ABS( point->out_dir ) != major_dir ) - { - point = point->next; - - if ( point == start ) - goto NextContour; - } - } - - NextContour: - ; - } /* contours */ - - /* now slightly increase the height of segments when this makes */ - /* sense -- this is used to better detect and ignore serifs */ - { - AF_Segment segments = axis->segments; - AF_Segment segments_end = segments + axis->num_segments; - - - for ( segment = segments; segment < segments_end; segment++ ) - { - AF_Point first = segment->first; - AF_Point last = segment->last; - AF_Point p; - FT_Pos first_v = first->v; - FT_Pos last_v = last->v; - - - if ( first_v < last_v ) - { - p = first->prev; - if ( p->v < first_v ) - segment->height = (FT_Short)( segment->height + - ( ( first_v - p->v ) >> 1 ) ); - - p = last->next; - if ( p->v > last_v ) - segment->height = (FT_Short)( segment->height + - ( ( p->v - last_v ) >> 1 ) ); - } - else - { - p = first->prev; - if ( p->v > first_v ) - segment->height = (FT_Short)( segment->height + - ( ( p->v - first_v ) >> 1 ) ); - - p = last->next; - if ( p->v < last_v ) - segment->height = (FT_Short)( segment->height + - ( ( last_v - p->v ) >> 1 ) ); - } - } - } - -#ifdef AF_SORT_SEGMENTS - /* place all segments with a negative direction to the start - * of the array, used to speed up segment linking later... - */ - { - AF_Segment segments = axis->segments; - FT_UInt count = axis->num_segments; - FT_UInt ii, jj; - - for ( ii = 0; ii < count; ii++ ) - { - if ( segments[ii].dir > 0 ) - { - for ( jj = ii + 1; jj < count; jj++ ) - { - if ( segments[jj].dir < 0 ) - { - AF_SegmentRec tmp; - - - tmp = segments[ii]; - segments[ii] = segments[jj]; - segments[jj] = tmp; - - break; - } - } - - if ( jj == count ) - break; - } - } - axis->mid_segments = ii; - } -#endif - - Exit: - return error; - } - - - FT_LOCAL_DEF( void ) - af_latin2_hints_link_segments( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - AF_Segment segments = axis->segments; - AF_Segment segment_limit = segments + axis->num_segments; -#ifdef AF_SORT_SEGMENTS - AF_Segment segment_mid = segments + axis->mid_segments; -#endif - FT_Pos len_threshold, len_score; - AF_Segment seg1, seg2; - - - len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 ); - if ( len_threshold == 0 ) - len_threshold = 1; - - len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 ); - -#ifdef AF_SORT_SEGMENTS - for ( seg1 = segments; seg1 < segment_mid; seg1++ ) - { - if ( seg1->dir != axis->major_dir ) - continue; - - for ( seg2 = segment_mid; seg2 < segment_limit; seg2++ ) -#else - /* now compare each segment to the others */ - for ( seg1 = segments; seg1 < segment_limit; seg1++ ) - { - if ( seg1->dir != axis->major_dir ) - continue; - - for ( seg2 = segments; seg2 < segment_limit; seg2++ ) - if ( seg1->dir + seg2->dir == 0 && seg2->pos > seg1->pos ) -#endif - { - FT_Pos pos1 = seg1->pos; - FT_Pos pos2 = seg2->pos; - FT_Pos dist = pos2 - pos1; - - - if ( dist < 0 ) - continue; - - { - FT_Pos min = seg1->min_coord; - FT_Pos max = seg1->max_coord; - FT_Pos len, score; - - - if ( min < seg2->min_coord ) - min = seg2->min_coord; - - if ( max > seg2->max_coord ) - max = seg2->max_coord; - - len = max - min; - if ( len >= len_threshold ) - { - score = dist + len_score / len; - if ( score < seg1->score ) - { - seg1->score = score; - seg1->link = seg2; - } - - if ( score < seg2->score ) - { - seg2->score = score; - seg2->link = seg1; - } - } - } - } - } -#if 0 - } -#endif - - /* now, compute the `serif' segments */ - for ( seg1 = segments; seg1 < segment_limit; seg1++ ) - { - seg2 = seg1->link; - - if ( seg2 ) - { - if ( seg2->link != seg1 ) - { - seg1->link = NULL; - seg1->serif = seg2->link; - } - } - } - } - - - FT_LOCAL_DEF( FT_Error ) - af_latin2_hints_compute_edges( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - FT_Error error = FT_Err_Ok; - FT_Memory memory = hints->memory; - AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim]; - - AF_Segment segments = axis->segments; - AF_Segment segment_limit = segments + axis->num_segments; - AF_Segment seg; - - AF_Direction up_dir; - FT_Fixed scale; - FT_Pos edge_distance_threshold; - FT_Pos segment_length_threshold; - - - axis->num_edges = 0; - - scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale - : hints->y_scale; - - up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP - : AF_DIR_RIGHT; - - /* - * We want to ignore very small (mostly serif) segments, we do that - * by ignoring those that whose length is less than a given fraction - * of the standard width. If there is no standard width, we ignore - * those that are less than a given size in pixels - * - * also, unlink serif segments that are linked to segments farther - * than 50% of the standard width - */ - if ( dim == AF_DIMENSION_HORZ ) - { - if ( laxis->width_count > 0 ) - segment_length_threshold = ( laxis->standard_width * 10 ) >> 4; - else - segment_length_threshold = FT_DivFix( 64, hints->y_scale ); - } - else - segment_length_threshold = 0; - - /********************************************************************** - * - * We will begin by generating a sorted table of edges for the - * current direction. To do so, we simply scan each segment and try - * to find an edge in our table that corresponds to its position. - * - * If no edge is found, we create and insert a new edge in the - * sorted table. Otherwise, we simply add the segment to the edge's - * list which will be processed in the second step to compute the - * edge's properties. - * - * Note that the edges table is sorted along the segment/edge - * position. - * - */ - - edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold, - scale ); - if ( edge_distance_threshold > 64 / 4 ) - edge_distance_threshold = 64 / 4; - - edge_distance_threshold = FT_DivFix( edge_distance_threshold, - scale ); - - for ( seg = segments; seg < segment_limit; seg++ ) - { - AF_Edge found = NULL; - FT_Int ee; - - - if ( seg->height < segment_length_threshold ) - continue; - - /* A special case for serif edges: If they are smaller than */ - /* 1.5 pixels we ignore them. */ - if ( seg->serif ) - { - FT_Pos dist = seg->serif->pos - seg->pos; - - - if ( dist < 0 ) - dist = -dist; - - if ( dist >= laxis->standard_width >> 1 ) - { - /* unlink this serif, it is too distant from its reference stem */ - seg->serif = NULL; - } - else if ( 2*seg->height < 3 * segment_length_threshold ) - continue; - } - - /* look for an edge corresponding to the segment */ - for ( ee = 0; ee < axis->num_edges; ee++ ) - { - AF_Edge edge = axis->edges + ee; - FT_Pos dist; - - - dist = seg->pos - edge->fpos; - if ( dist < 0 ) - dist = -dist; - - if ( dist < edge_distance_threshold && edge->dir == seg->dir ) - { - found = edge; - break; - } - } - - if ( !found ) - { - AF_Edge edge; - - - /* insert a new edge in the list and */ - /* sort according to the position */ - error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, 0, - memory, &edge ); - if ( error ) - goto Exit; - - /* add the segment to the new edge's list */ - FT_ZERO( edge ); - - edge->first = seg; - edge->last = seg; - edge->dir = seg->dir; - edge->fpos = seg->pos; - edge->opos = FT_MulFix( seg->pos, scale ); - edge->pos = edge->opos; - seg->edge_next = seg; - } - else - { - /* if an edge was found, simply add the segment to the edge's */ - /* list */ - seg->edge_next = found->first; - found->last->edge_next = seg; - found->last = seg; - } - } - - - /********************************************************************** - * - * Good, we will now compute each edge's properties according to - * segments found on its position. Basically, these are: - * - * - edge's main direction - * - stem edge, serif edge or both (which defaults to stem then) - * - rounded edge, straight or both (which defaults to straight) - * - link for edge - * - */ - - /* first of all, set the `edge' field in each segment -- this is */ - /* required in order to compute edge links */ - - /* - * Note that removing this loop and setting the `edge' field of each - * segment directly in the code above slows down execution speed for - * some reasons on platforms like the Sun. - */ - { - AF_Edge edges = axis->edges; - AF_Edge edge_limit = edges + axis->num_edges; - AF_Edge edge; - - - for ( edge = edges; edge < edge_limit; edge++ ) - { - seg = edge->first; - if ( seg ) - do - { - seg->edge = edge; - seg = seg->edge_next; - - } while ( seg != edge->first ); - } - - /* now, compute each edge properties */ - for ( edge = edges; edge < edge_limit; edge++ ) - { - FT_Int is_round = 0; /* does it contain round segments? */ - FT_Int is_straight = 0; /* does it contain straight segments? */ -#if 0 - FT_Pos ups = 0; /* number of upwards segments */ - FT_Pos downs = 0; /* number of downwards segments */ -#endif - - - seg = edge->first; - - do - { - FT_Bool is_serif; - - - /* check for roundness of segment */ - if ( seg->flags & AF_EDGE_ROUND ) - is_round++; - else - is_straight++; - -#if 0 - /* check for segment direction */ - if ( seg->dir == up_dir ) - ups += seg->max_coord-seg->min_coord; - else - downs += seg->max_coord-seg->min_coord; -#endif - - /* check for links -- if seg->serif is set, then seg->link must */ - /* be ignored */ - is_serif = FT_BOOL( seg->serif && - seg->serif->edge && - seg->serif->edge != edge ); - - if ( ( seg->link && seg->link->edge ) || is_serif ) - { - AF_Edge edge2; - AF_Segment seg2; - - - edge2 = edge->link; - seg2 = seg->link; - - if ( is_serif ) - { - seg2 = seg->serif; - edge2 = edge->serif; - } - - if ( edge2 ) - { - FT_Pos edge_delta; - FT_Pos seg_delta; - - - edge_delta = edge->fpos - edge2->fpos; - if ( edge_delta < 0 ) - edge_delta = -edge_delta; - - seg_delta = seg->pos - seg2->pos; - if ( seg_delta < 0 ) - seg_delta = -seg_delta; - - if ( seg_delta < edge_delta ) - edge2 = seg2->edge; - } - else - edge2 = seg2->edge; - - if ( is_serif ) - { - edge->serif = edge2; - edge2->flags |= AF_EDGE_SERIF; - } - else - edge->link = edge2; - } - - seg = seg->edge_next; - - } while ( seg != edge->first ); - - /* set the round/straight flags */ - edge->flags = AF_EDGE_NORMAL; - - if ( is_round > 0 && is_round >= is_straight ) - edge->flags |= AF_EDGE_ROUND; - -#if 0 - /* set the edge's main direction */ - edge->dir = AF_DIR_NONE; - - if ( ups > downs ) - edge->dir = (FT_Char)up_dir; - - else if ( ups < downs ) - edge->dir = (FT_Char)-up_dir; - - else if ( ups == downs ) - edge->dir = 0; /* both up and down! */ -#endif - - /* gets rid of serifs if link is set */ - /* XXX: This gets rid of many unpleasant artefacts! */ - /* Example: the `c' in cour.pfa at size 13 */ - - if ( edge->serif && edge->link ) - edge->serif = NULL; - } - } - - Exit: - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - af_latin2_hints_detect_features( AF_GlyphHints hints, - AF_Dimension dim ) - { - FT_Error error; - - - error = af_latin2_hints_compute_segments( hints, dim ); - if ( !error ) - { - af_latin2_hints_link_segments( hints, dim ); - - error = af_latin2_hints_compute_edges( hints, dim ); - } - return error; - } - - - static void - af_latin2_hints_compute_blue_edges( AF_GlyphHints hints, - AF_LatinMetrics metrics ) - { - AF_AxisHints axis = &hints->axis[AF_DIMENSION_VERT]; - AF_Edge edge = axis->edges; - AF_Edge edge_limit = edge + axis->num_edges; - AF_LatinAxis latin = &metrics->axis[AF_DIMENSION_VERT]; - FT_Fixed scale = latin->scale; - FT_Pos best_dist0; /* initial threshold */ - - - /* compute the initial threshold as a fraction of the EM size */ - best_dist0 = FT_MulFix( metrics->units_per_em / 40, scale ); - - if ( best_dist0 > 64 / 2 ) - best_dist0 = 64 / 2; - - /* compute which blue zones are active, i.e. have their scaled */ - /* size < 3/4 pixels */ - - /* for each horizontal edge search the blue zone which is closest */ - for ( ; edge < edge_limit; edge++ ) - { - FT_Int bb; - AF_Width best_blue = NULL; - FT_Pos best_dist = best_dist0; - - for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) - { - AF_LatinBlue blue = latin->blues + bb; - FT_Bool is_top_blue, is_major_dir; - - - /* skip inactive blue zones (i.e., those that are too small) */ - if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) ) - continue; - - /* if it is a top zone, check for right edges -- if it is a bottom */ - /* zone, check for left edges */ - /* */ - /* of course, that's for TrueType */ - is_top_blue = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 ); - is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); - - /* if it is a top zone, the edge must be against the major */ - /* direction; if it is a bottom zone, it must be in the major */ - /* direction */ - if ( is_top_blue ^ is_major_dir ) - { - FT_Pos dist; - AF_Width compare; - - - /* if it's a rounded edge, compare it to the overshoot position */ - /* if it's a flat edge, compare it to the reference position */ - if ( edge->flags & AF_EDGE_ROUND ) - compare = &blue->shoot; - else - compare = &blue->ref; - - dist = edge->fpos - compare->org; - if ( dist < 0 ) - dist = -dist; - - dist = FT_MulFix( dist, scale ); - if ( dist < best_dist ) - { - best_dist = dist; - best_blue = compare; - } - -#if 0 - /* now, compare it to the overshoot position if the edge is */ - /* rounded, and if the edge is over the reference position of a */ - /* top zone, or under the reference position of a bottom zone */ - if ( edge->flags & AF_EDGE_ROUND && dist != 0 ) - { - FT_Bool is_under_ref = FT_BOOL( edge->fpos < blue->ref.org ); - - - if ( is_top_blue ^ is_under_ref ) - { - blue = latin->blues + bb; - dist = edge->fpos - blue->shoot.org; - if ( dist < 0 ) - dist = -dist; - - dist = FT_MulFix( dist, scale ); - if ( dist < best_dist ) - { - best_dist = dist; - best_blue = & blue->shoot; - } - } - } -#endif - } - } - - if ( best_blue ) - edge->blue_edge = best_blue; - } - } - - - static FT_Error - af_latin2_hints_init( AF_GlyphHints hints, - AF_LatinMetrics metrics ) - { - FT_Render_Mode mode; - FT_UInt32 scaler_flags, other_flags; - FT_Face face = metrics->root.scaler.face; - - - af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics ); - - /* - * correct x_scale and y_scale if needed, since they may have - * been modified `af_latin2_metrics_scale_dim' above - */ - hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale; - hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta; - hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale; - hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta; - - /* compute flags depending on render mode, etc. */ - mode = metrics->root.scaler.render_mode; - -#if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */ - if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) - metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; -#endif - - scaler_flags = hints->scaler_flags; - other_flags = 0; - - /* - * We snap the width of vertical stems for the monochrome and - * horizontal LCD rendering targets only. - */ - if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) - other_flags |= AF_LATIN_HINTS_HORZ_SNAP; - - /* - * We snap the width of horizontal stems for the monochrome and - * vertical LCD rendering targets only. - */ - if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) - other_flags |= AF_LATIN_HINTS_VERT_SNAP; - - /* - * We adjust stems to full pixels unless in `light' or `lcd' mode. - */ - if ( mode != FT_RENDER_MODE_LIGHT && mode != FT_RENDER_MODE_LCD ) - other_flags |= AF_LATIN_HINTS_STEM_ADJUST; - - if ( mode == FT_RENDER_MODE_MONO ) - other_flags |= AF_LATIN_HINTS_MONO; - - /* - * In `light' or `lcd' mode we disable horizontal hinting completely. - * We also do it if the face is italic. - */ - if ( mode == FT_RENDER_MODE_LIGHT || mode == FT_RENDER_MODE_LCD || - ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) - scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL; - -#ifdef AF_CONFIG_OPTION_USE_WARPER - /* get (global) warper flag */ - if ( !metrics->root.globals->module->warping ) - scaler_flags |= AF_SCALER_FLAG_NO_WARPER; -#endif - - hints->scaler_flags = scaler_flags; - hints->other_flags = other_flags; - - return 0; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** L A T I N G L Y P H G R I D - F I T T I N G *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* snap a given width in scaled coordinates to one of the */ - /* current standard widths */ - - static FT_Pos - af_latin2_snap_width( AF_Width widths, - FT_UInt count, - FT_Pos width ) - { - FT_UInt n; - FT_Pos best = 64 + 32 + 2; - FT_Pos reference = width; - FT_Pos scaled; - - - for ( n = 0; n < count; n++ ) - { - FT_Pos w; - FT_Pos dist; - - - w = widths[n].cur; - dist = width - w; - if ( dist < 0 ) - dist = -dist; - if ( dist < best ) - { - best = dist; - reference = w; - } - } - - scaled = FT_PIX_ROUND( reference ); - - if ( width >= reference ) - { - if ( width < scaled + 48 ) - width = reference; - } - else - { - if ( width > scaled - 48 ) - width = reference; - } - - return width; - } - - - /* compute the snapped width of a given stem */ - - static FT_Pos - af_latin2_compute_stem_width( AF_GlyphHints hints, - AF_Dimension dim, - FT_Pos width, - FT_UInt base_flags, - FT_UInt stem_flags ) - { - AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; - AF_LatinAxis axis = & metrics->axis[dim]; - FT_Pos dist = width; - FT_Int sign = 0; - FT_Int vertical = ( dim == AF_DIMENSION_VERT ); - - FT_UNUSED( base_flags ); - - - if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) || - axis->extra_light ) - return width; - - if ( dist < 0 ) - { - dist = -width; - sign = 1; - } - - if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || - ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) - { - /* smooth hinting process: very lightly quantize the stem width */ - - /* leave the widths of serifs alone */ - - if ( ( stem_flags & AF_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) ) - goto Done_Width; - -#if 0 - else if ( ( base_flags & AF_EDGE_ROUND ) ) - { - if ( dist < 80 ) - dist = 64; - } - else if ( dist < 56 ) - dist = 56; -#endif - if ( axis->width_count > 0 ) - { - FT_Pos delta; - - - /* compare to standard width */ - if ( axis->width_count > 0 ) - { - delta = dist - axis->widths[0].cur; - - if ( delta < 0 ) - delta = -delta; - - if ( delta < 40 ) - { - dist = axis->widths[0].cur; - if ( dist < 48 ) - dist = 48; - - goto Done_Width; - } - } - - if ( dist < 3 * 64 ) - { - delta = dist & 63; - dist &= -64; - - if ( delta < 10 ) - dist += delta; - - else if ( delta < 32 ) - dist += 10; - - else if ( delta < 54 ) - dist += 54; - - else - dist += delta; - } - else - dist = ( dist + 32 ) & ~63; - } - } - else - { - /* strong hinting process: snap the stem width to integer pixels */ - FT_Pos org_dist = dist; - - - dist = af_latin2_snap_width( axis->widths, axis->width_count, dist ); - - if ( vertical ) - { - /* in the case of vertical hinting, always round */ - /* the stem heights to integer pixels */ - - if ( dist >= 64 ) - dist = ( dist + 16 ) & ~63; - else - dist = 64; - } - else - { - if ( AF_LATIN_HINTS_DO_MONO( hints ) ) - { - /* monochrome horizontal hinting: snap widths to integer pixels */ - /* with a different threshold */ - - if ( dist < 64 ) - dist = 64; - else - dist = ( dist + 32 ) & ~63; - } - else - { - /* for horizontal anti-aliased hinting, we adopt a more subtle */ - /* approach: we strengthen small stems, round stems whose size */ - /* is between 1 and 2 pixels to an integer, otherwise nothing */ - - if ( dist < 48 ) - dist = ( dist + 64 ) >> 1; - - else if ( dist < 128 ) - { - /* We only round to an integer width if the corresponding */ - /* distortion is less than 1/4 pixel. Otherwise this */ - /* makes everything worse since the diagonals, which are */ - /* not hinted, appear a lot bolder or thinner than the */ - /* vertical stems. */ - - FT_Int delta; - - - dist = ( dist + 22 ) & ~63; - delta = dist - org_dist; - if ( delta < 0 ) - delta = -delta; - - if ( delta >= 16 ) - { - dist = org_dist; - if ( dist < 48 ) - dist = ( dist + 64 ) >> 1; - } - } - else - /* round otherwise to prevent color fringes in LCD mode */ - dist = ( dist + 32 ) & ~63; - } - } - } - - Done_Width: - if ( sign ) - dist = -dist; - - return dist; - } - - - /* align one stem edge relative to the previous stem edge */ - - static void - af_latin2_align_linked_edge( AF_GlyphHints hints, - AF_Dimension dim, - AF_Edge base_edge, - AF_Edge stem_edge ) - { - FT_Pos dist = stem_edge->opos - base_edge->opos; - - FT_Pos fitted_width = af_latin2_compute_stem_width( hints, dim, dist, - base_edge->flags, - stem_edge->flags ); - - - stem_edge->pos = base_edge->pos + fitted_width; - - FT_TRACE5(( "LINK: edge %d (opos=%.2f) linked to (%.2f), " - "dist was %.2f, now %.2f\n", - stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0, - stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 )); - } - - - static void - af_latin2_align_serif_edge( AF_GlyphHints hints, - AF_Edge base, - AF_Edge serif ) - { - FT_UNUSED( hints ); - - serif->pos = base->pos + ( serif->opos - base->opos ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** E D G E H I N T I N G ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static void - af_latin2_hint_edges( AF_GlyphHints hints, - AF_Dimension dim ) - { - AF_AxisHints axis = &hints->axis[dim]; - AF_Edge edges = axis->edges; - AF_Edge edge_limit = edges + axis->num_edges; - AF_Edge edge; - AF_Edge anchor = NULL; - FT_Int has_serifs = 0; - FT_Pos anchor_drift = 0; - - - - FT_TRACE5(( "==== hinting %s edges =====\n", - dim == AF_DIMENSION_HORZ ? "vertical" : "horizontal" )); - - /* we begin by aligning all stems relative to the blue zone */ - /* if needed -- that's only for horizontal edges */ - - if ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_BLUES( hints ) ) - { - for ( edge = edges; edge < edge_limit; edge++ ) - { - AF_Width blue; - AF_Edge edge1, edge2; - - - if ( edge->flags & AF_EDGE_DONE ) - continue; - - blue = edge->blue_edge; - edge1 = NULL; - edge2 = edge->link; - - if ( blue ) - { - edge1 = edge; - } - else if ( edge2 && edge2->blue_edge ) - { - blue = edge2->blue_edge; - edge1 = edge2; - edge2 = edge; - } - - if ( !edge1 ) - continue; - - FT_TRACE5(( "BLUE: edge %d (opos=%.2f) snapped to (%.2f), " - "was (%.2f)\n", - edge1-edges, edge1->opos / 64.0, blue->fit / 64.0, - edge1->pos / 64.0 )); - - edge1->pos = blue->fit; - edge1->flags |= AF_EDGE_DONE; - - if ( edge2 && !edge2->blue_edge ) - { - af_latin2_align_linked_edge( hints, dim, edge1, edge2 ); - edge2->flags |= AF_EDGE_DONE; - } - - if ( !anchor ) - { - anchor = edge; - - anchor_drift = ( anchor->pos - anchor->opos ); - if ( edge2 ) - anchor_drift = ( anchor_drift + - ( edge2->pos - edge2->opos ) ) >> 1; - } - } - } - - /* now we will align all stem edges, trying to maintain the */ - /* relative order of stems in the glyph */ - for ( edge = edges; edge < edge_limit; edge++ ) - { - AF_Edge edge2; - - - if ( edge->flags & AF_EDGE_DONE ) - continue; - - /* skip all non-stem edges */ - edge2 = edge->link; - if ( !edge2 ) - { - has_serifs++; - continue; - } - - /* now align the stem */ - - /* this should not happen, but it's better to be safe */ - if ( edge2->blue_edge ) - { - FT_TRACE5(( "ASSERTION FAILED for edge %d\n", edge2-edges )); - - af_latin2_align_linked_edge( hints, dim, edge2, edge ); - edge->flags |= AF_EDGE_DONE; - continue; - } - - if ( !anchor ) - { - FT_Pos org_len, org_center, cur_len; - FT_Pos cur_pos1, error1, error2, u_off, d_off; - - - org_len = edge2->opos - edge->opos; - cur_len = af_latin2_compute_stem_width( hints, dim, org_len, - edge->flags, - edge2->flags ); - if ( cur_len <= 64 ) - u_off = d_off = 32; - else - { - u_off = 38; - d_off = 26; - } - - if ( cur_len < 96 ) - { - org_center = edge->opos + ( org_len >> 1 ); - - cur_pos1 = FT_PIX_ROUND( org_center ); - - error1 = org_center - ( cur_pos1 - u_off ); - if ( error1 < 0 ) - error1 = -error1; - - error2 = org_center - ( cur_pos1 + d_off ); - if ( error2 < 0 ) - error2 = -error2; - - if ( error1 < error2 ) - cur_pos1 -= u_off; - else - cur_pos1 += d_off; - - edge->pos = cur_pos1 - cur_len / 2; - edge2->pos = edge->pos + cur_len; - } - else - edge->pos = FT_PIX_ROUND( edge->opos ); - - FT_TRACE5(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f)" - " snapped to (%.2f) (%.2f)\n", - edge-edges, edge->opos / 64.0, - edge2-edges, edge2->opos / 64.0, - edge->pos / 64.0, edge2->pos / 64.0 )); - anchor = edge; - - edge->flags |= AF_EDGE_DONE; - - af_latin2_align_linked_edge( hints, dim, edge, edge2 ); - - edge2->flags |= AF_EDGE_DONE; - - anchor_drift = ( ( anchor->pos - anchor->opos ) + - ( edge2->pos - edge2->opos ) ) >> 1; - - FT_TRACE5(( "DRIFT: %.2f\n", anchor_drift/64.0 )); - } - else - { - FT_Pos org_pos, org_len, org_center, cur_center, cur_len; - FT_Pos org_left, org_right; - - - org_pos = edge->opos + anchor_drift; - org_len = edge2->opos - edge->opos; - org_center = org_pos + ( org_len >> 1 ); - - cur_len = af_latin2_compute_stem_width( hints, dim, org_len, - edge->flags, - edge2->flags ); - - org_left = org_pos + ( ( org_len - cur_len ) >> 1 ); - org_right = org_pos + ( ( org_len + cur_len ) >> 1 ); - - FT_TRACE5(( "ALIGN: left=%.2f right=%.2f ", - org_left / 64.0, org_right / 64.0 )); - cur_center = org_center; - - if ( edge2->flags & AF_EDGE_DONE ) - { - FT_TRACE5(( "\n" )); - edge->pos = edge2->pos - cur_len; - } - else - { - /* we want to compare several displacement, and choose - * the one that increases fitness while minimizing - * distortion as well - */ - FT_Pos displacements[6], scores[6], org, fit, delta; - FT_UInt count = 0; - - /* note: don't even try to fit tiny stems */ - if ( cur_len < 32 ) - { - FT_TRACE5(( "tiny stem\n" )); - goto AlignStem; - } - - /* if the span is within a single pixel, don't touch it */ - if ( FT_PIX_FLOOR( org_left ) == FT_PIX_CEIL( org_right ) ) - { - FT_TRACE5(( "single pixel stem\n" )); - goto AlignStem; - } - - if ( cur_len <= 96 ) - { - /* we want to avoid the absolute worst case which is - * when the left and right edges of the span each represent - * about 50% of the gray. we'd better want to change this - * to 25/75%, since this is much more pleasant to the eye with - * very acceptable distortion - */ - FT_Pos frac_left = org_left & 63; - FT_Pos frac_right = org_right & 63; - - if ( frac_left >= 22 && frac_left <= 42 && - frac_right >= 22 && frac_right <= 42 ) - { - org = frac_left; - fit = ( org <= 32 ) ? 16 : 48; - delta = FT_ABS( fit - org ); - displacements[count] = fit - org; - scores[count++] = delta; - FT_TRACE5(( "dispA=%.2f (%d) ", ( fit - org ) / 64.0, delta )); - - org = frac_right; - fit = ( org <= 32 ) ? 16 : 48; - delta = FT_ABS( fit - org ); - displacements[count] = fit - org; - scores[count++] = delta; - FT_TRACE5(( "dispB=%.2f (%d) ", ( fit - org ) / 64.0, delta )); - } - } - - /* snapping the left edge to the grid */ - org = org_left; - fit = FT_PIX_ROUND( org ); - delta = FT_ABS( fit - org ); - displacements[count] = fit - org; - scores[count++] = delta; - FT_TRACE5(( "dispC=%.2f (%d) ", ( fit - org ) / 64.0, delta )); - - /* snapping the right edge to the grid */ - org = org_right; - fit = FT_PIX_ROUND( org ); - delta = FT_ABS( fit - org ); - displacements[count] = fit - org; - scores[count++] = delta; - FT_TRACE5(( "dispD=%.2f (%d) ", ( fit - org ) / 64.0, delta )); - - /* now find the best displacement */ - { - FT_Pos best_score = scores[0]; - FT_Pos best_disp = displacements[0]; - FT_UInt nn; - - for ( nn = 1; nn < count; nn++ ) - { - if ( scores[nn] < best_score ) - { - best_score = scores[nn]; - best_disp = displacements[nn]; - } - } - - cur_center = org_center + best_disp; - } - FT_TRACE5(( "\n" )); - } - - AlignStem: - edge->pos = cur_center - ( cur_len >> 1 ); - edge2->pos = edge->pos + cur_len; - - FT_TRACE5(( "STEM1: %d (opos=%.2f) to %d (opos=%.2f)" - " snapped to (%.2f) and (%.2f)," - " org_len=%.2f cur_len=%.2f\n", - edge-edges, edge->opos / 64.0, - edge2-edges, edge2->opos / 64.0, - edge->pos / 64.0, edge2->pos / 64.0, - org_len / 64.0, cur_len / 64.0 )); - - edge->flags |= AF_EDGE_DONE; - edge2->flags |= AF_EDGE_DONE; - - if ( edge > edges && edge->pos < edge[-1].pos ) - { - FT_TRACE5(( "BOUND: %d (pos=%.2f) to (%.2f)\n", - edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); - edge->pos = edge[-1].pos; - } - } - } - - /* make sure that lowercase m's maintain their symmetry */ - - /* In general, lowercase m's have six vertical edges if they are sans */ - /* serif, or twelve if they are with serifs. This implementation is */ - /* based on that assumption, and seems to work very well with most */ - /* faces. However, if for a certain face this assumption is not */ - /* true, the m is just rendered like before. In addition, any stem */ - /* correction will only be applied to symmetrical glyphs (even if the */ - /* glyph is not an m), so the potential for unwanted distortion is */ - /* relatively low. */ - - /* We don't handle horizontal edges since we can't easily assure that */ - /* the third (lowest) stem aligns with the base line; it might end up */ - /* one pixel higher or lower. */ - -#if 0 - { - FT_Int n_edges = edge_limit - edges; - - - if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) - { - AF_Edge edge1, edge2, edge3; - FT_Pos dist1, dist2, span, delta; - - - if ( n_edges == 6 ) - { - edge1 = edges; - edge2 = edges + 2; - edge3 = edges + 4; - } - else - { - edge1 = edges + 1; - edge2 = edges + 5; - edge3 = edges + 9; - } - - dist1 = edge2->opos - edge1->opos; - dist2 = edge3->opos - edge2->opos; - - span = dist1 - dist2; - if ( span < 0 ) - span = -span; - - if ( span < 8 ) - { - delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); - edge3->pos -= delta; - if ( edge3->link ) - edge3->link->pos -= delta; - - /* move the serifs along with the stem */ - if ( n_edges == 12 ) - { - ( edges + 8 )->pos -= delta; - ( edges + 11 )->pos -= delta; - } - - edge3->flags |= AF_EDGE_DONE; - if ( edge3->link ) - edge3->link->flags |= AF_EDGE_DONE; - } - } - } -#endif - - if ( has_serifs || !anchor ) - { - /* - * now hint the remaining edges (serifs and single) in order - * to complete our processing - */ - for ( edge = edges; edge < edge_limit; edge++ ) - { - FT_Pos delta; - - - if ( edge->flags & AF_EDGE_DONE ) - continue; - - delta = 1000; - - if ( edge->serif ) - { - delta = edge->serif->opos - edge->opos; - if ( delta < 0 ) - delta = -delta; - } - - if ( delta < 64 + 16 ) - { - af_latin2_align_serif_edge( hints, edge->serif, edge ); - FT_TRACE5(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f)" - " aligned to (%.2f)\n", - edge-edges, edge->opos / 64.0, - edge->serif - edges, edge->serif->opos / 64.0, - edge->pos / 64.0 )); - } - else if ( !anchor ) - { - FT_TRACE5(( "SERIF_ANCHOR: edge %d (opos=%.2f)" - " snapped to (%.2f)\n", - edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); - edge->pos = FT_PIX_ROUND( edge->opos ); - anchor = edge; - } - else - { - AF_Edge before, after; - - - for ( before = edge - 1; before >= edges; before-- ) - if ( before->flags & AF_EDGE_DONE ) - break; - - for ( after = edge + 1; after < edge_limit; after++ ) - if ( after->flags & AF_EDGE_DONE ) - break; - - if ( before >= edges && before < edge && - after < edge_limit && after > edge ) - { - if ( after->opos == before->opos ) - edge->pos = before->pos; - else - edge->pos = before->pos + - FT_MulDiv( edge->opos - before->opos, - after->pos - before->pos, - after->opos - before->opos ); - FT_TRACE5(( "SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f)" - " from %d (opos=%.2f)\n", - edge-edges, edge->opos / 64.0, edge->pos / 64.0, - before - edges, before->opos / 64.0 )); - } - else - { - edge->pos = anchor->pos + - ( ( edge->opos - anchor->opos + 16 ) & ~31 ); - - FT_TRACE5(( "SERIF_LINK2: edge %d (opos=%.2f)" - " snapped to (%.2f)\n", - edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); - } - } - - edge->flags |= AF_EDGE_DONE; - - if ( edge > edges && edge->pos < edge[-1].pos ) - edge->pos = edge[-1].pos; - - if ( edge + 1 < edge_limit && - edge[1].flags & AF_EDGE_DONE && - edge->pos > edge[1].pos ) - edge->pos = edge[1].pos; - } - } - } - - - static FT_Error - af_latin2_hints_apply( FT_UInt glyph_index, - AF_GlyphHints hints, - FT_Outline* outline, - AF_LatinMetrics metrics ) - { - FT_Error error; - int dim; - - FT_UNUSED( glyph_index ); - - - error = af_glyph_hints_reload( hints, outline ); - if ( error ) - goto Exit; - - /* analyze glyph outline */ - if ( AF_HINTS_DO_HORIZONTAL( hints ) ) - { - error = af_latin2_hints_detect_features( hints, AF_DIMENSION_HORZ ); - if ( error ) - goto Exit; - } - - if ( AF_HINTS_DO_VERTICAL( hints ) ) - { - error = af_latin2_hints_detect_features( hints, AF_DIMENSION_VERT ); - if ( error ) - goto Exit; - - af_latin2_hints_compute_blue_edges( hints, metrics ); - } - - /* grid-fit the outline */ - for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) - { -#ifdef AF_CONFIG_OPTION_USE_WARPER - if ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL && - AF_HINTS_DO_WARP( hints ) ) - { - AF_WarperRec warper; - FT_Fixed scale; - FT_Pos delta; - - - af_warper_compute( &warper, hints, dim, &scale, &delta ); - af_glyph_hints_scale_dim( hints, dim, scale, delta ); - continue; - } -#endif /* AF_CONFIG_OPTION_USE_WARPER */ - - if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || - ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) - { - af_latin2_hint_edges( hints, (AF_Dimension)dim ); - af_glyph_hints_align_edge_points( hints, (AF_Dimension)dim ); - af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim ); - af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim ); - } - } - af_glyph_hints_save( hints, outline ); - - Exit: - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** L A T I N S C R I P T C L A S S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - AF_DEFINE_WRITING_SYSTEM_CLASS( - af_latin2_writing_system_class, - - AF_WRITING_SYSTEM_LATIN2, - - sizeof ( AF_LatinMetricsRec ), - - (AF_WritingSystem_InitMetricsFunc) af_latin2_metrics_init, /* style_metrics_init */ - (AF_WritingSystem_ScaleMetricsFunc)af_latin2_metrics_scale, /* style_metrics_scale */ - (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ - (AF_WritingSystem_GetStdWidthsFunc)af_latin2_get_standard_widths, /* style_metrics_getstdw */ - - (AF_WritingSystem_InitHintsFunc) af_latin2_hints_init, /* style_hints_init */ - (AF_WritingSystem_ApplyHintsFunc) af_latin2_hints_apply /* style_hints_apply */ - ) - -#else /* !FT_OPTION_AUTOFIT2 */ - - /* ANSI C doesn't like empty source files */ - typedef int _af_latin2_dummy; - -#endif /* !FT_OPTION_AUTOFIT2 */ - - -/* END */ diff --git a/thirdparty/freetype/src/autofit/aflatin2.h b/thirdparty/freetype/src/autofit/aflatin2.h deleted file mode 100644 index c2aebc49ac..0000000000 --- a/thirdparty/freetype/src/autofit/aflatin2.h +++ /dev/null @@ -1,46 +0,0 @@ -/* ATTENTION: This file doesn't compile. It is only here as a reference */ -/* of an alternative latin hinting algorithm that was always */ -/* marked as experimental. */ - - -/**************************************************************************** - * - * aflatin2.h - * - * Auto-fitter hinting routines for latin writing system - * (specification). - * - * Copyright (C) 2003-2020 by - * David Turner, Robert Wilhelm, and Werner Lemberg. - * - * This file is part of the FreeType project, and may only be used, - * modified, and distributed under the terms of the FreeType project - * license, LICENSE.TXT. By continuing to use, modify, or distribute - * this file you indicate that you have read the license and - * understand and accept it fully. - * - */ - - -#ifndef AFLATIN2_H_ -#define AFLATIN2_H_ - -#include "afhints.h" - - -FT_BEGIN_HEADER - - - /* the `latin' writing system */ - - AF_DECLARE_WRITING_SYSTEM_CLASS( af_latin2_writing_system_class ) - - -/* */ - -FT_END_HEADER - -#endif /* AFLATIN_H_ */ - - -/* END */ diff --git a/thirdparty/freetype/src/autofit/afloader.c b/thirdparty/freetype/src/autofit/afloader.c index c35d85c4cf..a06d49ad7e 100644 --- a/thirdparty/freetype/src/autofit/afloader.c +++ b/thirdparty/freetype/src/autofit/afloader.c @@ -4,7 +4,7 @@ * * Auto-fitter glyph loading routines (body). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -105,7 +105,6 @@ globals->stem_darkening_for_ppem; FT_Fixed em_size = af_intToFixed( face->units_per_EM ); - FT_Fixed em_ratio = FT_DivFix( af_intToFixed( 1000 ), em_size ); FT_Matrix scale_down_matrix = { 0x10000L, 0, 0, 0x10000L }; @@ -142,12 +141,11 @@ darken_by_font_units_x = - af_intToFixed( af_loader_compute_darkening( loader, - face, - stdVW ) ); - darken_x = FT_DivFix( FT_MulFix( darken_by_font_units_x, - size_metrics->x_scale ), - em_ratio ); + af_loader_compute_darkening( loader, + face, + stdVW ) ; + darken_x = FT_MulFix( darken_by_font_units_x, + size_metrics->x_scale ); globals->standard_vertical_width = stdVW; globals->stem_darkening_for_ppem = size_metrics->x_ppem; @@ -161,12 +159,11 @@ darken_by_font_units_y = - af_intToFixed( af_loader_compute_darkening( loader, - face, - stdHW ) ); - darken_y = FT_DivFix( FT_MulFix( darken_by_font_units_y, - size_metrics->y_scale ), - em_ratio ); + af_loader_compute_darkening( loader, + face, + stdHW ) ; + darken_y = FT_MulFix( darken_by_font_units_y, + size_metrics->y_scale ); globals->standard_horizontal_width = stdHW; globals->stem_darkening_for_ppem = size_metrics->x_ppem; @@ -300,12 +297,6 @@ if ( error ) goto Exit; -#ifdef FT_OPTION_AUTOFIT2 - /* XXX: undocumented hook to activate the latin2 writing system. */ - if ( load_flags & ( 1UL << 20 ) ) - style_options = AF_STYLE_LTN2_DFLT; -#endif - /* * Glyphs (really code points) are assigned to scripts. Script * analysis is done lazily: For each glyph that passes through here, @@ -482,8 +473,8 @@ FT_Pos pp2x = loader->pp2.x; - loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta ); - loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta ); + loader->pp1.x = FT_PIX_ROUND( pp1x ); + loader->pp2.x = FT_PIX_ROUND( pp2x ); slot->lsb_delta = loader->pp1.x - pp1x; slot->rsb_delta = loader->pp2.x - pp2x; @@ -594,7 +585,7 @@ * * XXX: Currently a crude adaption of the original algorithm. Do better? */ - FT_LOCAL_DEF( FT_Int32 ) + FT_LOCAL_DEF( FT_Fixed ) af_loader_compute_darkening( AF_Loader loader, FT_Face face, FT_Pos standard_width ) @@ -713,7 +704,7 @@ } /* Convert darken_amount from per 1000 em to true character space. */ - return af_fixedToInt( FT_DivFix( darken_amount, em_ratio ) ); + return FT_DivFix( darken_amount, em_ratio ); } diff --git a/thirdparty/freetype/src/autofit/afloader.h b/thirdparty/freetype/src/autofit/afloader.h index 97282371cd..b4936a8722 100644 --- a/thirdparty/freetype/src/autofit/afloader.h +++ b/thirdparty/freetype/src/autofit/afloader.h @@ -4,7 +4,7 @@ * * Auto-fitter glyph loading routines (specification). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -75,7 +75,7 @@ FT_BEGIN_HEADER FT_UInt gindex, FT_Int32 load_flags ); - FT_LOCAL_DEF( FT_Int32 ) + FT_LOCAL_DEF( FT_Fixed ) af_loader_compute_darkening( AF_Loader loader, FT_Face face, FT_Pos standard_width ); diff --git a/thirdparty/freetype/src/autofit/afmodule.c b/thirdparty/freetype/src/autofit/afmodule.c index e16494460e..76f9b3733b 100644 --- a/thirdparty/freetype/src/autofit/afmodule.c +++ b/thirdparty/freetype/src/autofit/afmodule.c @@ -4,7 +4,7 @@ * * Auto-fitter module implementation (body). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -48,7 +48,7 @@ int _af_debug_disable_blue_hints; /* we use a global object instead of a local one for debugging */ - AF_GlyphHintsRec _af_debug_hints_rec[1]; + static AF_GlyphHintsRec _af_debug_hints_rec[1]; void* _af_debug_hints = _af_debug_hints_rec; #endif @@ -148,7 +148,7 @@ if ( !af_style_classes[ss] ) { - FT_TRACE0(( "af_property_set: Invalid value %d for property `%s'\n", + FT_TRACE2(( "af_property_set: Invalid value %d for property `%s'\n", *fallback_script, property_name )); return FT_THROW( Invalid_Argument ); } @@ -190,35 +190,6 @@ return error; } -#ifdef AF_CONFIG_OPTION_USE_WARPER - else if ( !ft_strcmp( property_name, "warping" ) ) - { -#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES - if ( value_is_string ) - { - const char* s = (const char*)value; - long w = ft_strtol( s, NULL, 10 ); - - - if ( w == 0 ) - module->warping = 0; - else if ( w == 1 ) - module->warping = 1; - else - return FT_THROW( Invalid_Argument ); - } - else -#endif - { - FT_Bool* warping = (FT_Bool*)value; - - - module->warping = *warping; - } - - return error; - } -#endif /* AF_CONFIG_OPTION_USE_WARPER */ else if ( !ft_strcmp( property_name, "darkening-parameters" ) ) { FT_Int* darken_params; @@ -307,7 +278,7 @@ return error; } - FT_TRACE0(( "af_property_set: missing property `%s'\n", + FT_TRACE2(( "af_property_set: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); } @@ -322,9 +293,6 @@ AF_Module module = (AF_Module)ft_module; FT_UInt fallback_style = module->fallback_style; FT_UInt default_script = module->default_script; -#ifdef AF_CONFIG_OPTION_USE_WARPER - FT_Bool warping = module->warping; -#endif if ( !ft_strcmp( property_name, "glyph-to-script-map" ) ) @@ -371,17 +339,6 @@ return error; } -#ifdef AF_CONFIG_OPTION_USE_WARPER - else if ( !ft_strcmp( property_name, "warping" ) ) - { - FT_Bool* val = (FT_Bool*)value; - - - *val = warping; - - return error; - } -#endif /* AF_CONFIG_OPTION_USE_WARPER */ else if ( !ft_strcmp( property_name, "darkening-parameters" ) ) { FT_Int* darken_params = module->darken_params; @@ -410,7 +367,7 @@ return error; } - FT_TRACE0(( "af_property_get: missing property `%s'\n", + FT_TRACE2(( "af_property_get: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); } @@ -447,9 +404,6 @@ module->fallback_style = AF_STYLE_FALLBACK; module->default_script = AF_SCRIPT_DEFAULT; -#ifdef AF_CONFIG_OPTION_USE_WARPER - module->warping = 0; -#endif module->no_stem_darkening = TRUE; module->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; diff --git a/thirdparty/freetype/src/autofit/afmodule.h b/thirdparty/freetype/src/autofit/afmodule.h index e8fe4a93aa..c5bd468201 100644 --- a/thirdparty/freetype/src/autofit/afmodule.h +++ b/thirdparty/freetype/src/autofit/afmodule.h @@ -4,7 +4,7 @@ * * Auto-fitter module implementation (specification). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -37,9 +37,6 @@ FT_BEGIN_HEADER FT_UInt fallback_style; FT_UInt default_script; -#ifdef AF_CONFIG_OPTION_USE_WARPER - FT_Bool warping; -#endif FT_Bool no_stem_darkening; FT_Int darken_params[8]; diff --git a/thirdparty/freetype/src/autofit/afranges.c b/thirdparty/freetype/src/autofit/afranges.c index c8ebf5e784..e06f182dd0 100644 --- a/thirdparty/freetype/src/autofit/afranges.c +++ b/thirdparty/freetype/src/autofit/afranges.c @@ -4,7 +4,7 @@ * * Auto-fitter Unicode script ranges (body). * - * Copyright (C) 2013-2020 by + * Copyright (C) 2013-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/afranges.h b/thirdparty/freetype/src/autofit/afranges.h index c2ffda4b0f..841d630aab 100644 --- a/thirdparty/freetype/src/autofit/afranges.h +++ b/thirdparty/freetype/src/autofit/afranges.h @@ -4,7 +4,7 @@ * * Auto-fitter Unicode script ranges (specification). * - * Copyright (C) 2013-2020 by + * Copyright (C) 2013-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/afscript.h b/thirdparty/freetype/src/autofit/afscript.h index 4cf9cc19f5..af78d573e1 100644 --- a/thirdparty/freetype/src/autofit/afscript.h +++ b/thirdparty/freetype/src/autofit/afscript.h @@ -4,7 +4,7 @@ * * Auto-fitter scripts (specification only). * - * Copyright (C) 2013-2020 by + * Copyright (C) 2013-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/afshaper.c b/thirdparty/freetype/src/autofit/afshaper.c index bbf7b6b1f9..5d078937e1 100644 --- a/thirdparty/freetype/src/autofit/afshaper.c +++ b/thirdparty/freetype/src/autofit/afshaper.c @@ -4,7 +4,7 @@ * * HarfBuzz interface for accessing OpenType features (body). * - * Copyright (C) 2013-2020 by + * Copyright (C) 2013-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -132,13 +132,24 @@ /* Convert a HarfBuzz script tag into the corresponding OpenType */ /* tag or tags -- some Indic scripts like Devanagari have an old */ /* and a new set of features. */ - hb_ot_tags_from_script( script, - &script_tags[0], - &script_tags[1] ); + { + unsigned int tags_count = 3; + hb_tag_t tags[3]; + + + hb_ot_tags_from_script_and_language( script, + HB_LANGUAGE_INVALID, + &tags_count, + tags, + NULL, + NULL ); + script_tags[0] = tags_count > 0 ? tags[0] : HB_TAG_NONE; + script_tags[1] = tags_count > 1 ? tags[1] : HB_TAG_NONE; + script_tags[2] = tags_count > 2 ? tags[2] : HB_TAG_NONE; + } - /* `hb_ot_tags_from_script' usually returns HB_OT_TAG_DEFAULT_SCRIPT */ - /* as the second tag. We change that to HB_TAG_NONE except for the */ - /* default script. */ + /* If the second tag is HB_OT_TAG_DEFAULT_SCRIPT, change that to */ + /* HB_TAG_NONE except for the default script. */ if ( default_script ) { if ( script_tags[0] == HB_TAG_NONE ) @@ -157,9 +168,6 @@ /* HarfBuzz maps them to `DFLT', which we don't want to handle here */ if ( script_tags[0] == HB_OT_TAG_DEFAULT_SCRIPT ) goto Exit; - - if ( script_tags[1] == HB_OT_TAG_DEFAULT_SCRIPT ) - script_tags[1] = HB_TAG_NONE; } gsub_lookups = hb_set_create(); @@ -173,9 +181,9 @@ if ( hb_set_is_empty( gsub_lookups ) ) goto Exit; /* nothing to do */ - FT_TRACE4(( "GSUB lookups (style `%s'):\n" - " ", + FT_TRACE4(( "GSUB lookups (style `%s'):\n", af_style_names[style_class->style] )); + FT_TRACE4(( " " )); #ifdef FT_DEBUG_LEVEL_TRACE count = 0; @@ -202,12 +210,13 @@ #ifdef FT_DEBUG_LEVEL_TRACE if ( !count ) FT_TRACE4(( " (none)" )); - FT_TRACE4(( "\n\n" )); + FT_TRACE4(( "\n" )); + FT_TRACE4(( "\n" )); #endif - FT_TRACE4(( "GPOS lookups (style `%s'):\n" - " ", + FT_TRACE4(( "GPOS lookups (style `%s'):\n", af_style_names[style_class->style] )); + FT_TRACE4(( " " )); gpos_lookups = hb_set_create(); hb_ot_layout_collect_lookups( face, @@ -242,7 +251,8 @@ #ifdef FT_DEBUG_LEVEL_TRACE if ( !count ) FT_TRACE4(( " (none)" )); - FT_TRACE4(( "\n\n" )); + FT_TRACE4(( "\n" )); + FT_TRACE4(( "\n" )); #endif /* @@ -353,8 +363,10 @@ { #ifdef FT_DEBUG_LEVEL_TRACE if ( !( count % 10 ) ) - FT_TRACE4(( "\n" - " " )); + { + FT_TRACE4(( "\n" )); + FT_TRACE4(( " " )); + } FT_TRACE4(( " %d", idx )); count++; @@ -376,9 +388,12 @@ #ifdef FT_DEBUG_LEVEL_TRACE if ( !count ) - FT_TRACE4(( "\n" - " (none)" )); - FT_TRACE4(( "\n\n" )); + { + FT_TRACE4(( "\n" )); + FT_TRACE4(( " (none)" )); + } + FT_TRACE4(( "\n" )); + FT_TRACE4(( "\n" )); #endif Exit: diff --git a/thirdparty/freetype/src/autofit/afshaper.h b/thirdparty/freetype/src/autofit/afshaper.h index 138c27b32b..cf3f81342f 100644 --- a/thirdparty/freetype/src/autofit/afshaper.h +++ b/thirdparty/freetype/src/autofit/afshaper.h @@ -4,7 +4,7 @@ * * HarfBuzz interface for accessing OpenType features (specification). * - * Copyright (C) 2013-2020 by + * Copyright (C) 2013-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/autofit/afstyles.h b/thirdparty/freetype/src/autofit/afstyles.h index 9113ec451e..64c808c581 100644 --- a/thirdparty/freetype/src/autofit/afstyles.h +++ b/thirdparty/freetype/src/autofit/afstyles.h @@ -4,7 +4,7 @@ * * Auto-fitter styles (specification only). * - * Copyright (C) 2013-2020 by + * Copyright (C) 2013-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -299,15 +299,6 @@ AF_BLUE_STRINGSET_LATP, AF_COVERAGE_DEFAULT ) -#ifdef FT_OPTION_AUTOFIT2 - STYLE( ltn2_dflt, LTN2_DFLT, - "Latin 2 default style", - AF_WRITING_SYSTEM_LATIN2, - AF_SCRIPT_LATN, - AF_BLUE_STRINGSET_LATN, - AF_COVERAGE_DEFAULT ) -#endif - STYLE( lisu_dflt, LISU_DFLT, "Lisu default style", AF_WRITING_SYSTEM_LATIN, diff --git a/thirdparty/freetype/src/autofit/aftypes.h b/thirdparty/freetype/src/autofit/aftypes.h index 5f040c6b4b..1d792b9476 100644 --- a/thirdparty/freetype/src/autofit/aftypes.h +++ b/thirdparty/freetype/src/autofit/aftypes.h @@ -4,7 +4,7 @@ * * Auto-fitter types (specification only). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -92,63 +92,6 @@ extern void* _af_debug_hints; FT_Pos threshold ); - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** A N G L E T Y P E S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* - * The auto-fitter doesn't need a very high angular accuracy; - * this allows us to speed up some computations considerably with a - * light Cordic algorithm (see afangles.c). - */ - - typedef FT_Int AF_Angle; - - -#define AF_ANGLE_PI 256 -#define AF_ANGLE_2PI ( AF_ANGLE_PI * 2 ) -#define AF_ANGLE_PI2 ( AF_ANGLE_PI / 2 ) -#define AF_ANGLE_PI4 ( AF_ANGLE_PI / 4 ) - - -#if 0 - /* - * compute the angle of a given 2-D vector - */ - FT_LOCAL( AF_Angle ) - af_angle_atan( FT_Pos dx, - FT_Pos dy ); - - - /* - * compute `angle2 - angle1'; the result is always within - * the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1] - */ - FT_LOCAL( AF_Angle ) - af_angle_diff( AF_Angle angle1, - AF_Angle angle2 ); -#endif /* 0 */ - - -#define AF_ANGLE_DIFF( result, angle1, angle2 ) \ - FT_BEGIN_STMNT \ - AF_Angle _delta = (angle2) - (angle1); \ - \ - \ - while ( _delta <= -AF_ANGLE_PI ) \ - _delta += AF_ANGLE_2PI; \ - \ - while ( _delta > AF_ANGLE_PI ) \ - _delta -= AF_ANGLE_2PI; \ - \ - result = _delta; \ - FT_END_STMNT - - /* * opaque handle to glyph-specific hints -- see `afhints.h' for more * details @@ -172,7 +115,6 @@ extern void* _af_debug_hints; #define AF_SCALER_FLAG_NO_HORIZONTAL 1U /* disable horizontal hinting */ #define AF_SCALER_FLAG_NO_VERTICAL 2U /* disable vertical hinting */ #define AF_SCALER_FLAG_NO_ADVANCE 4U /* disable advance hinting */ -#define AF_SCALER_FLAG_NO_WARPER 8U /* disable warper */ typedef struct AF_ScalerRec_ @@ -256,7 +198,6 @@ extern void* _af_debug_hints; * outline according to the results of the glyph analyzer. */ -#define AFWRTSYS_H_ /* don't load header files */ #undef WRITING_SYSTEM #define WRITING_SYSTEM( ws, WS ) \ AF_WRITING_SYSTEM_ ## WS, @@ -265,14 +206,12 @@ extern void* _af_debug_hints; typedef enum AF_WritingSystem_ { -#include "afwrtsys.h" +#include "afws-iter.h" AF_WRITING_SYSTEM_MAX /* do not remove */ } AF_WritingSystem; -#undef AFWRTSYS_H_ - typedef struct AF_WritingSystemClassRec_ { diff --git a/thirdparty/freetype/src/autofit/afwarp.c b/thirdparty/freetype/src/autofit/afwarp.c deleted file mode 100644 index 808280df5d..0000000000 --- a/thirdparty/freetype/src/autofit/afwarp.c +++ /dev/null @@ -1,373 +0,0 @@ -/**************************************************************************** - * - * afwarp.c - * - * Auto-fitter warping algorithm (body). - * - * Copyright (C) 2006-2020 by - * David Turner, Robert Wilhelm, and Werner Lemberg. - * - * This file is part of the FreeType project, and may only be used, - * modified, and distributed under the terms of the FreeType project - * license, LICENSE.TXT. By continuing to use, modify, or distribute - * this file you indicate that you have read the license and - * understand and accept it fully. - * - */ - - - /* - * The idea of the warping code is to slightly scale and shift a glyph - * within a single dimension so that as much of its segments are aligned - * (more or less) on the grid. To find out the optimal scaling and - * shifting value, various parameter combinations are tried and scored. - */ - -#include "afwarp.h" - -#ifdef AF_CONFIG_OPTION_USE_WARPER - - /************************************************************************** - * - * The macro FT_COMPONENT is used in trace mode. It is an implicit - * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log - * messages during execution. - */ -#undef FT_COMPONENT -#define FT_COMPONENT afwarp - - - /* The weights cover the range 0/64 - 63/64 of a pixel. Obviously, */ - /* values around a half pixel (which means exactly between two grid */ - /* lines) gets the worst weight. */ -#if 1 - static const AF_WarpScore - af_warper_weights[64] = - { - 35, 32, 30, 25, 20, 15, 12, 10, 5, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -1, -2, -5, -8,-10,-10,-20,-20,-30,-30, - - -30,-30,-20,-20,-10,-10, -8, -5, -2, -1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 5, 10, 12, 15, 20, 25, 30, 32, - }; -#else - static const AF_WarpScore - af_warper_weights[64] = - { - 30, 20, 10, 5, 4, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -1, -2, -2, -5, -5,-10,-10,-15,-20, - - -20,-15,-15,-10,-10, -5, -5, -2, -2, -1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4, 5, 10, 20, - }; -#endif - - - /* Score segments for a given `scale' and `delta' in the range */ - /* `xx1' to `xx2', and store the best result in `warper'. If */ - /* the new best score is equal to the old one, prefer the */ - /* value with a smaller distortion (around `base_distort'). */ - - static void - af_warper_compute_line_best( AF_Warper warper, - FT_Fixed scale, - FT_Pos delta, - FT_Pos xx1, - FT_Pos xx2, - AF_WarpScore base_distort, - AF_Segment segments, - FT_Int num_segments ) - { - FT_Int idx_min, idx_max, idx0; - FT_Int nn; - AF_WarpScore scores[65]; - - - for ( nn = 0; nn < 65; nn++ ) - scores[nn] = 0; - - idx0 = xx1 - warper->t1; - - /* compute minimum and maximum indices */ - { - FT_Pos xx1min = warper->x1min; - FT_Pos xx1max = warper->x1max; - FT_Pos w = xx2 - xx1; - - - if ( xx1min + w < warper->x2min ) - xx1min = warper->x2min - w; - - if ( xx1max + w > warper->x2max ) - xx1max = warper->x2max - w; - - idx_min = xx1min - warper->t1; - idx_max = xx1max - warper->t1; - - if ( idx_min < 0 || idx_min > idx_max || idx_max > 64 ) - { - FT_TRACE5(( "invalid indices:\n" - " min=%d max=%d, xx1=%ld xx2=%ld,\n" - " x1min=%ld x1max=%ld, x2min=%ld x2max=%ld\n", - idx_min, idx_max, xx1, xx2, - warper->x1min, warper->x1max, - warper->x2min, warper->x2max )); - return; - } - } - - for ( nn = 0; nn < num_segments; nn++ ) - { - FT_Pos len = segments[nn].max_coord - segments[nn].min_coord; - FT_Pos y0 = FT_MulFix( segments[nn].pos, scale ) + delta; - FT_Pos y = y0 + ( idx_min - idx0 ); - FT_Int idx; - - - /* score the length of the segments for the given range */ - for ( idx = idx_min; idx <= idx_max; idx++, y++ ) - scores[idx] += af_warper_weights[y & 63] * len; - } - - /* find best score */ - { - FT_Int idx; - - - for ( idx = idx_min; idx <= idx_max; idx++ ) - { - AF_WarpScore score = scores[idx]; - AF_WarpScore distort = base_distort + ( idx - idx0 ); - - - if ( score > warper->best_score || - ( score == warper->best_score && - distort < warper->best_distort ) ) - { - warper->best_score = score; - warper->best_distort = distort; - warper->best_scale = scale; - warper->best_delta = delta + ( idx - idx0 ); - } - } - } - } - - - /* Compute optimal scaling and delta values for a given glyph and */ - /* dimension. */ - - FT_LOCAL_DEF( void ) - af_warper_compute( AF_Warper warper, - AF_GlyphHints hints, - AF_Dimension dim, - FT_Fixed *a_scale, - FT_Pos *a_delta ) - { - AF_AxisHints axis; - AF_Point points; - - FT_Fixed org_scale; - FT_Pos org_delta; - - FT_Int nn, num_points, num_segments; - FT_Int X1, X2; - FT_Int w; - - AF_WarpScore base_distort; - AF_Segment segments; - - - /* get original scaling transformation */ - if ( dim == AF_DIMENSION_VERT ) - { - org_scale = hints->y_scale; - org_delta = hints->y_delta; - } - else - { - org_scale = hints->x_scale; - org_delta = hints->x_delta; - } - - warper->best_scale = org_scale; - warper->best_delta = org_delta; - warper->best_score = FT_INT_MIN; - warper->best_distort = 0; - - axis = &hints->axis[dim]; - segments = axis->segments; - num_segments = axis->num_segments; - points = hints->points; - num_points = hints->num_points; - - *a_scale = org_scale; - *a_delta = org_delta; - - /* get X1 and X2, minimum and maximum in original coordinates */ - if ( num_segments < 1 ) - return; - -#if 1 - X1 = X2 = points[0].fx; - for ( nn = 1; nn < num_points; nn++ ) - { - FT_Int X = points[nn].fx; - - - if ( X < X1 ) - X1 = X; - if ( X > X2 ) - X2 = X; - } -#else - X1 = X2 = segments[0].pos; - for ( nn = 1; nn < num_segments; nn++ ) - { - FT_Int X = segments[nn].pos; - - - if ( X < X1 ) - X1 = X; - if ( X > X2 ) - X2 = X; - } -#endif - - if ( X1 >= X2 ) - return; - - warper->x1 = FT_MulFix( X1, org_scale ) + org_delta; - warper->x2 = FT_MulFix( X2, org_scale ) + org_delta; - - warper->t1 = AF_WARPER_FLOOR( warper->x1 ); - warper->t2 = AF_WARPER_CEIL( warper->x2 ); - - /* examine a half pixel wide range around the maximum coordinates */ - warper->x1min = warper->x1 & ~31; - warper->x1max = warper->x1min + 32; - warper->x2min = warper->x2 & ~31; - warper->x2max = warper->x2min + 32; - - if ( warper->x1max > warper->x2 ) - warper->x1max = warper->x2; - - if ( warper->x2min < warper->x1 ) - warper->x2min = warper->x1; - - warper->w0 = warper->x2 - warper->x1; - - if ( warper->w0 <= 64 ) - { - warper->x1max = warper->x1; - warper->x2min = warper->x2; - } - - /* examine (at most) a pixel wide range around the natural width */ - warper->wmin = warper->x2min - warper->x1max; - warper->wmax = warper->x2max - warper->x1min; - -#if 1 - /* some heuristics to reduce the number of widths to be examined */ - { - int margin = 16; - - - if ( warper->w0 <= 128 ) - { - margin = 8; - if ( warper->w0 <= 96 ) - margin = 4; - } - - if ( warper->wmin < warper->w0 - margin ) - warper->wmin = warper->w0 - margin; - - if ( warper->wmax > warper->w0 + margin ) - warper->wmax = warper->w0 + margin; - } - - if ( warper->wmin < warper->w0 * 3 / 4 ) - warper->wmin = warper->w0 * 3 / 4; - - if ( warper->wmax > warper->w0 * 5 / 4 ) - warper->wmax = warper->w0 * 5 / 4; -#else - /* no scaling, just translation */ - warper->wmin = warper->wmax = warper->w0; -#endif - - for ( w = warper->wmin; w <= warper->wmax; w++ ) - { - FT_Fixed new_scale; - FT_Pos new_delta; - FT_Pos xx1, xx2; - - - /* compute min and max positions for given width, */ - /* assuring that they stay within the coordinate ranges */ - xx1 = warper->x1; - xx2 = warper->x2; - if ( w >= warper->w0 ) - { - xx1 -= w - warper->w0; - if ( xx1 < warper->x1min ) - { - xx2 += warper->x1min - xx1; - xx1 = warper->x1min; - } - } - else - { - xx1 -= w - warper->w0; - if ( xx1 > warper->x1max ) - { - xx2 -= xx1 - warper->x1max; - xx1 = warper->x1max; - } - } - - if ( xx1 < warper->x1 ) - base_distort = warper->x1 - xx1; - else - base_distort = xx1 - warper->x1; - - if ( xx2 < warper->x2 ) - base_distort += warper->x2 - xx2; - else - base_distort += xx2 - warper->x2; - - /* give base distortion a greater weight while scoring */ - base_distort *= 10; - - new_scale = org_scale + FT_DivFix( w - warper->w0, X2 - X1 ); - new_delta = xx1 - FT_MulFix( X1, new_scale ); - - af_warper_compute_line_best( warper, new_scale, new_delta, xx1, xx2, - base_distort, - segments, num_segments ); - } - - { - FT_Fixed best_scale = warper->best_scale; - FT_Pos best_delta = warper->best_delta; - - - hints->xmin_delta = FT_MulFix( X1, best_scale - org_scale ) - + best_delta; - hints->xmax_delta = FT_MulFix( X2, best_scale - org_scale ) - + best_delta; - - *a_scale = best_scale; - *a_delta = best_delta; - } - } - -#else /* !AF_CONFIG_OPTION_USE_WARPER */ - - /* ANSI C doesn't like empty source files */ - typedef int _af_warp_dummy; - -#endif /* !AF_CONFIG_OPTION_USE_WARPER */ - -/* END */ diff --git a/thirdparty/freetype/src/autofit/afwarp.h b/thirdparty/freetype/src/autofit/afwarp.h deleted file mode 100644 index cdea23e7de..0000000000 --- a/thirdparty/freetype/src/autofit/afwarp.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** - * - * afwarp.h - * - * Auto-fitter warping algorithm (specification). - * - * Copyright (C) 2006-2020 by - * David Turner, Robert Wilhelm, and Werner Lemberg. - * - * This file is part of the FreeType project, and may only be used, - * modified, and distributed under the terms of the FreeType project - * license, LICENSE.TXT. By continuing to use, modify, or distribute - * this file you indicate that you have read the license and - * understand and accept it fully. - * - */ - - -#ifndef AFWARP_H_ -#define AFWARP_H_ - -#include "afhints.h" - -FT_BEGIN_HEADER - -#define AF_WARPER_SCALE - -#define AF_WARPER_FLOOR( x ) ( (x) & ~FT_TYPEOF( x )63 ) -#define AF_WARPER_CEIL( x ) AF_WARPER_FLOOR( (x) + 63 ) - - - typedef FT_Int32 AF_WarpScore; - - typedef struct AF_WarperRec_ - { - FT_Pos x1, x2; - FT_Pos t1, t2; - FT_Pos x1min, x1max; - FT_Pos x2min, x2max; - FT_Pos w0, wmin, wmax; - - FT_Fixed best_scale; - FT_Pos best_delta; - AF_WarpScore best_score; - AF_WarpScore best_distort; - - } AF_WarperRec, *AF_Warper; - - -#ifdef AF_CONFIG_OPTION_USE_WARPER - FT_LOCAL( void ) - af_warper_compute( AF_Warper warper, - AF_GlyphHints hints, - AF_Dimension dim, - FT_Fixed *a_scale, - FT_Pos *a_delta ); -#endif - - -FT_END_HEADER - - -#endif /* AFWARP_H_ */ - - -/* END */ diff --git a/thirdparty/freetype/src/autofit/afwrtsys.h b/thirdparty/freetype/src/autofit/afwrtsys.h deleted file mode 100644 index 3990633d2d..0000000000 --- a/thirdparty/freetype/src/autofit/afwrtsys.h +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** - * - * afwrtsys.h - * - * Auto-fitter writing systems (specification only). - * - * Copyright (C) 2013-2020 by - * David Turner, Robert Wilhelm, and Werner Lemberg. - * - * This file is part of the FreeType project, and may only be used, - * modified, and distributed under the terms of the FreeType project - * license, LICENSE.TXT. By continuing to use, modify, or distribute - * this file you indicate that you have read the license and - * understand and accept it fully. - * - */ - - -#ifndef AFWRTSYS_H_ -#define AFWRTSYS_H_ - - /* Since preprocessor directives can't create other preprocessor */ - /* directives, we have to include the header files manually. */ - -#include "afdummy.h" -#include "aflatin.h" -#include "afcjk.h" -#include "afindic.h" -#ifdef FT_OPTION_AUTOFIT2 -#include "aflatin2.h" -#endif - -#endif /* AFWRTSYS_H_ */ - - - /* The following part can be included multiple times. */ - /* Define `WRITING_SYSTEM' as needed. */ - - - /* Add new writing systems here. The arguments are the writing system */ - /* name in lowercase and uppercase, respectively. */ - - WRITING_SYSTEM( dummy, DUMMY ) - WRITING_SYSTEM( latin, LATIN ) - WRITING_SYSTEM( cjk, CJK ) - WRITING_SYSTEM( indic, INDIC ) -#ifdef FT_OPTION_AUTOFIT2 - WRITING_SYSTEM( latin2, LATIN2 ) -#endif - - -/* END */ diff --git a/thirdparty/freetype/src/autofit/afws-decl.h b/thirdparty/freetype/src/autofit/afws-decl.h new file mode 100644 index 0000000000..c10dd57e7b --- /dev/null +++ b/thirdparty/freetype/src/autofit/afws-decl.h @@ -0,0 +1,33 @@ +/**************************************************************************** + * + * afws-decl.h + * + * Auto-fitter writing system declarations (specification only). + * + * Copyright (C) 2013-2021 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#ifndef AFWS_DECL_H_ +#define AFWS_DECL_H_ + + /* Since preprocessor directives can't create other preprocessor */ + /* directives, we have to include the header files manually. */ + +#include "afdummy.h" +#include "aflatin.h" +#include "afcjk.h" +#include "afindic.h" + +#endif /* AFWS_DECL_H_ */ + + +/* END */ diff --git a/thirdparty/freetype/src/autofit/afws-iter.h b/thirdparty/freetype/src/autofit/afws-iter.h new file mode 100644 index 0000000000..55714203e3 --- /dev/null +++ b/thirdparty/freetype/src/autofit/afws-iter.h @@ -0,0 +1,31 @@ +/**************************************************************************** + * + * afws-iter.h + * + * Auto-fitter writing systems iterator (specification only). + * + * Copyright (C) 2013-2021 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + /* This header may be included multiple times. */ + /* Define `WRITING_SYSTEM' as needed. */ + + + /* Add new writing systems here. The arguments are the writing system */ + /* name in lowercase and uppercase, respectively. */ + + WRITING_SYSTEM( dummy, DUMMY ) + WRITING_SYSTEM( latin, LATIN ) + WRITING_SYSTEM( cjk, CJK ) + WRITING_SYSTEM( indic, INDIC ) + + +/* END */ diff --git a/thirdparty/freetype/src/autofit/autofit.c b/thirdparty/freetype/src/autofit/autofit.c index ef5e7f1452..7e692b4de9 100644 --- a/thirdparty/freetype/src/autofit/autofit.c +++ b/thirdparty/freetype/src/autofit/autofit.c @@ -4,7 +4,7 @@ * * Auto-fitter module (body). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -18,7 +18,6 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT -#include "afangles.c" #include "afblue.c" #include "afcjk.c" #include "afdummy.c" @@ -26,12 +25,10 @@ #include "afhints.c" #include "afindic.c" #include "aflatin.c" -#include "aflatin2.c" #include "afloader.c" #include "afmodule.c" #include "afranges.c" #include "afshaper.c" -#include "afwarp.c" /* END */ diff --git a/thirdparty/freetype/src/autofit/module.mk b/thirdparty/freetype/src/autofit/module.mk deleted file mode 100644 index c32781f478..0000000000 --- a/thirdparty/freetype/src/autofit/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 auto-fitter module definition -# - - -# Copyright (C) 2003-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += AUTOFIT_MODULE - -define AUTOFIT_MODULE -$(OPEN_DRIVER) FT_Module_Class, autofit_module_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)autofit $(ECHO_DRIVER_DESC)automatic hinting module$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/autofit/rules.mk b/thirdparty/freetype/src/autofit/rules.mk deleted file mode 100644 index 553ddce6b7..0000000000 --- a/thirdparty/freetype/src/autofit/rules.mk +++ /dev/null @@ -1,88 +0,0 @@ -# -# FreeType 2 auto-fitter module configuration rules -# - - -# Copyright (C) 2003-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# AUTOF driver directory -# -AUTOF_DIR := $(SRC_DIR)/autofit - - -# compilation flags for the driver -# -AUTOF_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(AUTOF_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# AUTOF driver sources (i.e., C files) -# -AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \ - $(AUTOF_DIR)/afblue.c \ - $(AUTOF_DIR)/afcjk.c \ - $(AUTOF_DIR)/afdummy.c \ - $(AUTOF_DIR)/afglobal.c \ - $(AUTOF_DIR)/afhints.c \ - $(AUTOF_DIR)/afindic.c \ - $(AUTOF_DIR)/aflatin.c \ - $(AUTOF_DIR)/afloader.c \ - $(AUTOF_DIR)/afmodule.c \ - $(AUTOF_DIR)/afranges.c \ - $(AUTOF_DIR)/afshaper.c \ - $(AUTOF_DIR)/afwarp.c - -# AUTOF driver headers -# -AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h) \ - $(AUTOF_DIR)/afcover.h \ - $(AUTOF_DIR)/aferrors.h \ - $(AUTOF_DIR)/afscript.h \ - $(AUTOF_DIR)/afstyles.h \ - $(AUTOF_DIR)/aftypes.h \ - $(AUTOF_DIR)/afwrtsys.h - - -# AUTOF driver object(s) -# -# AUTOF_DRV_OBJ_M is used during `multi' builds. -# AUTOF_DRV_OBJ_S is used during `single' builds. -# -AUTOF_DRV_OBJ_M := $(AUTOF_DRV_SRC:$(AUTOF_DIR)/%.c=$(OBJ_DIR)/%.$O) -AUTOF_DRV_OBJ_S := $(OBJ_DIR)/autofit.$O - -# AUTOF driver source file for single build -# -AUTOF_DRV_SRC_S := $(AUTOF_DIR)/autofit.c - - -# AUTOF driver - single object -# -$(AUTOF_DRV_OBJ_S): $(AUTOF_DRV_SRC_S) $(AUTOF_DRV_SRC) \ - $(FREETYPE_H) $(AUTOF_DRV_H) - $(AUTOF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(AUTOF_DRV_SRC_S)) - - -# AUTOF driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(AUTOF_DIR)/%.c $(FREETYPE_H) $(AUTOF_DRV_H) - $(AUTOF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(AUTOF_DRV_OBJ_S) -DRV_OBJS_M += $(AUTOF_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/base/ftadvanc.c b/thirdparty/freetype/src/base/ftadvanc.c index c689e6a15b..f20b9928aa 100644 --- a/thirdparty/freetype/src/base/ftadvanc.c +++ b/thirdparty/freetype/src/base/ftadvanc.c @@ -4,7 +4,7 @@ * * Quick computation of advance widths (body). * - * Copyright (C) 2008-2020 by + * Copyright (C) 2008-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftbase.c b/thirdparty/freetype/src/base/ftbase.c index bfbaffd64e..7366bc46db 100644 --- a/thirdparty/freetype/src/base/ftbase.c +++ b/thirdparty/freetype/src/base/ftbase.c @@ -4,7 +4,7 @@ * * Single object library component (body only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftbase.h b/thirdparty/freetype/src/base/ftbase.h index 25afa9bc31..963ff93d68 100644 --- a/thirdparty/freetype/src/base/ftbase.h +++ b/thirdparty/freetype/src/base/ftbase.h @@ -4,7 +4,7 @@ * * Private functions used in the `base' module (specification). * - * Copyright (C) 2008-2020 by + * Copyright (C) 2008-2021 by * David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftbbox.c b/thirdparty/freetype/src/base/ftbbox.c index 30a4eba0b3..4db29cbf83 100644 --- a/thirdparty/freetype/src/base/ftbbox.c +++ b/thirdparty/freetype/src/base/ftbbox.c @@ -4,7 +4,7 @@ * * FreeType bbox computation (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used diff --git a/thirdparty/freetype/src/base/ftbdf.c b/thirdparty/freetype/src/base/ftbdf.c index fc374c6675..f93ca8eb75 100644 --- a/thirdparty/freetype/src/base/ftbdf.c +++ b/thirdparty/freetype/src/base/ftbdf.c @@ -4,7 +4,7 @@ * * FreeType API for accessing BDF-specific strings (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftbitmap.c b/thirdparty/freetype/src/base/ftbitmap.c index 584213ddcf..2146d3e364 100644 --- a/thirdparty/freetype/src/base/ftbitmap.c +++ b/thirdparty/freetype/src/base/ftbitmap.c @@ -4,7 +4,7 @@ * * FreeType utility functions for bitmaps (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -112,10 +112,10 @@ target_size = (FT_ULong)target_pitch * target->rows; if ( target_size != size ) - (void)FT_QREALLOC( target->buffer, target_size, size ); + FT_MEM_QREALLOC( target->buffer, target_size, size ); } else - (void)FT_QALLOC( target->buffer, size ); + FT_MEM_QALLOC( target->buffer, size ); if ( !error ) { @@ -907,8 +907,8 @@ final_rows = ( final_ury - final_lly ) >> 6; #ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE5(( "FT_Bitmap_Blend:\n" - " source bitmap: (%ld, %ld) -- (%ld, %ld); %d x %d\n", + FT_TRACE5(( "FT_Bitmap_Blend:\n" )); + FT_TRACE5(( " source bitmap: (%ld, %ld) -- (%ld, %ld); %d x %d\n", source_llx / 64, source_lly / 64, source_urx / 64, source_ury / 64, source_->width, source_->rows )); diff --git a/thirdparty/freetype/src/base/ftcalc.c b/thirdparty/freetype/src/base/ftcalc.c index b5258c85a1..9df8e4010d 100644 --- a/thirdparty/freetype/src/base/ftcalc.c +++ b/thirdparty/freetype/src/base/ftcalc.c @@ -4,7 +4,7 @@ * * Arithmetic computations (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -45,7 +45,7 @@ /* we need to emulate a 64-bit data type if a real one isn't available */ -#ifndef FT_LONG64 +#ifndef FT_INT64 typedef struct FT_Int64_ { @@ -54,7 +54,7 @@ } FT_Int64; -#endif /* !FT_LONG64 */ +#endif /* !FT_INT64 */ /************************************************************************** @@ -79,7 +79,7 @@ FT_END_STMNT /* The following three functions are available regardless of whether */ - /* FT_LONG64 is defined. */ + /* FT_INT64 is defined. */ /* documentation is in freetype.h */ @@ -109,7 +109,7 @@ #ifndef FT_MSB - FT_BASE_DEF ( FT_Int ) + FT_BASE_DEF( FT_Int ) FT_MSB( FT_UInt32 z ) { FT_Int shift = 0; @@ -164,7 +164,7 @@ } -#ifdef FT_LONG64 +#ifdef FT_INT64 /* documentation is in freetype.h */ @@ -272,7 +272,7 @@ } -#else /* !FT_LONG64 */ +#else /* !FT_INT64 */ static void @@ -651,7 +651,7 @@ } -#endif /* !FT_LONG64 */ +#endif /* !FT_INT64 */ /* documentation is in ftglyph.h */ @@ -985,7 +985,7 @@ /* we silently ignore overflow errors since such large values */ /* lead to even more (harmless) rendering errors later on */ -#ifdef FT_LONG64 +#ifdef FT_INT64 FT_Int64 delta = SUB_INT64( MUL_INT64( in_x, out_y ), MUL_INT64( in_y, out_x ) ); diff --git a/thirdparty/freetype/src/base/ftcid.c b/thirdparty/freetype/src/base/ftcid.c index ce8a876adc..216ee2b3e4 100644 --- a/thirdparty/freetype/src/base/ftcid.c +++ b/thirdparty/freetype/src/base/ftcid.c @@ -4,7 +4,7 @@ * * FreeType API for accessing CID font information. * - * Copyright (C) 2007-2020 by + * Copyright (C) 2007-2021 by * Derek Clegg and Michael Toftdal. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftcolor.c b/thirdparty/freetype/src/base/ftcolor.c index a50d680096..3ef3256b20 100644 --- a/thirdparty/freetype/src/base/ftcolor.c +++ b/thirdparty/freetype/src/base/ftcolor.c @@ -4,7 +4,7 @@ * * FreeType's glyph color management (body). * - * Copyright (C) 2018-2020 by + * Copyright (C) 2018-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftdbgmem.c b/thirdparty/freetype/src/base/ftdbgmem.c index eb0d651607..4f5c1e7697 100644 --- a/thirdparty/freetype/src/base/ftdbgmem.c +++ b/thirdparty/freetype/src/base/ftdbgmem.c @@ -4,7 +4,7 @@ * * Memory debugger (body). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -302,46 +302,6 @@ } - static FT_MemTable - ft_mem_table_new( FT_Memory memory ) - { - FT_MemTable table; - - - table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) ); - if ( !table ) - goto Exit; - - FT_ZERO( table ); - - table->size = FT_MEM_SIZE_MIN; - table->nodes = 0; - - table->memory = memory; - - table->memory_user = memory->user; - - table->alloc = memory->alloc; - table->realloc = memory->realloc; - table->free = memory->free; - - table->buckets = (FT_MemNode *) - memory->alloc( - memory, - table->size * (FT_Long)sizeof ( FT_MemNode ) ); - if ( table->buckets ) - FT_ARRAY_ZERO( table->buckets, table->size ); - else - { - memory->free( memory, table ); - table = NULL; - } - - Exit: - return table; - } - - static void ft_mem_table_destroy( FT_MemTable table ) { @@ -350,8 +310,6 @@ FT_Long leaks = 0; - FT_DumpMemory( table->memory ); - /* remove all blocks from the table, revealing leaked ones */ for ( i = 0; i < table->size; i++ ) { @@ -413,8 +371,6 @@ printf( "FreeType: maximum memory footprint = %ld\n", table->alloc_max ); - ft_mem_table_free( table, table ); - if ( leak_count > 0 ) ft_mem_debug_panic( "FreeType: %ld bytes of memory leaked in %ld blocks\n", @@ -821,17 +777,30 @@ } - extern FT_Int + extern void ft_mem_debug_init( FT_Memory memory ) { FT_MemTable table; - FT_Int result = 0; - if ( ft_getenv( "FT2_DEBUG_MEMORY" ) ) + if ( !ft_getenv( "FT2_DEBUG_MEMORY" ) ) + return; + + table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) ); + + if ( table ) { - table = ft_mem_table_new( memory ); - if ( table ) + FT_ZERO( table ); + + table->memory = memory; + table->memory_user = memory->user; + table->alloc = memory->alloc; + table->realloc = memory->realloc; + table->free = memory->free; + + ft_mem_table_resize( table ); + + if ( table->size ) { const char* p; @@ -876,28 +845,31 @@ if ( keep_alive > 0 ) table->keep_alive = 1; } - - result = 1; } + else + memory->free( memory, table ); } - return result; } extern void ft_mem_debug_done( FT_Memory memory ) { - FT_MemTable table = (FT_MemTable)memory->user; + if ( memory->free == ft_mem_debug_free ) + { + FT_MemTable table = (FT_MemTable)memory->user; - if ( table ) - { + FT_DumpMemory( memory ); + + ft_mem_table_destroy( table ); + memory->free = table->free; memory->realloc = table->realloc; memory->alloc = table->alloc; + memory->user = table->memory_user; - ft_mem_table_destroy( table ); - memory->user = NULL; + memory->free( memory, table ); } } @@ -922,11 +894,9 @@ extern void FT_DumpMemory( FT_Memory memory ) { - FT_MemTable table = (FT_MemTable)memory->user; - - - if ( table ) + if ( memory->free == ft_mem_debug_free ) { + FT_MemTable table = (FT_MemTable)memory->user; FT_MemSource* bucket = table->sources; FT_MemSource* limit = bucket + FT_MEM_SOURCE_BUCKETS; FT_MemSource* sources; diff --git a/thirdparty/freetype/src/base/ftdebug.c b/thirdparty/freetype/src/base/ftdebug.c index 62cf680b01..3485791306 100644 --- a/thirdparty/freetype/src/base/ftdebug.c +++ b/thirdparty/freetype/src/base/ftdebug.c @@ -4,7 +4,7 @@ * * Debugging and logging component (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -42,7 +42,53 @@ #include <freetype/freetype.h> +#include <freetype/ftlogging.h> #include <freetype/internal/ftdebug.h> +#include <freetype/internal/ftobjs.h> + + +#ifdef FT_DEBUG_LOGGING + + /************************************************************************** + * + * Variables used to control logging. + * + * 1. `ft_default_trace_level` stores the value of trace levels, which are + * provided to FreeType using the `FT2_DEBUG` environment variable. + * + * 2. `ft_fileptr` stores the `FILE*` handle. + * + * 3. `ft_component` is a string that holds the name of `FT_COMPONENT`. + * + * 4. The flag `ft_component_flag` prints the name of `FT_COMPONENT` along + * with the actual log message if set to true. + * + * 5. The flag `ft_timestamp_flag` prints time along with the actual log + * message if set to ture. + * + * 6. `ft_have_newline_char` is used to differentiate between a log + * message with and without a trailing newline character. + * + * 7. `ft_custom_trace_level` stores the custom trace level value, which + * is provided by the user at run-time. + * + * We use `static` to avoid 'unused variable' warnings. + * + */ + static const char* ft_default_trace_level = NULL; + static FILE* ft_fileptr = NULL; + static const char* ft_component = NULL; + static FT_Bool ft_component_flag = FALSE; + static FT_Bool ft_timestamp_flag = FALSE; + static FT_Bool ft_have_newline_char = TRUE; + static const char* ft_custom_trace_level = NULL; + + /* declared in ftdebug.h */ + + dlg_handler ft_default_log_handler = NULL; + FT_Custom_Log_Handler custom_output_handler = NULL; + +#endif /* FT_DEBUG_LOGGING */ #ifdef FT_DEBUG_LEVEL_ERROR @@ -106,7 +152,6 @@ #endif /* FT_DEBUG_LEVEL_ERROR */ - #ifdef FT_DEBUG_LEVEL_TRACE /* array of trace levels, initialized to 0; */ @@ -195,8 +240,17 @@ FT_BASE_DEF( void ) ft_debug_init( void ) { - const char* ft2_debug = ft_getenv( "FT2_DEBUG" ); + const char* ft2_debug = NULL; + +#ifdef FT_DEBUG_LOGGING + if ( ft_custom_trace_level != NULL ) + ft2_debug = ft_custom_trace_level; + else + ft2_debug = ft_default_trace_level; +#else + ft2_debug = ft_getenv( "FT2_DEBUG" ); +#endif if ( ft2_debug ) { @@ -210,6 +264,49 @@ if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' ) continue; +#ifdef FT_DEBUG_LOGGING + + /* check extra arguments for logging */ + if ( *p == '-' ) + { + const char* r = ++p; + + + if ( *r == 'v' ) + { + const char* s = ++r; + + + ft_component_flag = TRUE; + + if ( *s == 't' ) + { + ft_timestamp_flag = TRUE; + p++; + } + + p++; + } + + else if ( *r == 't' ) + { + const char* s = ++r; + + + ft_timestamp_flag = TRUE; + + if ( *s == 'v' ) + { + ft_component_flag = TRUE; + p++; + } + + p++; + } + } + +#endif /* FT_DEBUG_LOGGING */ + /* read toggle name, followed by ':' */ q = p; while ( *p && *p != ':' ) @@ -311,8 +408,237 @@ /* nothing */ } - #endif /* !FT_DEBUG_LEVEL_TRACE */ +#ifdef FT_DEBUG_LOGGING + + /************************************************************************** + * + * Initialize and de-initialize 'dlg' library. + * + */ + + FT_BASE_DEF( void ) + ft_logging_init( void ) + { + ft_default_log_handler = ft_log_handler; + ft_default_trace_level = ft_getenv( "FT2_DEBUG" ); + + if ( ft_getenv( "FT_LOGGING_FILE" ) ) + ft_fileptr = ft_fopen( ft_getenv( "FT_LOGGING_FILE" ), "w" ); + else + ft_fileptr = stderr; + + ft_debug_init(); + + /* Set the default output handler for 'dlg'. */ + dlg_set_handler( ft_default_log_handler, NULL ); + } + + + FT_BASE_DEF( void ) + ft_logging_deinit( void ) + { + if ( ft_fileptr != stderr ) + ft_fclose( ft_fileptr ); + } + + + /************************************************************************** + * + * An output log handler for FreeType. + * + */ + FT_BASE_DEF( void ) + ft_log_handler( const struct dlg_origin* origin, + const char* string, + void* data ) + { + char features_buf[128]; + char* bufp = features_buf; + + FT_UNUSED( data ); + + + if ( ft_have_newline_char ) + { + const char* features = NULL; + size_t features_length = 0; + + +#define FEATURES_TIMESTAMP "[%h:%m] " +#define FEATURES_COMPONENT "[%t] " +#define FEATURES_TIMESTAMP_COMPONENT "[%h:%m %t] " + + if ( ft_timestamp_flag && ft_component_flag ) + { + features = FEATURES_TIMESTAMP_COMPONENT; + features_length = sizeof ( FEATURES_TIMESTAMP_COMPONENT ); + } + else if ( ft_timestamp_flag ) + { + features = FEATURES_TIMESTAMP; + features_length = sizeof ( FEATURES_TIMESTAMP ); + } + else if ( ft_component_flag ) + { + features = FEATURES_COMPONENT; + features_length = sizeof ( FEATURES_COMPONENT ); + } + + if ( ft_component_flag || ft_timestamp_flag ) + { + ft_strncpy( features_buf, features, features_length ); + bufp += features_length - 1; + } + + if ( ft_component_flag ) + { + size_t tag_length = ft_strlen( *origin->tags ); + size_t i; + + + /* To vertically align tracing messages we compensate the */ + /* different FT_COMPONENT string lengths by inserting an */ + /* appropriate amount of space characters. */ + for ( i = 0; + i < FT_MAX_TRACE_LEVEL_LENGTH - tag_length; + i++ ) + *bufp++ = ' '; + } + } + + /* Finally add the format string for the tracing message. */ + *bufp++ = '%'; + *bufp++ = 'c'; + *bufp = '\0'; + + dlg_generic_outputf_stream( ft_fileptr, + (const char*)features_buf, + origin, + string, + dlg_default_output_styles, + true ); + + if ( ft_strrchr( string, '\n' ) ) + ft_have_newline_char = TRUE; + else + ft_have_newline_char = FALSE; + } + + + /* documentation is in ftdebug.h */ + FT_BASE_DEF( void ) + ft_add_tag( const char* tag ) + { + ft_component = tag; + + dlg_add_tag( tag, NULL ); + } + + + /* documentation is in ftdebug.h */ + FT_BASE_DEF( void ) + ft_remove_tag( const char* tag ) + { + dlg_remove_tag( tag, NULL ); + } + + + /* documentation is in ftlogging.h */ + + FT_EXPORT_DEF( void ) + FT_Trace_Set_Level( const char* level ) + { + ft_component_flag = FALSE; + ft_timestamp_flag = FALSE; + ft_custom_trace_level = level; + + ft_debug_init(); + } + + + /* documentation is in ftlogging.h */ + + FT_EXPORT_DEF( void ) + FT_Trace_Set_Default_Level( void ) + { + ft_component_flag = FALSE; + ft_timestamp_flag = FALSE; + ft_custom_trace_level = NULL; + + ft_debug_init(); + } + + + /************************************************************************** + * + * Functions to handle a custom log handler. + * + */ + + /* documentation is in ftlogging.h */ + + FT_EXPORT_DEF( void ) + FT_Set_Log_Handler( FT_Custom_Log_Handler handler ) + { + custom_output_handler = handler; + } + + + /* documentation is in ftlogging.h */ + + FT_EXPORT_DEF( void ) + FT_Set_Default_Log_Handler( void ) + { + custom_output_handler = NULL; + } + + + /* documentation is in ftdebug.h */ + FT_BASE_DEF( void ) + FT_Logging_Callback( const char* fmt, + ... ) + { + va_list ap; + + + va_start( ap, fmt ); + custom_output_handler( ft_component, fmt, ap ); + va_end( ap ); + } + +#else /* !FT_DEBUG_LOGGING */ + + FT_EXPORT_DEF( void ) + FT_Trace_Set_Level( const char* level ) + { + FT_UNUSED( level ); + } + + + FT_EXPORT_DEF( void ) + FT_Trace_Set_Default_Level( void ) + { + /* nothing */ + } + + + FT_EXPORT_DEF( void ) + FT_Set_Log_Handler( FT_Custom_Log_Handler handler ) + { + FT_UNUSED( handler ); + } + + + FT_EXPORT_DEF( void ) + FT_Set_Default_Log_Handler( void ) + { + /* nothing */ + } + +#endif /* !FT_DEBUG_LOGGING */ + + /* END */ diff --git a/thirdparty/freetype/src/base/fterrors.c b/thirdparty/freetype/src/base/fterrors.c index eba9e76563..14649268f8 100644 --- a/thirdparty/freetype/src/base/fterrors.c +++ b/thirdparty/freetype/src/base/fterrors.c @@ -4,7 +4,7 @@ * * FreeType API for error code handling. * - * Copyright (C) 2018-2020 by + * Copyright (C) 2018-2021 by * Armin Hasitzka, David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftfntfmt.c b/thirdparty/freetype/src/base/ftfntfmt.c index a45317e797..4e1b830190 100644 --- a/thirdparty/freetype/src/base/ftfntfmt.c +++ b/thirdparty/freetype/src/base/ftfntfmt.c @@ -4,7 +4,7 @@ * * FreeType utility file for font formats (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftfstype.c b/thirdparty/freetype/src/base/ftfstype.c index bca548fc56..57e904d6f4 100644 --- a/thirdparty/freetype/src/base/ftfstype.c +++ b/thirdparty/freetype/src/base/ftfstype.c @@ -4,7 +4,7 @@ * * FreeType utility file to access FSType data (body). * - * Copyright (C) 2008-2020 by + * Copyright (C) 2008-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftgasp.c b/thirdparty/freetype/src/base/ftgasp.c index eed05a3265..b744f0a465 100644 --- a/thirdparty/freetype/src/base/ftgasp.c +++ b/thirdparty/freetype/src/base/ftgasp.c @@ -4,7 +4,7 @@ * * Access of TrueType's `gasp' table (body). * - * Copyright (C) 2007-2020 by + * Copyright (C) 2007-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftgloadr.c b/thirdparty/freetype/src/base/ftgloadr.c index 05fc7692bb..83ce0660ae 100644 --- a/thirdparty/freetype/src/base/ftgloadr.c +++ b/thirdparty/freetype/src/base/ftgloadr.c @@ -4,7 +4,7 @@ * * The FreeType glyph loader (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftglyph.c b/thirdparty/freetype/src/base/ftglyph.c index 825eba2c4d..e2c6f73f80 100644 --- a/thirdparty/freetype/src/base/ftglyph.c +++ b/thirdparty/freetype/src/base/ftglyph.c @@ -4,7 +4,7 @@ * * FreeType convenience functions to handle glyphs (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -453,9 +453,9 @@ /* documentation is in ftglyph.h */ FT_EXPORT_DEF( FT_Error ) - FT_Glyph_Transform( FT_Glyph glyph, - FT_Matrix* matrix, - FT_Vector* delta ) + FT_Glyph_Transform( FT_Glyph glyph, + const FT_Matrix* matrix, + const FT_Vector* delta ) { FT_Error error = FT_Err_Ok; @@ -533,10 +533,10 @@ /* documentation is in ftglyph.h */ FT_EXPORT_DEF( FT_Error ) - FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, - FT_Render_Mode render_mode, - FT_Vector* origin, - FT_Bool destroy ) + FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, + FT_Render_Mode render_mode, + const FT_Vector* origin, + FT_Bool destroy ) { FT_GlyphSlotRec dummy; FT_GlyphSlot_InternalRec dummy_internal; @@ -585,7 +585,7 @@ #if 1 /* if `origin' is set, translate the glyph image */ if ( origin ) - FT_Glyph_Transform( glyph, 0, origin ); + FT_Glyph_Transform( glyph, NULL, origin ); #else FT_UNUSED( origin ); #endif @@ -603,7 +603,7 @@ v.x = -origin->x; v.y = -origin->y; - FT_Glyph_Transform( glyph, 0, &v ); + FT_Glyph_Transform( glyph, NULL, &v ); } #endif diff --git a/thirdparty/freetype/src/base/ftgxval.c b/thirdparty/freetype/src/base/ftgxval.c index f04df14526..e9567f77f3 100644 --- a/thirdparty/freetype/src/base/ftgxval.c +++ b/thirdparty/freetype/src/base/ftgxval.c @@ -4,7 +4,7 @@ * * FreeType API for validating TrueTypeGX/AAT tables (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * Masatake YAMATO, Redhat K.K, * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/base/ftinit.c b/thirdparty/freetype/src/base/ftinit.c index 0acc75e460..a2d2b933c0 100644 --- a/thirdparty/freetype/src/base/ftinit.c +++ b/thirdparty/freetype/src/base/ftinit.c @@ -4,7 +4,7 @@ * * FreeType initialization layer (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -202,6 +202,10 @@ FT_Memory memory; +#ifdef FT_DEBUG_LOGGING + ft_logging_init(); +#endif + /* check of `alibrary' delayed to `FT_New_Library' */ /* First of all, allocate a new system object -- this function is part */ @@ -248,6 +252,10 @@ /* discard memory manager */ FT_Done_Memory( memory ); +#ifdef FT_DEBUG_LOGGING + ft_logging_deinit(); +#endif + return FT_Err_Ok; } diff --git a/thirdparty/freetype/src/base/ftlcdfil.c b/thirdparty/freetype/src/base/ftlcdfil.c index 1e84dbc894..488b913e63 100644 --- a/thirdparty/freetype/src/base/ftlcdfil.c +++ b/thirdparty/freetype/src/base/ftlcdfil.c @@ -4,7 +4,7 @@ * * FreeType API for color filtering of subpixel bitmap glyphs (body). * - * Copyright (C) 2006-2020 by + * Copyright (C) 2006-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -32,7 +32,7 @@ /* add padding according to filter weights */ - FT_BASE_DEF (void) + FT_BASE_DEF( void ) ft_lcd_padding( FT_BBox* cbox, FT_GlyphSlot slot, FT_Render_Mode mode ) @@ -357,7 +357,7 @@ FT_EXPORT_DEF( FT_Error ) FT_Library_SetLcdGeometry( FT_Library library, - FT_Vector* sub ) + FT_Vector sub[3] ) { FT_UNUSED( library ); FT_UNUSED( sub ); @@ -368,7 +368,7 @@ #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ /* add padding to accommodate outline shifts */ - FT_BASE_DEF (void) + FT_BASE_DEF( void ) ft_lcd_padding( FT_BBox* cbox, FT_GlyphSlot slot, FT_Render_Mode mode ) @@ -428,7 +428,7 @@ ft_memcpy( library->lcd_geometry, sub, 3 * sizeof( FT_Vector ) ); - return FT_THROW( Unimplemented_Feature ); + return FT_Err_Ok; } #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ diff --git a/thirdparty/freetype/src/base/ftmac.c b/thirdparty/freetype/src/base/ftmac.c index 55a631fd74..36a860979e 100644 --- a/thirdparty/freetype/src/base/ftmac.c +++ b/thirdparty/freetype/src/base/ftmac.c @@ -8,7 +8,7 @@ * This file is for Mac OS X only; see builds/mac/ftoldmac.c for * classic platforms built by MPW. * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -560,7 +560,7 @@ if ( lwfn_file_name[0] ) { err = lookup_lwfn_by_fond( pathname, lwfn_file_name, - buff, sizeof ( buff ) ); + buff, sizeof ( buff ) ); if ( !err ) have_lwfn = 1; } @@ -631,7 +631,7 @@ old_total_size = total_size; } - if ( FT_ALLOC( buffer, (FT_Long)total_size ) ) + if ( FT_QALLOC( buffer, (FT_Long)total_size ) ) goto Error; /* Second pass: append all POST data to the buffer, add PFB fields. */ @@ -752,7 +752,7 @@ if ( FT_MAC_RFORK_MAX_LEN < sfnt_size ) return FT_THROW( Array_Too_Large ); - if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) ) + if ( FT_QALLOC( sfnt_data, (FT_Long)sfnt_size ) ) { ReleaseResource( sfnt ); return error; diff --git a/thirdparty/freetype/src/base/ftmm.c b/thirdparty/freetype/src/base/ftmm.c index 9a702b9933..fc5d4ecc8d 100644 --- a/thirdparty/freetype/src/base/ftmm.c +++ b/thirdparty/freetype/src/base/ftmm.c @@ -4,7 +4,7 @@ * * Multiple Master font support (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftobjs.c b/thirdparty/freetype/src/base/ftobjs.c index c060bbbc87..883f1a8970 100644 --- a/thirdparty/freetype/src/base/ftobjs.c +++ b/thirdparty/freetype/src/base/ftobjs.c @@ -4,7 +4,7 @@ * * The FreeType private base classes (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -78,6 +78,9 @@ #pragma warning( pop ) #endif + /* This array must stay in sync with the @FT_Pixel_Mode enumeration */ + /* (in file `ftimage.h`). */ + static const char* const pixel_modes[] = { "none", @@ -87,7 +90,8 @@ "gray 4-bit bitmap", "LCD 8-bit bitmap", "vertical LCD 8-bit bitmap", - "BGRA 32-bit color image bitmap" + "BGRA 32-bit color image bitmap", + "SDF 8-bit bitmap" }; #endif /* FT_DEBUG_LEVEL_TRACE */ @@ -193,6 +197,7 @@ FT_Error error; FT_Memory memory; FT_Stream stream = NULL; + FT_UInt mode; *astream = NULL; @@ -204,49 +209,56 @@ return FT_THROW( Invalid_Argument ); memory = library->memory; + mode = args->flags & + ( FT_OPEN_MEMORY | FT_OPEN_STREAM | FT_OPEN_PATHNAME ); - if ( FT_NEW( stream ) ) - goto Exit; - - stream->memory = memory; - - if ( args->flags & FT_OPEN_MEMORY ) + if ( mode == FT_OPEN_MEMORY ) { /* create a memory-based stream */ + if ( FT_NEW( stream ) ) + goto Exit; + FT_Stream_OpenMemory( stream, (const FT_Byte*)args->memory_base, (FT_ULong)args->memory_size ); + stream->memory = memory; } #ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT - else if ( args->flags & FT_OPEN_PATHNAME ) + else if ( mode == FT_OPEN_PATHNAME ) { /* create a normal system stream */ + if ( FT_NEW( stream ) ) + goto Exit; + + stream->memory = memory; error = FT_Stream_Open( stream, args->pathname ); - stream->pathname.pointer = args->pathname; + if ( error ) + FT_FREE( stream ); } - else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream ) + else if ( ( mode == FT_OPEN_STREAM ) && args->stream ) { /* use an existing, user-provided stream */ /* in this case, we do not need to allocate a new stream object */ /* since the caller is responsible for closing it himself */ - FT_FREE( stream ); - stream = args->stream; + stream = args->stream; + stream->memory = memory; + error = FT_Err_Ok; } #endif else + { error = FT_THROW( Invalid_Argument ); + if ( ( args->flags & FT_OPEN_STREAM ) && args->stream ) + FT_Stream_Close( args->stream ); + } - if ( error ) - FT_FREE( stream ); - else - stream->memory = memory; /* just to be certain */ - - *astream = stream; + if ( !error ) + *astream = stream; Exit: return error; @@ -523,7 +535,7 @@ else slot->internal->flags |= FT_GLYPH_OWN_BITMAP; - (void)FT_ALLOC( slot->bitmap.buffer, size ); + FT_MEM_ALLOC( slot->bitmap.buffer, size ); return error; } @@ -535,6 +547,8 @@ ft_glyphslot_free_bitmap( slot ); /* clear all public fields in the glyph slot */ + slot->glyph_index = 0; + FT_ZERO( &slot->metrics ); FT_ZERO( &slot->outline ); @@ -555,6 +569,8 @@ slot->linearHoriAdvance = 0; slot->linearVertAdvance = 0; + slot->advance.x = 0; + slot->advance.y = 0; slot->lsb_delta = 0; slot->rsb_delta = 0; } @@ -734,6 +750,29 @@ } + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( void ) + FT_Get_Transform( FT_Face face, + FT_Matrix* matrix, + FT_Vector* delta ) + { + FT_Face_Internal internal; + + + if ( !face ) + return; + + internal = face->internal; + + if ( matrix ) + *matrix = internal->transform_matrix; + + if ( delta ) + *delta = internal->transform_delta; + } + + static FT_Renderer ft_lookup_glyph_renderer( FT_GlyphSlot slot ); @@ -1056,19 +1095,24 @@ #ifdef FT_DEBUG_LEVEL_TRACE FT_TRACE5(( "FT_Load_Glyph: index %d, flags 0x%x\n", glyph_index, load_flags )); + FT_TRACE5(( " bitmap %dx%d %s, %s (mode %d)\n", + slot->bitmap.width, + slot->bitmap.rows, + slot->outline.points ? + slot->bitmap.buffer ? "rendered" + : "preset" + : + slot->internal->flags & FT_GLYPH_OWN_BITMAP ? "owned" + : "unowned", + pixel_modes[slot->bitmap.pixel_mode], + slot->bitmap.pixel_mode )); + FT_TRACE5(( "\n" )); FT_TRACE5(( " x advance: %f\n", slot->advance.x / 64.0 )); FT_TRACE5(( " y advance: %f\n", slot->advance.y / 64.0 )); FT_TRACE5(( " linear x advance: %f\n", slot->linearHoriAdvance / 65536.0 )); FT_TRACE5(( " linear y advance: %f\n", slot->linearVertAdvance / 65536.0 )); - FT_TRACE5(( "\n" )); - FT_TRACE5(( " bitmap %dx%d, %s (mode %d)\n", - slot->bitmap.width, - slot->bitmap.rows, - pixel_modes[slot->bitmap.pixel_mode], - slot->bitmap.pixel_mode )); - FT_TRACE5(( "\n" )); { FT_Glyph_Metrics* metrics = &slot->metrics; @@ -1782,7 +1826,7 @@ if ( error ) goto Exit; - if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) ) + if ( FT_QALLOC( sfnt_ps, (FT_Long)length ) ) goto Exit; error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length ); @@ -1892,7 +1936,7 @@ goto Exit; } - if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) + if ( FT_QALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) goto Exit; pfb_data[0] = 0x80; @@ -1956,7 +2000,7 @@ { FT_TRACE3(( " Write POST fragment #%d header (4-byte) to buffer" " %p + 0x%08lx\n", - i, pfb_data, pfb_lenpos )); + i, (void*)pfb_data, pfb_lenpos )); if ( pfb_lenpos + 3 > pfb_len + 2 ) goto Exit2; @@ -1971,7 +2015,7 @@ FT_TRACE3(( " Write POST fragment #%d header (6-byte) to buffer" " %p + 0x%08lx\n", - i, pfb_data, pfb_pos )); + i, (void*)pfb_data, pfb_pos )); if ( pfb_pos + 6 > pfb_len + 2 ) goto Exit2; @@ -1994,7 +2038,7 @@ FT_TRACE3(( " Load POST fragment #%d (%ld byte) to buffer" " %p + 0x%08lx\n", - i, rlen, pfb_data, pfb_pos )); + i, rlen, (void*)pfb_data, pfb_pos )); error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); if ( error ) @@ -2092,7 +2136,7 @@ if ( error ) goto Exit; - if ( FT_ALLOC( sfnt_data, rlen ) ) + if ( FT_QALLOC( sfnt_data, rlen ) ) return error; error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, (FT_ULong)rlen ); if ( error ) { @@ -2566,7 +2610,7 @@ FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" )); /* add the face object to its driver's list */ - if ( FT_NEW( node ) ) + if ( FT_QNEW( node ) ) goto Fail; node->data = face; @@ -2681,10 +2725,10 @@ #ifdef FT_DEBUG_LEVEL_TRACE if ( !error && face_index < 0 ) { - FT_TRACE3(( "FT_Open_Face: The font has %ld face%s\n" - " and %ld named instance%s for face %ld\n", + FT_TRACE3(( "FT_Open_Face: The font has %ld face%s\n", face->num_faces, - face->num_faces == 1 ? "" : "s", + face->num_faces == 1 ? "" : "s" )); + FT_TRACE3(( " and %ld named instance%s for face %ld\n", face->style_flags >> 16, ( face->style_flags >> 16 ) == 1 ? "" : "s", -face_index - 1 )); @@ -2851,7 +2895,7 @@ memory = face->memory; /* Allocate new size object and perform basic initialisation */ - if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) ) + if ( FT_ALLOC( size, clazz->size_object_size ) || FT_QNEW( node ) ) goto Exit; size->face = face; @@ -3088,10 +3132,12 @@ } - FT_BASE_DEF( void ) + FT_BASE_DEF( FT_Error ) FT_Request_Metrics( FT_Face face, FT_Size_Request req ) { + FT_Error error = FT_Err_Ok; + FT_Size_Metrics* metrics; @@ -3182,8 +3228,18 @@ scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale ); } - metrics->x_ppem = (FT_UShort)( ( scaled_w + 32 ) >> 6 ); - metrics->y_ppem = (FT_UShort)( ( scaled_h + 32 ) >> 6 ); + scaled_w = ( scaled_w + 32 ) >> 6; + scaled_h = ( scaled_h + 32 ) >> 6; + if ( scaled_w > (FT_Long)FT_USHORT_MAX || + scaled_h > (FT_Long)FT_USHORT_MAX ) + { + FT_ERROR(( "FT_Request_Metrics: Resulting ppem size too large\n" )); + error = FT_ERR( Invalid_Pixel_Size ); + goto Exit; + } + + metrics->x_ppem = (FT_UShort)scaled_w; + metrics->y_ppem = (FT_UShort)scaled_h; ft_recompute_scaled_metrics( face, metrics ); } @@ -3193,6 +3249,9 @@ metrics->x_scale = 1L << 16; metrics->y_scale = 1L << 16; } + + Exit: + return error; } @@ -3256,7 +3315,7 @@ FT_Request_Size( FT_Face face, FT_Size_Request req ) { - FT_Error error = FT_Err_Ok; + FT_Error error; FT_Driver_Class clazz; FT_ULong strike_index; @@ -3292,13 +3351,15 @@ */ error = FT_Match_Size( face, req, 0, &strike_index ); if ( error ) - return error; + goto Exit; return FT_Select_Size( face, (FT_Int)strike_index ); } else { - FT_Request_Metrics( face, req ); + error = FT_Request_Metrics( face, req ); + if ( error ) + goto Exit; FT_TRACE5(( "FT_Request_Size:\n" )); } @@ -3321,6 +3382,7 @@ } #endif + Exit: return error; } @@ -3645,9 +3707,9 @@ FT_CharMap last_charmap = face->charmaps[face->num_charmaps - 1]; - if ( FT_RENEW_ARRAY( face->charmaps, - face->num_charmaps, - face->num_charmaps - 1 ) ) + if ( FT_QRENEW_ARRAY( face->charmaps, + face->num_charmaps, + face->num_charmaps - 1 ) ) return; /* remove it from our list of charmaps */ @@ -3679,7 +3741,7 @@ FT_CharMap charmap, FT_CMap *acmap ) { - FT_Error error = FT_Err_Ok; + FT_Error error; FT_Face face; FT_Memory memory; FT_CMap cmap = NULL; @@ -3704,9 +3766,9 @@ } /* add it to our list of charmaps */ - if ( FT_RENEW_ARRAY( face->charmaps, - face->num_charmaps, - face->num_charmaps + 1 ) ) + if ( FT_QRENEW_ARRAY( face->charmaps, + face->num_charmaps, + face->num_charmaps + 1 ) ) goto Fail; face->charmaps[face->num_charmaps++] = (FT_CharMap)cmap; @@ -4400,7 +4462,7 @@ FT_ListNode node = NULL; - if ( FT_NEW( node ) ) + if ( FT_QNEW( node ) ) goto Exit; { @@ -4412,8 +4474,7 @@ render->glyph_format = clazz->glyph_format; /* allocate raster object if needed */ - if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && - clazz->raster_class->raster_new ) + if ( clazz->raster_class->raster_new ) { error = clazz->raster_class->raster_new( memory, &render->raster ); if ( error ) @@ -4460,8 +4521,7 @@ /* release raster object, if any */ - if ( render->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && - render->raster ) + if ( render->raster ) render->clazz->raster_class->raster_done( render->raster ); /* remove from list */ @@ -4556,9 +4616,6 @@ switch ( slot->format ) { - case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */ - break; - default: if ( slot->internal->load_flags & FT_LOAD_COLOR ) { @@ -4646,7 +4703,7 @@ else renderer = FT_Lookup_Renderer( library, slot->format, &node ); - error = FT_ERR( Unimplemented_Feature ); + error = FT_ERR( Cannot_Render_Glyph ); while ( renderer ) { error = renderer->render( renderer, slot, render_mode, NULL ); @@ -4662,6 +4719,11 @@ /* format. */ renderer = FT_Lookup_Renderer( library, slot->format, &node ); } + + /* it is not an error if we cannot render a bitmap glyph */ + if ( FT_ERR_EQ( error, Cannot_Render_Glyph ) && + slot->format == FT_GLYPH_FORMAT_BITMAP ) + error = FT_Err_Ok; } } @@ -4734,11 +4796,11 @@ /* we use FT_TRACE7 in this block */ if ( !error && - ft_trace_levels[trace_checksum] >= 7 ) + ft_trace_levels[trace_checksum] >= 7 && + slot->bitmap.buffer ) { if ( slot->bitmap.rows < 128U && - slot->bitmap.width < 128U && - slot->bitmap.buffer ) + slot->bitmap.width < 128U ) { int rows = (int)slot->bitmap.rows; int width = (int)slot->bitmap.width; @@ -5149,16 +5211,16 @@ if ( cur == limit ) { - FT_ERROR(( "%s: can't find module `%s'\n", - func_name, module_name )); + FT_TRACE2(( "%s: can't find module `%s'\n", + func_name, module_name )); return FT_THROW( Missing_Module ); } /* check whether we have a service interface */ if ( !cur[0]->clazz->get_interface ) { - FT_ERROR(( "%s: module `%s' doesn't support properties\n", - func_name, module_name )); + FT_TRACE2(( "%s: module `%s' doesn't support properties\n", + func_name, module_name )); return FT_THROW( Unimplemented_Feature ); } @@ -5167,8 +5229,8 @@ FT_SERVICE_ID_PROPERTIES ); if ( !interface ) { - FT_ERROR(( "%s: module `%s' doesn't support properties\n", - func_name, module_name )); + FT_TRACE2(( "%s: module `%s' doesn't support properties\n", + func_name, module_name )); return FT_THROW( Unimplemented_Feature ); } @@ -5181,8 +5243,8 @@ if ( missing_func ) { - FT_ERROR(( "%s: property service of module `%s' is broken\n", - func_name, module_name )); + FT_TRACE2(( "%s: property service of module `%s' is broken\n", + func_name, module_name )); return FT_THROW( Unimplemented_Feature ); } @@ -5292,10 +5354,12 @@ if ( !memory || !alibrary ) return FT_THROW( Invalid_Argument ); +#ifndef FT_DEBUG_LOGGING #ifdef FT_DEBUG_LEVEL_ERROR /* init debugging support */ ft_debug_init(); -#endif +#endif /* FT_DEBUG_LEVEL_ERROR */ +#endif /* !FT_DEBUG_LOGGING */ /* first of all, allocate the library object */ if ( FT_NEW( library ) ) @@ -5567,4 +5631,145 @@ } + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Get_Color_Glyph_Paint( FT_Face face, + FT_UInt base_glyph, + FT_Color_Root_Transform root_transform, + FT_OpaquePaint* paint ) + { + TT_Face ttface; + SFNT_Service sfnt; + + + if ( !face || !paint ) + return 0; + + if ( !FT_IS_SFNT( face ) ) + return 0; + + ttface = (TT_Face)face; + sfnt = (SFNT_Service)ttface->sfnt; + + if ( sfnt->get_colr_layer ) + return sfnt->get_colr_glyph_paint( ttface, + base_glyph, + root_transform, + paint ); + else + return 0; + } + + + /* documentation is in ftcolor.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Get_Color_Glyph_ClipBox( FT_Face face, + FT_UInt base_glyph, + FT_ClipBox* clip_box ) + { + TT_Face ttface; + SFNT_Service sfnt; + + + if ( !face || !clip_box ) + return 0; + + if ( !FT_IS_SFNT( face ) ) + return 0; + + ttface = (TT_Face)face; + sfnt = (SFNT_Service)ttface->sfnt; + + if ( sfnt->get_color_glyph_clipbox ) + return sfnt->get_color_glyph_clipbox( ttface, + base_glyph, + clip_box ); + else + return 0; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Get_Paint_Layers( FT_Face face, + FT_LayerIterator* layer_iterator, + FT_OpaquePaint* paint ) + { + TT_Face ttface; + SFNT_Service sfnt; + + + if ( !face || !paint || !layer_iterator ) + return 0; + + if ( !FT_IS_SFNT( face ) ) + return 0; + + ttface = (TT_Face)face; + sfnt = (SFNT_Service)ttface->sfnt; + + if ( sfnt->get_paint_layers ) + return sfnt->get_paint_layers( ttface, layer_iterator, paint ); + else + return 0; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Get_Paint( FT_Face face, + FT_OpaquePaint opaque_paint, + FT_COLR_Paint* paint ) + { + TT_Face ttface; + SFNT_Service sfnt; + + + if ( !face || !paint || !paint ) + return 0; + + if ( !FT_IS_SFNT( face ) ) + return 0; + + ttface = (TT_Face)face; + sfnt = (SFNT_Service)ttface->sfnt; + + if ( sfnt->get_paint ) + return sfnt->get_paint( ttface, opaque_paint, paint ); + else + return 0; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Get_Colorline_Stops ( FT_Face face, + FT_ColorStop * color_stop, + FT_ColorStopIterator *iterator ) + { + TT_Face ttface; + SFNT_Service sfnt; + + + if ( !face || !color_stop || !iterator ) + return 0; + + if ( !FT_IS_SFNT( face ) ) + return 0; + + ttface = (TT_Face)face; + sfnt = (SFNT_Service)ttface->sfnt; + + if ( sfnt->get_colorline_stops ) + return sfnt->get_colorline_stops ( ttface, color_stop, iterator ); + else + return 0; + } + + /* END */ diff --git a/thirdparty/freetype/src/base/ftotval.c b/thirdparty/freetype/src/base/ftotval.c index 90a5dd617c..0f748d006c 100644 --- a/thirdparty/freetype/src/base/ftotval.c +++ b/thirdparty/freetype/src/base/ftotval.c @@ -4,7 +4,7 @@ * * FreeType API for validating OpenType tables (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftoutln.c b/thirdparty/freetype/src/base/ftoutln.c index 311f098e3a..98c6ca16e6 100644 --- a/thirdparty/freetype/src/base/ftoutln.c +++ b/thirdparty/freetype/src/base/ftoutln.c @@ -4,7 +4,7 @@ * * FreeType outline management (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftpatent.c b/thirdparty/freetype/src/base/ftpatent.c index a02c636a65..cd192d33bd 100644 --- a/thirdparty/freetype/src/base/ftpatent.c +++ b/thirdparty/freetype/src/base/ftpatent.c @@ -5,7 +5,7 @@ * FreeType API for checking patented TrueType bytecode instructions * (body). Obsolete, retained for backward compatibility. * - * Copyright (C) 2007-2020 by + * Copyright (C) 2007-2021 by * David Turner. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftpfr.c b/thirdparty/freetype/src/base/ftpfr.c index c656fcd9b9..5afd5a183f 100644 --- a/thirdparty/freetype/src/base/ftpfr.c +++ b/thirdparty/freetype/src/base/ftpfr.c @@ -4,7 +4,7 @@ * * FreeType API for accessing PFR-specific data (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftpsprop.c b/thirdparty/freetype/src/base/ftpsprop.c index 8c29f50f6b..3655ae97ec 100644 --- a/thirdparty/freetype/src/base/ftpsprop.c +++ b/thirdparty/freetype/src/base/ftpsprop.c @@ -5,7 +5,7 @@ * Get and set properties of PostScript drivers (body). * See `ftdriver.h' for available properties. * - * Copyright (C) 2017-2020 by + * Copyright (C) 2017-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -220,7 +220,7 @@ return error; } - FT_TRACE0(( "ps_property_set: missing property `%s'\n", + FT_TRACE2(( "ps_property_set: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); } @@ -275,7 +275,7 @@ return error; } - FT_TRACE0(( "ps_property_get: missing property `%s'\n", + FT_TRACE2(( "ps_property_get: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); } diff --git a/thirdparty/freetype/src/base/ftrfork.c b/thirdparty/freetype/src/base/ftrfork.c index f989be47f4..cb7e94ddb0 100644 --- a/thirdparty/freetype/src/base/ftrfork.c +++ b/thirdparty/freetype/src/base/ftrfork.c @@ -4,7 +4,7 @@ * * Embedded resource forks accessor (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * Masatake YAMATO and Redhat K.K. * * FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are @@ -167,16 +167,11 @@ } - static int - ft_raccess_sort_ref_by_id( FT_RFork_Ref* a, - FT_RFork_Ref* b ) + FT_COMPARE_DEF( int ) + ft_raccess_sort_ref_by_id( const void* a, + const void* b ) { - if ( a->res_id < b->res_id ) - return -1; - else if ( a->res_id > b->res_id ) - return 1; - else - return 0; + return ( (FT_RFork_Ref*)a )->res_id - ( (FT_RFork_Ref*)b )->res_id; } @@ -256,7 +251,7 @@ if ( error ) return error; - if ( FT_NEW_ARRAY( ref, *count ) ) + if ( FT_QNEW_ARRAY( ref, *count ) ) return error; for ( j = 0; j < *count; j++ ) @@ -294,8 +289,7 @@ ft_qsort( ref, (size_t)*count, sizeof ( FT_RFork_Ref ), - ( int(*)(const void*, - const void*) )ft_raccess_sort_ref_by_id ); + ft_raccess_sort_ref_by_id ); FT_TRACE3(( " -- sort resources by their ids --\n" )); @@ -305,7 +299,7 @@ j, ref[j].res_id, ref[j].offset )); } - if ( FT_NEW_ARRAY( offsets_internal, *count ) ) + if ( FT_QNEW_ARRAY( offsets_internal, *count ) ) goto Exit; /* XXX: duplicated reference ID, @@ -608,7 +602,7 @@ if ( base_file_len + 6 > FT_INT_MAX ) return FT_THROW( Array_Too_Large ); - if ( FT_ALLOC( newpath, base_file_len + 6 ) ) + if ( FT_QALLOC( newpath, base_file_len + 6 ) ) return error; FT_MEM_COPY( newpath, base_file_name, base_file_len ); @@ -644,7 +638,7 @@ if ( base_file_len + 18 > FT_INT_MAX ) return FT_THROW( Array_Too_Large ); - if ( FT_ALLOC( newpath, base_file_len + 18 ) ) + if ( FT_QALLOC( newpath, base_file_len + 18 ) ) return error; FT_MEM_COPY( newpath, base_file_name, base_file_len ); @@ -880,7 +874,7 @@ new_length = ft_strlen( original_name ) + ft_strlen( insertion ); - if ( FT_ALLOC( new_name, new_length + 1 ) ) + if ( FT_QALLOC( new_name, new_length + 1 ) ) return NULL; tmp = ft_strrchr( original_name, '/' ); diff --git a/thirdparty/freetype/src/base/ftsnames.c b/thirdparty/freetype/src/base/ftsnames.c index 8507f28d36..44dba66638 100644 --- a/thirdparty/freetype/src/base/ftsnames.c +++ b/thirdparty/freetype/src/base/ftsnames.c @@ -7,7 +7,7 @@ * * This is _not_ used to retrieve glyph names! * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -65,7 +65,7 @@ FT_Stream stream = face->stream; - if ( FT_NEW_ARRAY ( entry->string, entry->stringLength ) || + if ( FT_QNEW_ARRAY ( entry->string, entry->stringLength ) || FT_STREAM_SEEK( entry->stringOffset ) || FT_STREAM_READ( entry->string, entry->stringLength ) ) { @@ -121,7 +121,7 @@ FT_Stream stream = face->stream; - if ( FT_NEW_ARRAY ( entry->string, entry->stringLength ) || + if ( FT_QNEW_ARRAY ( entry->string, entry->stringLength ) || FT_STREAM_SEEK( entry->stringOffset ) || FT_STREAM_READ( entry->string, entry->stringLength ) ) { diff --git a/thirdparty/freetype/src/base/ftstream.c b/thirdparty/freetype/src/base/ftstream.c index d940254d8b..5992998ba3 100644 --- a/thirdparty/freetype/src/base/ftstream.c +++ b/thirdparty/freetype/src/base/ftstream.c @@ -4,7 +4,7 @@ * * I/O stream support (body). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -61,7 +61,7 @@ if ( stream->read ) { - if ( stream->read( stream, pos, 0, 0 ) ) + if ( stream->read( stream, pos, NULL, 0 ) ) { FT_ERROR(( "FT_Stream_Seek:" " invalid i/o; pos = 0x%lx, size = 0x%lx\n", @@ -347,17 +347,17 @@ } - FT_BASE_DEF( FT_Char ) - FT_Stream_GetChar( FT_Stream stream ) + FT_BASE_DEF( FT_Byte ) + FT_Stream_GetByte( FT_Stream stream ) { - FT_Char result; + FT_Byte result; FT_ASSERT( stream && stream->cursor ); result = 0; if ( stream->cursor < stream->limit ) - result = (FT_Char)*stream->cursor++; + result = *stream->cursor++; return result; } @@ -455,8 +455,8 @@ } - FT_BASE_DEF( FT_Char ) - FT_Stream_ReadChar( FT_Stream stream, + FT_BASE_DEF( FT_Byte ) + FT_Stream_ReadByte( FT_Stream stream, FT_Error* error ) { FT_Byte result = 0; @@ -464,31 +464,32 @@ FT_ASSERT( stream ); - *error = FT_Err_Ok; - - if ( stream->read ) + if ( stream->pos < stream->size ) { - if ( stream->read( stream, stream->pos, &result, 1L ) != 1L ) - goto Fail; - } - else - { - if ( stream->pos < stream->size ) - result = stream->base[stream->pos]; + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, &result, 1L ) != 1L ) + goto Fail; + } else - goto Fail; + result = stream->base[stream->pos]; } + else + goto Fail; + stream->pos++; - return (FT_Char)result; + *error = FT_Err_Ok; + + return result; Fail: *error = FT_THROW( Invalid_Stream_Operation ); - FT_ERROR(( "FT_Stream_ReadChar:" + FT_ERROR(( "FT_Stream_ReadByte:" " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); - return 0; + return result; } @@ -497,14 +498,12 @@ FT_Error* error ) { FT_Byte reads[2]; - FT_Byte* p = 0; + FT_Byte* p; FT_UShort result = 0; FT_ASSERT( stream ); - *error = FT_Err_Ok; - if ( stream->pos + 1 < stream->size ) { if ( stream->read ) @@ -525,6 +524,8 @@ stream->pos += 2; + *error = FT_Err_Ok; + return result; Fail: @@ -533,7 +534,7 @@ " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); - return 0; + return result; } @@ -542,14 +543,12 @@ FT_Error* error ) { FT_Byte reads[2]; - FT_Byte* p = 0; + FT_Byte* p; FT_UShort result = 0; FT_ASSERT( stream ); - *error = FT_Err_Ok; - if ( stream->pos + 1 < stream->size ) { if ( stream->read ) @@ -570,6 +569,8 @@ stream->pos += 2; + *error = FT_Err_Ok; + return result; Fail: @@ -578,7 +579,7 @@ " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); - return 0; + return result; } @@ -587,14 +588,12 @@ FT_Error* error ) { FT_Byte reads[3]; - FT_Byte* p = 0; + FT_Byte* p; FT_ULong result = 0; FT_ASSERT( stream ); - *error = FT_Err_Ok; - if ( stream->pos + 2 < stream->size ) { if ( stream->read ) @@ -615,6 +614,8 @@ stream->pos += 3; + *error = FT_Err_Ok; + return result; Fail: @@ -623,7 +624,7 @@ " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); - return 0; + return result; } @@ -632,14 +633,12 @@ FT_Error* error ) { FT_Byte reads[4]; - FT_Byte* p = 0; + FT_Byte* p; FT_ULong result = 0; FT_ASSERT( stream ); - *error = FT_Err_Ok; - if ( stream->pos + 3 < stream->size ) { if ( stream->read ) @@ -660,6 +659,8 @@ stream->pos += 4; + *error = FT_Err_Ok; + return result; Fail: @@ -668,7 +669,7 @@ " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); - return 0; + return result; } @@ -677,14 +678,12 @@ FT_Error* error ) { FT_Byte reads[4]; - FT_Byte* p = 0; + FT_Byte* p; FT_ULong result = 0; FT_ASSERT( stream ); - *error = FT_Err_Ok; - if ( stream->pos + 3 < stream->size ) { if ( stream->read ) @@ -705,6 +704,8 @@ stream->pos += 4; + *error = FT_Err_Ok; + return result; Fail: @@ -713,7 +714,7 @@ " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); - return 0; + return result; } diff --git a/thirdparty/freetype/src/base/ftstroke.c b/thirdparty/freetype/src/base/ftstroke.c index 56f98e1d92..37e9649411 100644 --- a/thirdparty/freetype/src/base/ftstroke.c +++ b/thirdparty/freetype/src/base/ftstroke.c @@ -4,7 +4,7 @@ * * FreeType path stroker (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -974,7 +974,8 @@ FT_StrokeBorder border = stroker->borders + side; FT_Angle phi, theta, rotate; FT_Fixed length; - FT_Vector sigma, delta; + FT_Vector sigma = { 0, 0 }; + FT_Vector delta; FT_Error error = FT_Err_Ok; FT_Bool intersect; /* use intersection of lines? */ @@ -1048,7 +1049,7 @@ { /* this is a mitered (pointed) or beveled (truncated) corner */ FT_Fixed radius = stroker->radius; - FT_Vector sigma; + FT_Vector sigma = { 0, 0 }; FT_Angle theta = 0, phi = 0; FT_Bool bevel, fixed_bevel; @@ -1528,7 +1529,8 @@ stroker->angle_in = angle_out; } - stroker->center = *to; + stroker->center = *to; + stroker->line_length = 0; Exit: return error; @@ -1744,7 +1746,8 @@ stroker->angle_in = angle_out; } - stroker->center = *to; + stroker->center = *to; + stroker->line_length = 0; Exit: return error; @@ -1897,13 +1900,9 @@ } else { - FT_Angle turn; - FT_Int inside_side; - - /* close the path if needed */ - if ( stroker->center.x != stroker->subpath_start.x || - stroker->center.y != stroker->subpath_start.y ) + if ( !FT_IS_SMALL( stroker->center.x - stroker->subpath_start.x ) || + !FT_IS_SMALL( stroker->center.y - stroker->subpath_start.y ) ) { error = FT_Stroker_LineTo( stroker, &stroker->subpath_start ); if ( error ) @@ -1912,29 +1911,11 @@ /* process the corner */ stroker->angle_out = stroker->subpath_angle; - turn = FT_Angle_Diff( stroker->angle_in, - stroker->angle_out ); - - /* no specific corner processing is required if the turn is 0 */ - if ( turn != 0 ) - { - /* when we turn to the right, the inside side is 0 */ - /* otherwise, the inside side is 1 */ - inside_side = ( turn < 0 ); - error = ft_stroker_inside( stroker, - inside_side, - stroker->subpath_line_length ); - if ( error ) - goto Exit; - - /* process the outside side */ - error = ft_stroker_outside( stroker, - !inside_side, - stroker->subpath_line_length ); - if ( error ) - goto Exit; - } + error = ft_stroker_process_corner( stroker, + stroker->subpath_line_length ); + if ( error ) + goto Exit; /* then end our two subpaths */ ft_stroke_border_close( stroker->borders + 0, FALSE ); diff --git a/thirdparty/freetype/src/base/ftsynth.c b/thirdparty/freetype/src/base/ftsynth.c index a9119e2b24..73565b1307 100644 --- a/thirdparty/freetype/src/base/ftsynth.c +++ b/thirdparty/freetype/src/base/ftsynth.c @@ -4,7 +4,7 @@ * * FreeType synthesizing code for emboldening and slanting (body). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftsystem.c b/thirdparty/freetype/src/base/ftsystem.c index 3013cbda9d..9beb7e245d 100644 --- a/thirdparty/freetype/src/base/ftsystem.c +++ b/thirdparty/freetype/src/base/ftsystem.c @@ -4,7 +4,7 @@ * * ANSI-specific FreeType low-level system interface (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -275,7 +275,7 @@ stream->close = ft_ansi_stream_close; FT_TRACE1(( "FT_Stream_Open:" )); - FT_TRACE1(( " opened `%s' (%d bytes) successfully\n", + FT_TRACE1(( " opened `%s' (%ld bytes) successfully\n", filepathname, stream->size )); return FT_Err_Ok; diff --git a/thirdparty/freetype/src/base/fttrigon.c b/thirdparty/freetype/src/base/fttrigon.c index c6f027cf61..0ca6d7810a 100644 --- a/thirdparty/freetype/src/base/fttrigon.c +++ b/thirdparty/freetype/src/base/fttrigon.c @@ -4,7 +4,7 @@ * * FreeType trigonometric functions (body). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -53,7 +53,7 @@ }; -#ifdef FT_LONG64 +#ifdef FT_INT64 /* multiply a given value by the CORDIC shrink factor */ static FT_Fixed @@ -76,7 +76,7 @@ return s < 0 ? -val : val; } -#else /* !FT_LONG64 */ +#else /* !FT_INT64 */ /* multiply a given value by the CORDIC shrink factor */ static FT_Fixed @@ -125,7 +125,7 @@ return s < 0 ? -val : val; } -#endif /* !FT_LONG64 */ +#endif /* !FT_INT64 */ /* undefined and never called for zero vector */ diff --git a/thirdparty/freetype/src/base/fttype1.c b/thirdparty/freetype/src/base/fttype1.c index be60ed6ec5..0d0afbcef0 100644 --- a/thirdparty/freetype/src/base/fttype1.c +++ b/thirdparty/freetype/src/base/fttype1.c @@ -4,7 +4,7 @@ * * FreeType utility file for PS names support (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftutil.c b/thirdparty/freetype/src/base/ftutil.c index d90cfbcd26..3142faee98 100644 --- a/thirdparty/freetype/src/base/ftutil.c +++ b/thirdparty/freetype/src/base/ftutil.c @@ -4,7 +4,7 @@ * * FreeType utility file for memory and list management (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/ftver.rc b/thirdparty/freetype/src/base/ftver.rc index 0b92e9b899..a3d05b3780 100644 --- a/thirdparty/freetype/src/base/ftver.rc +++ b/thirdparty/freetype/src/base/ftver.rc @@ -4,7 +4,7 @@ /* */ /* FreeType VERSIONINFO resource for Windows DLLs. */ /* */ -/* Copyright (C) 2018-2020 by */ +/* Copyright (C) 2018-2021 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,8 +18,8 @@ #include<windows.h> -#define FT_VERSION 2,10,4,0 -#define FT_VERSION_STR "2.10.4" +#define FT_VERSION 2,11,1,0 +#define FT_VERSION_STR "2.11.1" VS_VERSION_INFO VERSIONINFO FILEVERSION FT_VERSION @@ -45,7 +45,7 @@ BEGIN VALUE "FileVersion", FT_VERSION_STR VALUE "ProductName", "FreeType" VALUE "ProductVersion", FT_VERSION_STR - VALUE "LegalCopyright", "\251 2000-2020 The FreeType Project www.freetype.org. All rights reserved." + VALUE "LegalCopyright", "\251 2000-2021 The FreeType Project www.freetype.org. All rights reserved." VALUE "InternalName", "freetype" VALUE "OriginalFilename", FT_FILENAME END diff --git a/thirdparty/freetype/src/base/ftwinfnt.c b/thirdparty/freetype/src/base/ftwinfnt.c index 699dc3d700..98f197afdc 100644 --- a/thirdparty/freetype/src/base/ftwinfnt.c +++ b/thirdparty/freetype/src/base/ftwinfnt.c @@ -4,7 +4,7 @@ * * FreeType API for accessing Windows FNT specific info (body). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/base/rules.mk b/thirdparty/freetype/src/base/rules.mk deleted file mode 100644 index 411c4c821f..0000000000 --- a/thirdparty/freetype/src/base/rules.mk +++ /dev/null @@ -1,108 +0,0 @@ -# -# FreeType 2 base layer configuration rules -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# It sets the following variables which are used by the master Makefile -# after the call: -# -# BASE_OBJ_S: The single-object base layer. -# BASE_OBJ_M: A list of all objects for a multiple-objects build. -# BASE_EXT_OBJ: A list of base layer extensions, i.e., components found -# in `src/base' which are not compiled within the base -# layer proper. - - -BASE_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(BASE_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# Base layer sources -# -# ftsystem, ftinit, and ftdebug are handled by freetype.mk -# -# All files listed here should be included in `ftbase.c' (for a `single' -# build). -# -BASE_SRC := $(BASE_DIR)/ftadvanc.c \ - $(BASE_DIR)/ftcalc.c \ - $(BASE_DIR)/ftcolor.c \ - $(BASE_DIR)/ftdbgmem.c \ - $(BASE_DIR)/fterrors.c \ - $(BASE_DIR)/ftfntfmt.c \ - $(BASE_DIR)/ftgloadr.c \ - $(BASE_DIR)/fthash.c \ - $(BASE_DIR)/ftlcdfil.c \ - $(BASE_DIR)/ftobjs.c \ - $(BASE_DIR)/ftoutln.c \ - $(BASE_DIR)/ftpsprop.c \ - $(BASE_DIR)/ftrfork.c \ - $(BASE_DIR)/ftsnames.c \ - $(BASE_DIR)/ftstream.c \ - $(BASE_DIR)/fttrigon.c \ - $(BASE_DIR)/ftutil.c - - -ifneq ($(ftmac_c),) - BASE_SRC += $(BASE_DIR)/$(ftmac_c) -endif - -# for simplicity, we also handle `md5.c' (which gets included by `ftobjs.h') -BASE_H := $(BASE_DIR)/ftbase.h \ - $(BASE_DIR)/md5.c \ - $(BASE_DIR)/md5.h - -# Base layer `extensions' sources -# -# An extension is added to the library file as a separate object. It is -# then linked to the final executable only if one of its symbols is used by -# the application. -# -BASE_EXT_SRC := $(patsubst %,$(BASE_DIR)/%,$(BASE_EXTENSIONS)) - -# Default extensions objects -# -BASE_EXT_OBJ := $(BASE_EXT_SRC:$(BASE_DIR)/%.c=$(OBJ_DIR)/%.$O) - - -# Base layer object(s) -# -# BASE_OBJ_M is used during `multi' builds (each base source file compiles -# to a single object file). -# -# BASE_OBJ_S is used during `single' builds (the whole base layer is -# compiled as a single object file using ftbase.c). -# -BASE_OBJ_M := $(BASE_SRC:$(BASE_DIR)/%.c=$(OBJ_DIR)/%.$O) -BASE_OBJ_S := $(OBJ_DIR)/ftbase.$O - -# Base layer root source file for single build -# -BASE_SRC_S := $(BASE_DIR)/ftbase.c - - -# Base layer - single object build -# -$(BASE_OBJ_S): $(BASE_SRC_S) $(BASE_SRC) $(FREETYPE_H) $(BASE_H) - $(BASE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(BASE_SRC_S)) - - -# Multiple objects build + extensions -# -$(OBJ_DIR)/%.$O: $(BASE_DIR)/%.c $(FREETYPE_H) $(BASE_H) - $(BASE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# EOF diff --git a/thirdparty/freetype/src/bdf/bdfdrivr.c b/thirdparty/freetype/src/bdf/bdfdrivr.c index d29188b97b..eb73a7cf93 100644 --- a/thirdparty/freetype/src/bdf/bdfdrivr.c +++ b/thirdparty/freetype/src/bdf/bdfdrivr.c @@ -276,7 +276,7 @@ THE SOFTWARE. char* s; - if ( FT_ALLOC( face->style_name, len ) ) + if ( FT_QALLOC( face->style_name, len ) ) return error; s = face->style_name; @@ -442,7 +442,7 @@ THE SOFTWARE. bdfface->num_glyphs = (FT_Long)( font->glyphs_size + 1 ); bdfface->num_fixed_sizes = 1; - if ( FT_NEW_ARRAY( bdfface->available_sizes, 1 ) ) + if ( FT_NEW( bdfface->available_sizes ) ) goto Exit; { @@ -451,8 +451,6 @@ THE SOFTWARE. long value; - FT_ZERO( bsize ); - /* sanity checks */ if ( font->font_ascent > 0x7FFF || font->font_ascent < -0x7FFF ) { @@ -489,7 +487,7 @@ THE SOFTWARE. else { /* this is a heuristical value */ - bsize->width = (FT_Short)FT_MulDiv( bsize->height, 2, 3 ); + bsize->width = ( bsize->height * 2 + 1 ) / 3; } prop = bdf_get_font_property( font, "POINT_SIZE" ); @@ -608,7 +606,7 @@ THE SOFTWARE. unsigned long n; - if ( FT_NEW_ARRAY( face->en_table, font->glyphs_size ) ) + if ( FT_QNEW_ARRAY( face->en_table, font->glyphs_size ) ) goto Exit; face->default_glyph = 0; diff --git a/thirdparty/freetype/src/bdf/bdflib.c b/thirdparty/freetype/src/bdf/bdflib.c index a4ddb9a1d9..b65c8a2f3e 100644 --- a/thirdparty/freetype/src/bdf/bdflib.c +++ b/thirdparty/freetype/src/bdf/bdflib.c @@ -170,7 +170,7 @@ /* An auxiliary macro to parse properties, to be used in conditionals. */ /* It behaves like `strncmp' but also tests the following character */ - /* whether it is a whitespace or NULL. */ + /* whether it is a whitespace or null. */ /* `property' is a constant string of length `n' to compare with. */ #define _bdf_strncmp( name, property, n ) \ ( ft_strncmp( name, property, n ) || \ @@ -185,12 +185,12 @@ "Added `FONT_ASCENT %hd'.\n" #define ACMSG2 "FONT_DESCENT property missing. " \ "Added `FONT_DESCENT %hd'.\n" -#define ACMSG3 "Font width != actual width. Old: %hd New: %hd.\n" +#define ACMSG3 "Font width != actual width. Old: %d New: %d.\n" #define ACMSG4 "Font left bearing != actual left bearing. " \ "Old: %hd New: %hd.\n" #define ACMSG5 "Font ascent != actual ascent. Old: %hd New: %hd.\n" -#define ACMSG6 "Font descent != actual descent. Old: %hd New: %hd.\n" -#define ACMSG7 "Font height != actual height. Old: %hd New: %hd.\n" +#define ACMSG6 "Font descent != actual descent. Old: %d New: %d.\n" +#define ACMSG7 "Font height != actual height. Old: %d New: %d.\n" #define ACMSG8 "Glyph scalable width (SWIDTH) adjustments made.\n" #define ACMSG9 "SWIDTH field missing at line %ld. Set automatically.\n" #define ACMSG10 "DWIDTH field missing at line %ld. Set to glyph width.\n" @@ -328,7 +328,7 @@ else if ( newsize < oldsize || newsize > bigsize ) newsize = bigsize; - if ( FT_RENEW_ARRAY( list->field, oldsize, newsize ) ) + if ( FT_QRENEW_ARRAY( list->field, oldsize, newsize ) ) goto Exit; list->size = newsize; @@ -346,7 +346,7 @@ unsigned long i, u; - if ( list == 0 || list->used == 0 || n == 0 ) + if ( list == NULL || list->used == 0 || n == 0 ) return; if ( n >= list->used ) @@ -377,7 +377,7 @@ *alen = 0; - if ( list == 0 || list->used == 0 ) + if ( list == NULL || list->used == 0 ) return 0; dp = list->field[0]; @@ -436,7 +436,7 @@ /* In the original code, if the `separators' parameter is NULL or */ /* empty, the list is split into individual bytes. We don't need */ /* this, so an error is signaled. */ - if ( separators == 0 || *separators == 0 ) + if ( separators == NULL || *separators == 0 ) { error = FT_THROW( Invalid_Argument ); goto Exit; @@ -504,7 +504,7 @@ if ( final_empty ) list->field[list->used++] = (char*)empty; - list->field[list->used] = 0; + list->field[list->used] = NULL; Exit: return error; @@ -529,7 +529,7 @@ FT_Error error = FT_Err_Ok; - if ( callback == 0 ) + if ( callback == NULL ) { error = FT_THROW( Invalid_Argument ); goto Exit; @@ -538,7 +538,7 @@ /* initial size and allocation of the input buffer */ buf_size = 1024; - if ( FT_NEW_ARRAY( buf, buf_size ) ) + if ( FT_QALLOC( buf, buf_size ) ) goto Exit; cb = callback; @@ -581,8 +581,14 @@ /* or even resizing it */ if ( end >= avail ) { - if ( bytes == 0 ) /* last line in file doesn't end in \r or \n */ - break; /* ignore it then exit */ + if ( bytes == 0 ) + { + /* last line in file doesn't end in \r or \n; */ + /* ignore it then exit */ + if ( lineno == 1 ) + error = FT_THROW( Missing_Startfont_Field ); + break; + } if ( start == 0 ) { @@ -593,13 +599,18 @@ if ( buf_size >= 65536UL ) /* limit ourselves to 64KByte */ { - FT_ERROR(( "_bdf_readstream: " ERRMSG6, lineno )); - error = FT_THROW( Invalid_Argument ); + if ( lineno == 1 ) + error = FT_THROW( Missing_Startfont_Field ); + else + { + FT_ERROR(( "_bdf_readstream: " ERRMSG6, lineno )); + error = FT_THROW( Invalid_Argument ); + } goto Exit; } new_size = buf_size * 2; - if ( FT_RENEW_ARRAY( buf, buf_size, new_size ) ) + if ( FT_QREALLOC( buf, buf_size, new_size ) ) goto Exit; cursor = (ptrdiff_t)buf_size; @@ -697,7 +708,7 @@ unsigned long v; - if ( s == 0 || *s == 0 ) + if ( s == NULL || *s == 0 ) return 0; for ( v = 0; sbitset( ddigits, *s ); s++ ) @@ -722,7 +733,7 @@ long v, neg; - if ( s == 0 || *s == 0 ) + if ( s == NULL || *s == 0 ) return 0; /* Check for a minus sign. */ @@ -755,7 +766,7 @@ unsigned short v; - if ( s == 0 || *s == 0 ) + if ( s == NULL || *s == 0 ) return 0; for ( v = 0; sbitset( ddigits, *s ); s++ ) @@ -780,7 +791,7 @@ short v, neg; - if ( s == 0 || *s == 0 ) + if ( s == NULL || *s == 0 ) return 0; /* Check for a minus. */ @@ -807,7 +818,7 @@ /* Routine to compare two glyphs by encoding so they can be sorted. */ - static int + FT_COMPARE_DEF( int ) by_encoding( const void* a, const void* b ) { @@ -844,25 +855,25 @@ if ( ft_hash_str_lookup( name, &(font->proptbl) ) ) goto Exit; - if ( FT_RENEW_ARRAY( font->user_props, - font->nuser_props, - font->nuser_props + 1 ) ) + if ( FT_QRENEW_ARRAY( font->user_props, + font->nuser_props, + font->nuser_props + 1 ) ) goto Exit; p = font->user_props + font->nuser_props; - FT_ZERO( p ); n = ft_strlen( name ) + 1; - if ( n > FT_ULONG_MAX ) + if ( n > FT_LONG_MAX ) return FT_THROW( Invalid_Argument ); - if ( FT_NEW_ARRAY( p->name, n ) ) + if ( FT_QALLOC( p->name, n ) ) goto Exit; FT_MEM_COPY( (char *)p->name, name, n ); - p->format = format; - p->builtin = 0; + p->format = format; + p->builtin = 0; + p->value.atom = NULL; /* nothing is ever stored here */ n = _num_bdf_properties + font->nuser_props; @@ -884,7 +895,7 @@ size_t* propid; - if ( name == 0 || *name == 0 ) + if ( name == NULL || *name == 0 ) return 0; if ( ( propid = ft_hash_str_lookup( name, &(font->proptbl) ) ) == NULL ) @@ -942,15 +953,15 @@ FT_Error error = FT_Err_Ok; - if ( FT_RENEW_ARRAY( font->comments, - font->comments_len, - font->comments_len + len + 1 ) ) + if ( FT_QRENEW_ARRAY( font->comments, + font->comments_len, + font->comments_len + len + 1 ) ) goto Exit; cp = font->comments + font->comments_len; FT_MEM_COPY( cp, comment, len ); - cp[len] = '\n'; + cp[len] = '\0'; font->comments_len += len + 1; @@ -975,7 +986,7 @@ FT_UNUSED( lineno ); /* only used in debug mode */ - if ( font == 0 || font->name == 0 || font->name[0] == 0 ) + if ( font == NULL || font->name == NULL || font->name[0] == 0 ) { error = FT_THROW( Invalid_Argument ); goto Exit; @@ -1159,21 +1170,12 @@ /* Allocate another property if this is overflowing. */ if ( font->props_used == font->props_size ) { - if ( font->props_size == 0 ) - { - if ( FT_NEW_ARRAY( font->props, 1 ) ) - goto Exit; - } - else - { - if ( FT_RENEW_ARRAY( font->props, - font->props_size, - font->props_size + 1 ) ) - goto Exit; - } + if ( FT_QRENEW_ARRAY( font->props, + font->props_size, + font->props_size + 1 ) ) + goto Exit; fp = font->props + font->props_size; - FT_ZERO( fp ); font->props_size++; } @@ -1191,8 +1193,8 @@ switch ( prop->format ) { case BDF_ATOM: - fp->value.atom = 0; - if ( value != 0 && value[0] ) + fp->value.atom = NULL; + if ( value && value[0] ) { if ( FT_STRDUP( fp->value.atom, value ) ) goto Exit; @@ -1314,15 +1316,18 @@ /* Check for a comment. */ if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 ) { - linelen -= 7; - - s = line + 7; - if ( *s != 0 ) + if ( p->opts->keep_comments ) { - s++; - linelen--; + linelen -= 7; + + s = line + 7; + if ( *s != 0 ) + { + s++; + linelen--; + } + error = _bdf_add_comment( p->font, s, linelen ); } - error = _bdf_add_comment( p->font, s, linelen ); goto Exit; } @@ -1438,7 +1443,7 @@ goto Exit; } - if ( FT_NEW_ARRAY( p->glyph_name, slen + 1 ) ) + if ( FT_QALLOC( p->glyph_name, slen + 1 ) ) goto Exit; FT_MEM_COPY( p->glyph_name, s, slen + 1 ); @@ -1506,7 +1511,7 @@ { /* Unencoded glyph. Check whether it should */ /* be added or not. */ - if ( p->opts->keep_unencoded != 0 ) + if ( p->opts->keep_unencoded ) { /* Allocate the next unencoded glyph. */ if ( font->unencoded_used == font->unencoded_size ) @@ -1619,20 +1624,20 @@ if ( error ) goto Exit; - glyph->swidth = (unsigned short)_bdf_atoul( p->list.field[1] ); + glyph->swidth = _bdf_atous( p->list.field[1] ); p->flags |= BDF_SWIDTH_; goto Exit; } - /* Expect the DWIDTH (scalable width) field next. */ + /* Expect the DWIDTH (device width) field next. */ if ( _bdf_strncmp( line, "DWIDTH", 6 ) == 0 ) { error = _bdf_list_split( &p->list, " +", line, linelen ); if ( error ) goto Exit; - glyph->dwidth = (unsigned short)_bdf_atoul( p->list.field[1] ); + glyph->dwidth = _bdf_atous( p->list.field[1] ); if ( !( p->flags & BDF_SWIDTH_ ) ) { @@ -1687,7 +1692,7 @@ /* If the BDF_CORRECT_METRICS flag is set, then adjust the SWIDTH */ /* value if necessary. */ - if ( p->opts->correct_metrics != 0 ) + if ( p->opts->correct_metrics ) { /* Determine the point size of the glyph. */ unsigned short sw = (unsigned short)FT_MulDiv( @@ -1735,7 +1740,7 @@ else glyph->bytes = (unsigned short)bitmap_size; - if ( FT_NEW_ARRAY( glyph->bitmap, glyph->bytes ) ) + if ( FT_ALLOC( glyph->bitmap, glyph->bytes ) ) goto Exit; p->row = 0; @@ -1894,7 +1899,7 @@ /* comments before the STARTFONT line for some reason. */ if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 ) { - if ( p->opts->keep_comments != 0 && p->font != 0 ) + if ( p->opts->keep_comments && p->font ) { linelen -= 7; @@ -1904,13 +1909,8 @@ s++; linelen--; } - error = _bdf_add_comment( p->font, s, linelen ); - if ( error ) - goto Exit; - /* here font is not defined! */ } - goto Exit; } @@ -1927,14 +1927,13 @@ } p->flags = BDF_START_; - font = p->font = 0; + font = p->font = NULL; if ( FT_NEW( font ) ) goto Exit; p->font = font; font->memory = p->memory; - p->memory = 0; { /* setup */ size_t i; @@ -2055,7 +2054,7 @@ /* Allowing multiple `FONT' lines (which is invalid) doesn't hurt... */ FT_FREE( p->font->name ); - if ( FT_NEW_ARRAY( p->font->name, slen + 1 ) ) + if ( FT_QALLOC( p->font->name, slen + 1 ) ) goto Exit; FT_MEM_COPY( p->font->name, s, slen + 1 ); @@ -2095,7 +2094,7 @@ unsigned short bpp; - bpp = (unsigned short)_bdf_atos( p->list.field[4] ); + bpp = _bdf_atous( p->list.field[4] ); /* Only values 1, 2, 4, 8 are allowed for greymap fonts. */ if ( bpp > 4 ) @@ -2174,34 +2173,32 @@ FT_LOCAL_DEF( FT_Error ) bdf_load_font( FT_Stream stream, - FT_Memory extmemory, + FT_Memory memory, bdf_options_t* opts, bdf_font_t* *font ) { unsigned long lineno = 0; /* make compiler happy */ _bdf_parse_t *p = NULL; - FT_Memory memory = extmemory; /* needed for FT_NEW */ - FT_Error error = FT_Err_Ok; + FT_Error error = FT_Err_Ok; if ( FT_NEW( p ) ) goto Exit; - memory = NULL; - p->opts = (bdf_options_t*)( ( opts != 0 ) ? opts : &_bdf_opts ); + p->opts = (bdf_options_t*)( opts ? opts : &_bdf_opts ); p->minlb = 32767; p->size = stream->size; - p->memory = extmemory; /* only during font creation */ + p->memory = memory; /* only during font creation */ - _bdf_list_init( &p->list, extmemory ); + _bdf_list_init( &p->list, memory ); error = _bdf_readstream( stream, _bdf_parse_start, (void *)p, &lineno ); if ( error ) goto Fail; - if ( p->font != 0 ) + if ( p->font ) { /* If the font is not proportional, set the font's monowidth */ /* field to the width of the font bounding box. */ @@ -2282,22 +2279,7 @@ } } - if ( p->font != 0 ) - { - /* Make sure the comments are NULL terminated if they exist. */ - memory = p->font->memory; - - if ( p->font->comments_len > 0 ) - { - if ( FT_RENEW_ARRAY( p->font->comments, - p->font->comments_len, - p->font->comments_len + 1 ) ) - goto Fail; - - p->font->comments[p->font->comments_len] = 0; - } - } - else if ( !error ) + if ( !p->font && !error ) error = FT_THROW( Invalid_File_Format ); *font = p->font; @@ -2307,8 +2289,6 @@ { _bdf_list_done( &p->list ); - memory = extmemory; - FT_FREE( p->glyph_name ); FT_FREE( p ); } @@ -2318,8 +2298,6 @@ Fail: bdf_free_font( p->font ); - memory = extmemory; - FT_FREE( p->font ); goto Exit; @@ -2335,7 +2313,7 @@ FT_Memory memory; - if ( font == 0 ) + if ( font == NULL ) return; memory = font->memory; @@ -2385,11 +2363,7 @@ /* Free up the user defined properties. */ for ( prop = font->user_props, i = 0; i < font->nuser_props; i++, prop++ ) - { FT_FREE( prop->name ); - if ( prop->format == BDF_ATOM ) - FT_FREE( prop->value.atom ); - } FT_FREE( font->user_props ); @@ -2404,7 +2378,7 @@ size_t* propid; - if ( font == 0 || font->props_size == 0 || name == 0 || *name == 0 ) + if ( font == NULL || font->props_size == 0 || name == NULL || *name == 0 ) return 0; propid = ft_hash_str_lookup( name, (FT_Hash)font->internal ); diff --git a/thirdparty/freetype/src/bdf/module.mk b/thirdparty/freetype/src/bdf/module.mk deleted file mode 100644 index fe06ae8e06..0000000000 --- a/thirdparty/freetype/src/bdf/module.mk +++ /dev/null @@ -1,34 +0,0 @@ -# -# FreeType 2 BDF module definition -# - -# Copyright 2001, 2002, 2006 by -# Francesco Zappa Nardelli -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - - -FTMODULE_H_COMMANDS += BDF_DRIVER - -define BDF_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, bdf_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)bdf $(ECHO_DRIVER_DESC)bdf bitmap fonts$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/bdf/rules.mk b/thirdparty/freetype/src/bdf/rules.mk deleted file mode 100644 index d1dd76b1c3..0000000000 --- a/thirdparty/freetype/src/bdf/rules.mk +++ /dev/null @@ -1,84 +0,0 @@ -# -# FreeType 2 bdf driver configuration rules -# - - -# Copyright (C) 2001, 2002, 2003, 2008 by -# Francesco Zappa Nardelli -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - - - - -# bdf driver directory -# -BDF_DIR := $(SRC_DIR)/bdf - - -BDF_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(BDF_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# bdf driver sources (i.e., C files) -# -BDF_DRV_SRC := $(BDF_DIR)/bdflib.c \ - $(BDF_DIR)/bdfdrivr.c - - -# bdf driver headers -# -BDF_DRV_H := $(BDF_DIR)/bdf.h \ - $(BDF_DIR)/bdfdrivr.h \ - $(BDF_DIR)/bdferror.h - -# bdf driver object(s) -# -# BDF_DRV_OBJ_M is used during `multi' builds -# BDF_DRV_OBJ_S is used during `single' builds -# -BDF_DRV_OBJ_M := $(BDF_DRV_SRC:$(BDF_DIR)/%.c=$(OBJ_DIR)/%.$O) -BDF_DRV_OBJ_S := $(OBJ_DIR)/bdf.$O - -# bdf driver source file for single build -# -BDF_DRV_SRC_S := $(BDF_DIR)/bdf.c - - -# bdf driver - single object -# -$(BDF_DRV_OBJ_S): $(BDF_DRV_SRC_S) $(BDF_DRV_SRC) $(FREETYPE_H) $(BDF_DRV_H) - $(BDF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(BDF_DRV_SRC_S)) - - -# bdf driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(BDF_DIR)/%.c $(FREETYPE_H) $(BDF_DRV_H) - $(BDF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(BDF_DRV_OBJ_S) -DRV_OBJS_M += $(BDF_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/bzip2/ftbzip2.c b/thirdparty/freetype/src/bzip2/ftbzip2.c index 411c5d263b..296cea088b 100644 --- a/thirdparty/freetype/src/bzip2/ftbzip2.c +++ b/thirdparty/freetype/src/bzip2/ftbzip2.c @@ -8,7 +8,7 @@ * parse compressed PCF fonts, as found with many X11 server * distributions. * - * Copyright (C) 2010-2020 by + * Copyright (C) 2010-2021 by * Joel Klinghed. * * based on `src/gzip/ftgzip.c' @@ -70,7 +70,7 @@ FT_Pointer p = NULL; - (void)FT_ALLOC( p, sz ); + FT_MEM_QALLOC( p, sz ); return p; } @@ -327,12 +327,13 @@ FT_ULong count ) { FT_Error error = FT_Err_Ok; - FT_ULong delta; for (;;) { - delta = (FT_ULong)( zip->limit - zip->cursor ); + FT_ULong delta = (FT_ULong)( zip->limit - zip->cursor ); + + if ( delta >= count ) delta = count; @@ -494,7 +495,7 @@ stream->size = 0x7FFFFFFFL; /* don't know the real size! */ stream->pos = 0; - stream->base = 0; + stream->base = NULL; stream->read = ft_bzip2_stream_io; stream->close = ft_bzip2_stream_close; diff --git a/thirdparty/freetype/src/bzip2/rules.mk b/thirdparty/freetype/src/bzip2/rules.mk deleted file mode 100644 index eed0f4baa4..0000000000 --- a/thirdparty/freetype/src/bzip2/rules.mk +++ /dev/null @@ -1,64 +0,0 @@ -# -# FreeType 2 BZIP2 support configuration rules -# - -# Copyright (C) 2010-2020 by -# Joel Klinghed. -# -# based on `src/lzw/rules.mk' -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# BZIP2 driver directory -# -BZIP2_DIR := $(SRC_DIR)/bzip2 - - -# compilation flags for the driver -# -BZIP2_COMPILE := $(CC) $(ANSIFLAGS) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# BZIP2 support sources (i.e., C files) -# -BZIP2_DRV_SRC := $(BZIP2_DIR)/ftbzip2.c - -# BZIP2 driver object(s) -# -# BZIP2_DRV_OBJ_M is used during `multi' builds -# BZIP2_DRV_OBJ_S is used during `single' builds -# -BZIP2_DRV_OBJ_M := $(OBJ_DIR)/ftbzip2.$O -BZIP2_DRV_OBJ_S := $(OBJ_DIR)/ftbzip2.$O - -# BZIP2 support source file for single build -# -BZIP2_DRV_SRC_S := $(BZIP2_DIR)/ftbzip2.c - - -# BZIP2 support - single object -# -$(BZIP2_DRV_OBJ_S): $(BZIP2_DRV_SRC_S) $(BZIP2_DRV_SRC) $(FREETYPE_H) $(BZIP2_DRV_H) - $(BZIP2_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(BZIP2_DRV_SRC_S)) - - -# BZIP2 support - multiple objects -# -$(OBJ_DIR)/%.$O: $(BZIP2_DIR)/%.c $(FREETYPE_H) $(BZIP2_DRV_H) - $(BZIP2_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(BZIP2_DRV_OBJ_S) -DRV_OBJS_M += $(BZIP2_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/cache/ftcache.c b/thirdparty/freetype/src/cache/ftcache.c index e90f4639cb..ddd3e43c02 100644 --- a/thirdparty/freetype/src/cache/ftcache.c +++ b/thirdparty/freetype/src/cache/ftcache.c @@ -4,7 +4,7 @@ * * The FreeType Caching sub-system (body only). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cache/ftcbasic.c b/thirdparty/freetype/src/cache/ftcbasic.c index 43ea314d4a..1760c5fbd4 100644 --- a/thirdparty/freetype/src/cache/ftcbasic.c +++ b/thirdparty/freetype/src/cache/ftcbasic.c @@ -4,7 +4,7 @@ * * The FreeType basic cache interface (body). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -108,12 +108,16 @@ if ( error || !face ) return result; +#ifdef FT_DEBUG_LEVEL_TRACE if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs ) + { FT_TRACE1(( "ftc_basic_family_get_count:" - " the number of glyphs in this face is %ld,\n" - " " - " which is too much and thus truncated\n", + " the number of glyphs in this face is %ld,\n", face->num_glyphs )); + FT_TRACE1(( " " + " which is too much and thus truncated\n" )); + } +#endif if ( !error ) result = (FT_UInt)face->num_glyphs; diff --git a/thirdparty/freetype/src/cache/ftccache.c b/thirdparty/freetype/src/cache/ftccache.c index 1c8e0f3221..5bbf329298 100644 --- a/thirdparty/freetype/src/cache/ftccache.c +++ b/thirdparty/freetype/src/cache/ftccache.c @@ -4,7 +4,7 @@ * * The FreeType internal cache interface (body). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -90,15 +90,14 @@ ftc_get_top_node_for_hash( FTC_Cache cache, FT_Offset hash ) { - FTC_Node* pnode; FT_Offset idx; idx = hash & cache->mask; if ( idx < cache->p ) idx = hash & ( 2 * cache->mask + 1 ); - pnode = cache->buckets + idx; - return pnode; + + return cache->buckets + idx; } #endif /* !FTC_INLINE */ @@ -119,7 +118,7 @@ FT_UFast count = mask + p + 1; /* number of buckets */ - /* do we need to shrink the buckets array? */ + /* do we need to expand the buckets array? */ if ( cache->slack < 0 ) { FTC_Node new_list = NULL; @@ -172,7 +171,7 @@ cache->p = p + 1; } - /* do we need to expand the buckets array? */ + /* do we need to shrink the buckets array? */ else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD ) { FT_UFast old_index = p + mask; @@ -189,7 +188,7 @@ /* if we can't shrink the array, leave immediately */ - if ( FT_RENEW_ARRAY( cache->buckets, + if ( FT_QRENEW_ARRAY( cache->buckets, ( mask + 1 ) * 2, mask + 1 ) ) break; @@ -341,7 +340,7 @@ cache->mask = FTC_HASH_INITIAL_SIZE - 1; cache->slack = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD; - (void)FT_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 ); + FT_MEM_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 ); return error; } @@ -360,7 +359,7 @@ for ( i = 0; i < count; i++ ) { - FTC_Node *pnode = cache->buckets + i, next, node = *pnode; + FTC_Node node = cache->buckets[i], next; while ( node ) @@ -417,7 +416,7 @@ FTC_Node node ) { node->hash = hash; - node->cache_index = (FT_UInt16)cache->index; + node->cache_index = (FT_UShort)cache->index; node->ref_count = 0; ftc_node_hash_link( node, cache ); @@ -459,7 +458,7 @@ { error = cache->clazz.node_new( &node, query, cache ); } - FTC_CACHE_TRYLOOP_END( NULL ); + FTC_CACHE_TRYLOOP_END( NULL ) if ( error ) node = NULL; @@ -528,7 +527,7 @@ goto NewNode; } else - pnode = &((*pnode)->link); + pnode = &(*pnode)->link; } } @@ -571,8 +570,7 @@ count = cache->p + cache->mask + 1; for ( i = 0; i < count; i++ ) { - FTC_Node* bucket = cache->buckets + i; - FTC_Node* pnode = bucket; + FTC_Node* pnode = cache->buckets + i; for (;;) diff --git a/thirdparty/freetype/src/cache/ftccache.h b/thirdparty/freetype/src/cache/ftccache.h index 11698bb0e9..4849b92352 100644 --- a/thirdparty/freetype/src/cache/ftccache.h +++ b/thirdparty/freetype/src/cache/ftccache.h @@ -4,7 +4,7 @@ * * FreeType internal cache interface (specification). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -251,7 +251,7 @@ FT_BEGIN_HEADER goto NewNode_; \ } \ else \ - _pnode = &((*_pnode)->link); \ + _pnode = &(*_pnode)->link; \ } \ } \ \ diff --git a/thirdparty/freetype/src/cache/ftccback.h b/thirdparty/freetype/src/cache/ftccback.h index 542acb1565..8185fe3738 100644 --- a/thirdparty/freetype/src/cache/ftccback.h +++ b/thirdparty/freetype/src/cache/ftccback.h @@ -4,7 +4,7 @@ * * Callback functions of the caching sub-system (specification only). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cache/ftccmap.c b/thirdparty/freetype/src/cache/ftccmap.c index 468c008cf6..40b449b9cc 100644 --- a/thirdparty/freetype/src/cache/ftccmap.c +++ b/thirdparty/freetype/src/cache/ftccmap.c @@ -4,7 +4,7 @@ * * FreeType CharMap cache (body) * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -273,12 +273,11 @@ if ( error ) goto Exit; - FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) < - FTC_CMAP_INDICES_MAX ); + FT_ASSERT( char_code - FTC_CMAP_NODE( node )->first < + FTC_CMAP_INDICES_MAX ); /* something rotten can happen with rogue clients */ - if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >= - FTC_CMAP_INDICES_MAX ) ) + if ( char_code - FTC_CMAP_NODE( node )->first >= FTC_CMAP_INDICES_MAX ) return 0; /* XXX: should return appropriate error */ gindex = FTC_CMAP_NODE( node )->indices[char_code - diff --git a/thirdparty/freetype/src/cache/ftcerror.h b/thirdparty/freetype/src/cache/ftcerror.h index bedfd28371..2c6faf65e2 100644 --- a/thirdparty/freetype/src/cache/ftcerror.h +++ b/thirdparty/freetype/src/cache/ftcerror.h @@ -4,7 +4,7 @@ * * Caching sub-system error codes (specification only). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cache/ftcglyph.c b/thirdparty/freetype/src/cache/ftcglyph.c index 7f5438aad5..52771c7a8a 100644 --- a/thirdparty/freetype/src/cache/ftcglyph.c +++ b/thirdparty/freetype/src/cache/ftcglyph.c @@ -4,7 +4,7 @@ * * FreeType Glyph Image (FT_Glyph) cache (body). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cache/ftcglyph.h b/thirdparty/freetype/src/cache/ftcglyph.h index 5629545f3c..cf00cdc7b8 100644 --- a/thirdparty/freetype/src/cache/ftcglyph.h +++ b/thirdparty/freetype/src/cache/ftcglyph.h @@ -4,7 +4,7 @@ * * FreeType abstract glyph cache (specification). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cache/ftcimage.c b/thirdparty/freetype/src/cache/ftcimage.c index 58ebad8c93..3f12a654b2 100644 --- a/thirdparty/freetype/src/cache/ftcimage.c +++ b/thirdparty/freetype/src/cache/ftcimage.c @@ -4,7 +4,7 @@ * * FreeType Image cache (body). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cache/ftcimage.h b/thirdparty/freetype/src/cache/ftcimage.h index a400788b3c..8b28d6f00b 100644 --- a/thirdparty/freetype/src/cache/ftcimage.h +++ b/thirdparty/freetype/src/cache/ftcimage.h @@ -4,7 +4,7 @@ * * FreeType Generic Image cache (specification) * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cache/ftcmanag.c b/thirdparty/freetype/src/cache/ftcmanag.c index 436d41f374..512de8a3fc 100644 --- a/thirdparty/freetype/src/cache/ftcmanag.c +++ b/thirdparty/freetype/src/cache/ftcmanag.c @@ -4,7 +4,7 @@ * * FreeType Cache Manager (body). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -357,7 +357,7 @@ { FT_Error error; FT_Memory memory; - FTC_Manager manager = 0; + FTC_Manager manager = NULL; if ( !library ) @@ -368,7 +368,7 @@ memory = library->memory; - if ( FT_NEW( manager ) ) + if ( FT_QNEW( manager ) ) goto Exit; if ( max_faces == 0 ) @@ -399,6 +399,10 @@ manager, memory ); + manager->nodes_list = NULL; + manager->num_nodes = 0; + manager->num_caches = 0; + *amanager = manager; Exit: @@ -593,7 +597,7 @@ goto Exit; } - if ( !FT_ALLOC( cache, clazz->cache_size ) ) + if ( !FT_QALLOC( cache, clazz->cache_size ) ) { cache->manager = manager; cache->memory = memory; diff --git a/thirdparty/freetype/src/cache/ftcmanag.h b/thirdparty/freetype/src/cache/ftcmanag.h index 6c6ec68545..99aa926369 100644 --- a/thirdparty/freetype/src/cache/ftcmanag.h +++ b/thirdparty/freetype/src/cache/ftcmanag.h @@ -4,7 +4,7 @@ * * FreeType Cache Manager (specification). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cache/ftcmru.c b/thirdparty/freetype/src/cache/ftcmru.c index 8feed45f6b..2cac6f9d3a 100644 --- a/thirdparty/freetype/src/cache/ftcmru.c +++ b/thirdparty/freetype/src/cache/ftcmru.c @@ -4,7 +4,7 @@ * * FreeType MRU support (body). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -262,7 +262,7 @@ if ( list->clazz.node_done ) list->clazz.node_done( node, list->data ); } - else if ( FT_ALLOC( node, list->clazz.node_size ) ) + else if ( FT_QALLOC( node, list->clazz.node_size ) ) goto Exit; error = list->clazz.node_init( node, key, list->data ); diff --git a/thirdparty/freetype/src/cache/ftcmru.h b/thirdparty/freetype/src/cache/ftcmru.h index ac4f9b126d..6befde307f 100644 --- a/thirdparty/freetype/src/cache/ftcmru.h +++ b/thirdparty/freetype/src/cache/ftcmru.h @@ -4,7 +4,7 @@ * * Simple MRU list-cache (specification). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cache/ftcsbits.c b/thirdparty/freetype/src/cache/ftcsbits.c index e0db930af8..362999fce0 100644 --- a/thirdparty/freetype/src/cache/ftcsbits.c +++ b/thirdparty/freetype/src/cache/ftcsbits.c @@ -4,7 +4,7 @@ * * FreeType sbits manager (body). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -52,10 +52,8 @@ pitch = -pitch; size = (FT_ULong)pitch * bitmap->rows; - if ( !size ) - return FT_Err_Ok; - if ( !FT_ALLOC( sbit->buffer, size ) ) + if ( !FT_QALLOC( sbit->buffer, size ) ) FT_MEM_COPY( sbit->buffer, bitmap->buffer, size ); return error; @@ -108,13 +106,12 @@ FT_Error error; FTC_GNode gnode = FTC_GNODE( snode ); FTC_Family family = gnode->family; - FT_Memory memory = manager->memory; FT_Face face; FTC_SBit sbit; FTC_SFamilyClass clazz; - if ( (FT_UInt)(gindex - gnode->gindex) >= snode->count ) + if ( gindex - gnode->gindex >= snode->count ) { FT_ERROR(( "ftc_snode_load: invalid glyph index" )); return FT_THROW( Invalid_Argument ); @@ -123,8 +120,6 @@ sbit = snode->sbits + ( gindex - gnode->gindex ); clazz = (FTC_SFamilyClass)family->clazz; - sbit->buffer = 0; - error = clazz->family_load_glyph( family, gindex, manager, &face ); if ( error ) goto BadGlyph; @@ -143,12 +138,13 @@ goto BadGlyph; } - /* Check whether our values fit into 8-bit containers! */ + /* Check whether our values fit into 8/16-bit containers! */ /* If this is not the case, our bitmap is too large */ /* and we will leave it as `missing' with sbit.buffer = 0 */ #define CHECK_CHAR( d ) ( temp = (FT_Char)d, (FT_Int) temp == (FT_Int) d ) #define CHECK_BYTE( d ) ( temp = (FT_Byte)d, (FT_UInt)temp == (FT_UInt)d ) +#define CHECK_SHRT( d ) ( temp = (FT_Short)d, (FT_Int)temp == (FT_Int) d ) /* horizontal advance in pixels */ xadvance = ( slot->advance.x + 32 ) >> 6; @@ -156,7 +152,7 @@ if ( !CHECK_BYTE( bitmap->rows ) || !CHECK_BYTE( bitmap->width ) || - !CHECK_CHAR( bitmap->pitch ) || + !CHECK_SHRT( bitmap->pitch ) || !CHECK_CHAR( slot->bitmap_left ) || !CHECK_CHAR( slot->bitmap_top ) || !CHECK_CHAR( xadvance ) || @@ -169,7 +165,7 @@ sbit->width = (FT_Byte)bitmap->width; sbit->height = (FT_Byte)bitmap->rows; - sbit->pitch = (FT_Char)bitmap->pitch; + sbit->pitch = (FT_Short)bitmap->pitch; sbit->left = (FT_Char)slot->bitmap_left; sbit->top = (FT_Char)slot->bitmap_top; sbit->xadvance = (FT_Char)xadvance; @@ -177,8 +173,17 @@ sbit->format = (FT_Byte)bitmap->pixel_mode; sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1); - /* copy the bitmap into a new buffer -- ignore error */ - error = ftc_sbit_copy_bitmap( sbit, bitmap, memory ); + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + { + /* take the bitmap ownership */ + sbit->buffer = bitmap->buffer; + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + else + { + /* copy the bitmap into a new buffer -- ignore error */ + error = ftc_sbit_copy_bitmap( sbit, bitmap, manager->memory ); + } /* now, compute size */ if ( asize ) @@ -337,8 +342,8 @@ if (list_changed) *list_changed = FALSE; - result = FT_BOOL( gnode->family == gquery->family && - (FT_UInt)( gindex - gnode->gindex ) < snode->count ); + result = FT_BOOL( gnode->family == gquery->family && + gindex - gnode->gindex < snode->count ); if ( result ) { /* check if we need to load the glyph bitmap now */ @@ -390,7 +395,7 @@ { error = ftc_snode_load( snode, cache->manager, gindex, &size ); } - FTC_CACHE_TRYLOOP_END( list_changed ); + FTC_CACHE_TRYLOOP_END( list_changed ) ftcsnode->ref_count--; /* unlock the node */ diff --git a/thirdparty/freetype/src/cache/ftcsbits.h b/thirdparty/freetype/src/cache/ftcsbits.h index 46f797e724..9f2d5fb33c 100644 --- a/thirdparty/freetype/src/cache/ftcsbits.h +++ b/thirdparty/freetype/src/cache/ftcsbits.h @@ -4,7 +4,7 @@ * * A small-bitmap cache (specification). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cache/rules.mk b/thirdparty/freetype/src/cache/rules.mk deleted file mode 100644 index 4738b5153a..0000000000 --- a/thirdparty/freetype/src/cache/rules.mk +++ /dev/null @@ -1,85 +0,0 @@ -# -# FreeType 2 Cache configuration rules -# - - -# Copyright (C) 2000-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# Cache driver directory -# -CACHE_DIR := $(SRC_DIR)/cache - - -# compilation flags for the driver -# -CACHE_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(CACHE_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# Cache driver sources (i.e., C files) -# -CACHE_DRV_SRC := $(CACHE_DIR)/ftcbasic.c \ - $(CACHE_DIR)/ftccache.c \ - $(CACHE_DIR)/ftccmap.c \ - $(CACHE_DIR)/ftcglyph.c \ - $(CACHE_DIR)/ftcimage.c \ - $(CACHE_DIR)/ftcmanag.c \ - $(CACHE_DIR)/ftcmru.c \ - $(CACHE_DIR)/ftcsbits.c - - -# Cache driver headers -# -CACHE_DRV_H := $(CACHE_DIR)/ftccache.h \ - $(CACHE_DIR)/ftccback.h \ - $(CACHE_DIR)/ftcerror.h \ - $(CACHE_DIR)/ftcglyph.h \ - $(CACHE_DIR)/ftcimage.h \ - $(CACHE_DIR)/ftcmanag.h \ - $(CACHE_DIR)/ftcmru.h \ - $(CACHE_DIR)/ftcsbits.h - - -# Cache driver object(s) -# -# CACHE_DRV_OBJ_M is used during `multi' builds. -# CACHE_DRV_OBJ_S is used during `single' builds. -# -CACHE_DRV_OBJ_M := $(CACHE_DRV_SRC:$(CACHE_DIR)/%.c=$(OBJ_DIR)/%.$O) -CACHE_DRV_OBJ_S := $(OBJ_DIR)/ftcache.$O - -# Cache driver source file for single build -# -CACHE_DRV_SRC_S := $(CACHE_DIR)/ftcache.c - - -# Cache driver - single object -# -$(CACHE_DRV_OBJ_S): $(CACHE_DRV_SRC_S) $(CACHE_DRV_SRC) \ - $(FREETYPE_H) $(CACHE_DRV_H) - $(CACHE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(CACHE_DRV_SRC_S)) - - -# Cache driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(CACHE_DIR)/%.c $(FREETYPE_H) $(CACHE_DRV_H) - $(CACHE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(CACHE_DRV_OBJ_S) -DRV_OBJS_M += $(CACHE_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/cff/cff.c b/thirdparty/freetype/src/cff/cff.c index 0fa6c87870..c2ffea3d0d 100644 --- a/thirdparty/freetype/src/cff/cff.c +++ b/thirdparty/freetype/src/cff/cff.c @@ -4,7 +4,7 @@ * * FreeType OpenType driver component (body only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cff/cffcmap.c b/thirdparty/freetype/src/cff/cffcmap.c index 6d16ed4226..ff1aae69ef 100644 --- a/thirdparty/freetype/src/cff/cffcmap.c +++ b/thirdparty/freetype/src/cff/cffcmap.c @@ -4,7 +4,7 @@ * * CFF character mapping table (cmap) support (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cff/cffcmap.h b/thirdparty/freetype/src/cff/cffcmap.h index 69fab8dc6c..221e255afb 100644 --- a/thirdparty/freetype/src/cff/cffcmap.h +++ b/thirdparty/freetype/src/cff/cffcmap.h @@ -4,7 +4,7 @@ * * CFF character mapping table (cmap) support (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cff/cffdrivr.c b/thirdparty/freetype/src/cff/cffdrivr.c index 486ab24235..59210f37c5 100644 --- a/thirdparty/freetype/src/cff/cffdrivr.c +++ b/thirdparty/freetype/src/cff/cffdrivr.c @@ -4,7 +4,7 @@ * * OpenType font driver implementation (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -345,8 +345,8 @@ else { FT_ERROR(( "cff_get_glyph_name:" - " cannot get glyph name from a CFF2 font\n" - " " + " cannot get glyph name from a CFF2 font\n" )); + FT_ERROR(( " " " without the `psnames' module\n" )); error = FT_THROW( Missing_Module ); goto Exit; @@ -356,8 +356,8 @@ if ( !font->psnames ) { FT_ERROR(( "cff_get_glyph_name:" - " cannot get glyph name from CFF & CEF fonts\n" - " " + " cannot get glyph name from CFF & CEF fonts\n" )); + FT_ERROR(( " " " without the `psnames' module\n" )); error = FT_THROW( Missing_Module ); goto Exit; @@ -412,8 +412,8 @@ else { FT_ERROR(( "cff_get_name_index:" - " cannot get glyph index from a CFF2 font\n" - " " + " cannot get glyph index from a CFF2 font\n" )); + FT_ERROR(( " " " without the `psnames' module\n" )); return 0; } @@ -474,11 +474,11 @@ if ( cff && !cff->font_info ) { CFF_FontRecDict dict = &cff->top_font.font_dict; - PS_FontInfoRec *font_info = NULL; FT_Memory memory = face->root.memory; + PS_FontInfoRec* font_info = NULL; - if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) ) + if ( FT_QNEW( font_info ) ) goto Fail; font_info->version = cff_index_get_sid_string( cff, @@ -515,15 +515,15 @@ FT_Error error = FT_Err_Ok; - if ( cff && cff->font_extra == NULL ) + if ( cff && !cff->font_extra ) { CFF_FontRecDict dict = &cff->top_font.font_dict; - PS_FontExtraRec* font_extra = NULL; FT_Memory memory = face->root.memory; + PS_FontExtraRec* font_extra = NULL; FT_String* embedded_postscript; - if ( FT_ALLOC( font_extra, sizeof ( *font_extra ) ) ) + if ( FT_QNEW( font_extra ) ) goto Fail; font_extra->fs_type = 0U; diff --git a/thirdparty/freetype/src/cff/cffdrivr.h b/thirdparty/freetype/src/cff/cffdrivr.h index d198dd35cb..fce92bbb00 100644 --- a/thirdparty/freetype/src/cff/cffdrivr.h +++ b/thirdparty/freetype/src/cff/cffdrivr.h @@ -4,7 +4,7 @@ * * High-level OpenType driver interface (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cff/cfferrs.h b/thirdparty/freetype/src/cff/cfferrs.h index 5b00a3f0a2..b507ec8bb7 100644 --- a/thirdparty/freetype/src/cff/cfferrs.h +++ b/thirdparty/freetype/src/cff/cfferrs.h @@ -4,7 +4,7 @@ * * CFF error codes (specification only). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cff/cffgload.c b/thirdparty/freetype/src/cff/cffgload.c index feee38a413..97e8f9c1c6 100644 --- a/thirdparty/freetype/src/cff/cffgload.c +++ b/thirdparty/freetype/src/cff/cffgload.c @@ -4,7 +4,7 @@ * * OpenType Glyph Loader (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -59,7 +59,7 @@ *pointer = (FT_Byte*)data.pointer; - *length = (FT_ULong)data.length; + *length = data.length; return error; } @@ -94,7 +94,7 @@ data.pointer = *pointer; - data.length = (FT_Int)length; + data.length = (FT_UInt)length; face->root.internal->incremental_interface->funcs->free_glyph_data( face->root.internal->incremental_interface->object, &data ); diff --git a/thirdparty/freetype/src/cff/cffgload.h b/thirdparty/freetype/src/cff/cffgload.h index 3b312f452e..d0d6a6fa08 100644 --- a/thirdparty/freetype/src/cff/cffgload.h +++ b/thirdparty/freetype/src/cff/cffgload.h @@ -4,7 +4,7 @@ * * OpenType Glyph Loader (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cff/cffload.c b/thirdparty/freetype/src/cff/cffload.c index 73d3eecd31..3c3f6fe502 100644 --- a/thirdparty/freetype/src/cff/cffload.c +++ b/thirdparty/freetype/src/cff/cffload.c @@ -4,7 +4,7 @@ * * OpenType and CFF data/program tables loader (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -356,9 +356,9 @@ data_size = (FT_ULong)( idx->count + 1 ) * offsize; - if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) || - FT_STREAM_SEEK( idx->start + idx->hdr_size ) || - FT_FRAME_ENTER( data_size ) ) + if ( FT_QNEW_ARRAY( idx->offsets, idx->count + 1 ) || + FT_STREAM_SEEK( idx->start + idx->hdr_size ) || + FT_FRAME_ENTER( data_size ) ) goto Exit; poff = idx->offsets; @@ -400,7 +400,7 @@ /* Allocate a table containing pointers to an index's elements. */ /* The `pool' argument makes this function convert the index */ - /* entries to C-style strings (this is, NULL-terminated). */ + /* entries to C-style strings (this is, null-terminated). */ static FT_Error cff_index_get_pointers( CFF_Index idx, FT_Byte*** table, @@ -427,7 +427,7 @@ new_size = idx->data_size + idx->count; if ( idx->count > 0 && - !FT_NEW_ARRAY( tbl, idx->count + 1 ) && + !FT_QNEW_ARRAY( tbl, idx->count + 1 ) && ( !pool || !FT_ALLOC( new_bytes, new_size ) ) ) { FT_ULong n, cur_offset; @@ -622,7 +622,7 @@ FT_Byte* bytes; FT_ULong byte_len; FT_Error error; - FT_String* name = 0; + FT_String* name = NULL; if ( !idx->stream ) /* CFF2 does not include a name index */ @@ -634,10 +634,9 @@ if ( error ) goto Exit; - if ( !FT_ALLOC( name, byte_len + 1 ) ) + if ( !FT_QALLOC( name, byte_len + 1 ) ) { - if ( byte_len ) - FT_MEM_COPY( name, bytes, byte_len ); + FT_MEM_COPY( name, bytes, byte_len ); name[byte_len] = 0; } cff_index_forget_element( idx, &bytes ); @@ -772,8 +771,7 @@ case 3: /* first, compare to the cache */ - if ( (FT_UInt)( glyph_index - fdselect->cache_first ) < - fdselect->cache_count ) + if ( glyph_index - fdselect->cache_first < fdselect->cache_count ) { fd = fdselect->cache_fd; break; @@ -836,7 +834,6 @@ { FT_Error error = FT_Err_Ok; FT_UInt i; - FT_Long j; FT_UShort max_cid = 0; @@ -854,9 +851,10 @@ /* When multiple GIDs map to the same CID, we choose the lowest */ /* GID. This is not described in any spec, but it matches the */ - /* behaviour of recent Acroread versions. */ - for ( j = (FT_Long)num_glyphs - 1; j >= 0; j-- ) - charset->cids[charset->sids[j]] = (FT_UShort)j; + /* behaviour of recent Acroread versions. The loop stops when */ + /* the unsigned index wraps around after reaching zero. */ + for ( i = num_glyphs - 1; i < num_glyphs; i-- ) + charset->cids[charset->sids[i]] = (FT_UShort)i; charset->max_cid = max_cid; charset->num_glyphs = num_glyphs; @@ -932,7 +930,7 @@ goto Exit; /* Allocate memory for sids. */ - if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) + if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) ) goto Exit; /* assign the .notdef glyph */ @@ -1018,14 +1016,14 @@ case 0: if ( num_glyphs > 229 ) { - FT_ERROR(( "cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe ISO-Latin)\n" )); + FT_ERROR(( "cff_charset_load: implicit charset larger than\n" )); + FT_ERROR(( "predefined charset (Adobe ISO-Latin)\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } /* Allocate memory for sids. */ - if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) + if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) ) goto Exit; /* Copy the predefined charset into the allocated memory. */ @@ -1036,14 +1034,14 @@ case 1: if ( num_glyphs > 166 ) { - FT_ERROR(( "cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe Expert)\n" )); + FT_ERROR(( "cff_charset_load: implicit charset larger than\n" )); + FT_ERROR(( "predefined charset (Adobe Expert)\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } /* Allocate memory for sids. */ - if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) + if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) ) goto Exit; /* Copy the predefined charset into the allocated memory. */ @@ -1054,14 +1052,14 @@ case 2: if ( num_glyphs > 87 ) { - FT_ERROR(( "cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe Expert Subset)\n" )); + FT_ERROR(( "cff_charset_load: implicit charset larger than\n" )); + FT_ERROR(( "predefined charset (Adobe Expert Subset)\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } /* Allocate memory for sids. */ - if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) + if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) ) goto Exit; /* Copy the predefined charset into the allocated memory. */ @@ -1087,7 +1085,6 @@ FT_FREE( charset->cids ); charset->format = 0; charset->offset = 0; - charset->sids = 0; } return error; @@ -1141,6 +1138,8 @@ { FT_UInt vsOffset; FT_UInt format; + FT_UInt dataCount; + FT_UInt regionCount; FT_ULong regionListOffset; @@ -1163,16 +1162,16 @@ } /* read top level fields */ - if ( FT_READ_ULONG( regionListOffset ) || - FT_READ_USHORT( vstore->dataCount ) ) + if ( FT_READ_ULONG( regionListOffset ) || + FT_READ_USHORT( dataCount ) ) goto Exit; /* make temporary copy of item variation data offsets; */ /* we'll parse region list first, then come back */ - if ( FT_NEW_ARRAY( dataOffsetArray, vstore->dataCount ) ) + if ( FT_QNEW_ARRAY( dataOffsetArray, dataCount ) ) goto Exit; - for ( i = 0; i < vstore->dataCount; i++ ) + for ( i = 0; i < dataCount; i++ ) { if ( FT_READ_ULONG( dataOffsetArray[i] ) ) goto Exit; @@ -1181,20 +1180,24 @@ /* parse regionList and axisLists */ if ( FT_STREAM_SEEK( vsOffset + regionListOffset ) || FT_READ_USHORT( vstore->axisCount ) || - FT_READ_USHORT( vstore->regionCount ) ) + FT_READ_USHORT( regionCount ) ) goto Exit; - if ( FT_NEW_ARRAY( vstore->varRegionList, vstore->regionCount ) ) + vstore->regionCount = 0; + if ( FT_QNEW_ARRAY( vstore->varRegionList, regionCount ) ) goto Exit; - for ( i = 0; i < vstore->regionCount; i++ ) + for ( i = 0; i < regionCount; i++ ) { CFF_VarRegion* region = &vstore->varRegionList[i]; - if ( FT_NEW_ARRAY( region->axisList, vstore->axisCount ) ) + if ( FT_QNEW_ARRAY( region->axisList, vstore->axisCount ) ) goto Exit; + /* keep track of how many axisList to deallocate on error */ + vstore->regionCount++; + for ( j = 0; j < vstore->axisCount; j++ ) { CFF_AxisCoords* axis = ®ion->axisList[j]; @@ -1214,10 +1217,11 @@ } /* use dataOffsetArray now to parse varData items */ - if ( FT_NEW_ARRAY( vstore->varData, vstore->dataCount ) ) + vstore->dataCount = 0; + if ( FT_QNEW_ARRAY( vstore->varData, dataCount ) ) goto Exit; - for ( i = 0; i < vstore->dataCount; i++ ) + for ( i = 0; i < dataCount; i++ ) { CFF_VarData* data = &vstore->varData[i]; @@ -1236,9 +1240,12 @@ if ( FT_READ_USHORT( data->regionIdxCount ) ) goto Exit; - if ( FT_NEW_ARRAY( data->regionIndices, data->regionIdxCount ) ) + if ( FT_QNEW_ARRAY( data->regionIndices, data->regionIdxCount ) ) goto Exit; + /* keep track of how many regionIndices to deallocate on error */ + vstore->dataCount++; + for ( j = 0; j < data->regionIdxCount; j++ ) { if ( FT_READ_USHORT( data->regionIndices[j] ) ) @@ -1322,9 +1329,9 @@ /* increase or allocate `blend_stack' and reset `blend_top'; */ /* prepare to append `numBlends' values to the buffer */ - if ( FT_REALLOC( subFont->blend_stack, - subFont->blend_alloc, - subFont->blend_alloc + size ) ) + if ( FT_QREALLOC( subFont->blend_stack, + subFont->blend_alloc, + subFont->blend_alloc + size ) ) goto Exit; subFont->blend_top = subFont->blend_stack + subFont->blend_used; @@ -1437,9 +1444,7 @@ /* prepare buffer for the blend vector */ len = varData->regionIdxCount + 1; /* add 1 for default component */ - if ( FT_REALLOC( blend->BV, - blend->lenBV * sizeof( *blend->BV ), - len * sizeof( *blend->BV ) ) ) + if ( FT_QRENEW_ARRAY( blend->BV, blend->lenBV, len ) ) goto Exit; blend->lenBV = len; @@ -1456,10 +1461,8 @@ if ( master == 0 ) { blend->BV[master] = FT_FIXED_ONE; - FT_TRACE4(( " build blend vector len %d\n" - " [ %f ", - len, - blend->BV[master] / 65536.0 )); + FT_TRACE4(( " build blend vector len %d\n", len )); + FT_TRACE4(( " [ %f ", blend->BV[master] / 65536.0 )); continue; } @@ -1543,9 +1546,7 @@ if ( lenNDV != 0 ) { /* user has set a normalized vector */ - if ( FT_REALLOC( blend->lastNDV, - blend->lenNDV * sizeof ( *NDV ), - lenNDV * sizeof ( *NDV ) ) ) + if ( FT_QRENEW_ARRAY( blend->lastNDV, blend->lenNDV, lenNDV ) ) goto Exit; FT_MEM_COPY( blend->lastNDV, @@ -1827,7 +1828,8 @@ /* Construct code to GID mapping from code to SID mapping */ /* and charset. */ - encoding->count = 0; + encoding->offset = offset; /* used in cff_face_init */ + encoding->count = 0; error = cff_charset_compute_cids( charset, num_glyphs, stream->memory ); @@ -2363,8 +2365,8 @@ if ( font->name_index.count > 1 ) { FT_ERROR(( "cff_font_load:" - " invalid CFF font with multiple subfonts\n" - " " + " invalid CFF font with multiple subfonts\n" )); + FT_ERROR(( " " " in SFNT wrapper\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; diff --git a/thirdparty/freetype/src/cff/cffload.h b/thirdparty/freetype/src/cff/cffload.h index fc998db2db..20f9296c4f 100644 --- a/thirdparty/freetype/src/cff/cffload.h +++ b/thirdparty/freetype/src/cff/cffload.h @@ -4,7 +4,7 @@ * * OpenType & CFF data/program tables loader (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cff/cffobjs.c b/thirdparty/freetype/src/cff/cffobjs.c index d555d52358..3a4d47dbdd 100644 --- a/thirdparty/freetype/src/cff/cffobjs.c +++ b/thirdparty/freetype/src/cff/cffobjs.c @@ -4,7 +4,7 @@ * * OpenType objects manager (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -283,6 +283,8 @@ cff_size_request( FT_Size size, FT_Size_Request req ) { + FT_Error error; + CFF_Size cffsize = (CFF_Size)size; PSH_Globals_Funcs funcs; @@ -304,7 +306,9 @@ #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - FT_Request_Metrics( size->face, req ); + error = FT_Request_Metrics( size->face, req ); + if ( error ) + goto Exit; funcs = cff_size_get_globals_funcs( cffsize ); @@ -345,7 +349,8 @@ } } - return FT_Err_Ok; + Exit: + return error; } @@ -659,8 +664,8 @@ if ( dict->cid_registry == 0xFFFFU && !psnames ) { FT_ERROR(( "cff_face_init:" - " cannot open CFF & CEF fonts\n" - " " + " cannot open CFF & CEF fonts\n" )); + FT_ERROR(( " " " without the `psnames' module\n" )); error = FT_THROW( Missing_Module ); goto Exit; @@ -684,13 +689,13 @@ /* In Multiple Master CFFs, two SIDs hold the Normalize Design */ /* Vector (NDV) and Convert Design Vector (CDV) charstrings, */ - /* which may contain NULL bytes in the middle of the data, too. */ + /* which may contain null bytes in the middle of the data, too. */ /* We thus access `cff->strings' directly. */ for ( idx = 1; idx < cff->num_strings; idx++ ) { FT_Byte* s1 = cff->strings[idx - 1]; FT_Byte* s2 = cff->strings[idx]; - FT_PtrDist s1len = s2 - s1 - 1; /* without the final NULL byte */ + FT_PtrDist s1len = s2 - s1 - 1; /* without the final null byte */ FT_PtrDist l; @@ -1049,11 +1054,11 @@ { FT_CharMapRec cmaprec; FT_CharMap cmap; - FT_UInt nn; + FT_Int nn; CFF_Encoding encoding = &cff->encoding; - for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ ) + for ( nn = 0; nn < cffface->num_charmaps; nn++ ) { cmap = cffface->charmaps[nn]; @@ -1078,7 +1083,7 @@ cmaprec.encoding_id = TT_MS_ID_UNICODE_CS; cmaprec.encoding = FT_ENCODING_UNICODE; - nn = (FT_UInt)cffface->num_charmaps; + nn = cffface->num_charmaps; error = FT_CMap_New( &cff_cmap_unicode_class_rec, NULL, &cmaprec, NULL ); @@ -1089,7 +1094,7 @@ error = FT_Err_Ok; /* if no Unicode charmap was previously selected, select this one */ - if ( !cffface->charmap && nn != (FT_UInt)cffface->num_charmaps ) + if ( !cffface->charmap && nn != cffface->num_charmaps ) cffface->charmap = cffface->charmaps[nn]; Skip_Unicode: @@ -1174,11 +1179,7 @@ /* set default property values, cf. `ftcffdrv.h' */ -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - driver->hinting_engine = FT_HINTING_FREETYPE; -#else driver->hinting_engine = FT_HINTING_ADOBE; -#endif driver->no_stem_darkening = TRUE; diff --git a/thirdparty/freetype/src/cff/cffobjs.h b/thirdparty/freetype/src/cff/cffobjs.h index 845bd90941..149a8a2f0a 100644 --- a/thirdparty/freetype/src/cff/cffobjs.h +++ b/thirdparty/freetype/src/cff/cffobjs.h @@ -4,7 +4,7 @@ * * OpenType objects manager (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cff/cffparse.c b/thirdparty/freetype/src/cff/cffparse.c index 69bcd5d957..dde55e95c2 100644 --- a/thirdparty/freetype/src/cff/cffparse.c +++ b/thirdparty/freetype/src/cff/cffparse.c @@ -4,7 +4,7 @@ * * CFF token stream parser (body) * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -62,7 +62,7 @@ parser->num_axes = num_axes; /* allocate the stack buffer */ - if ( FT_NEW_ARRAY( parser->stack, stackSize ) ) + if ( FT_QNEW_ARRAY( parser->stack, stackSize ) ) { FT_FREE( parser->stack ); goto Exit; @@ -713,9 +713,10 @@ ( max_scaling - min_scaling ) > 9 ) { FT_TRACE1(( "cff_parse_font_matrix:" - " strange scaling values (minimum %ld, maximum %ld),\n" - " " - " using default matrix\n", min_scaling, max_scaling )); + " strange scaling values (minimum %ld, maximum %ld),\n", + min_scaling, max_scaling )); + FT_TRACE1(( " " + " using default matrix\n" )); goto Unlikely; } @@ -1515,6 +1516,7 @@ case cff_kind_fixed_thousand: FT_TRACE4(( " %f\n", (double)val / 65536 / 1000 )); + break; default: ; /* never reached */ diff --git a/thirdparty/freetype/src/cff/cffparse.h b/thirdparty/freetype/src/cff/cffparse.h index 6f3fbb37d6..a28ab52200 100644 --- a/thirdparty/freetype/src/cff/cffparse.h +++ b/thirdparty/freetype/src/cff/cffparse.h @@ -4,7 +4,7 @@ * * CFF token stream parser (specification) * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cff/cfftoken.h b/thirdparty/freetype/src/cff/cfftoken.h index 4c6a53eec1..eef30690c4 100644 --- a/thirdparty/freetype/src/cff/cfftoken.h +++ b/thirdparty/freetype/src/cff/cfftoken.h @@ -4,7 +4,7 @@ * * CFF token definitions (specification only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cff/module.mk b/thirdparty/freetype/src/cff/module.mk deleted file mode 100644 index bd728c6a34..0000000000 --- a/thirdparty/freetype/src/cff/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 CFF module definition -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += CFF_DRIVER - -define CFF_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, cff_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)cff $(ECHO_DRIVER_DESC)OpenType fonts with extension *.otf$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/cff/rules.mk b/thirdparty/freetype/src/cff/rules.mk deleted file mode 100644 index 70bb92d506..0000000000 --- a/thirdparty/freetype/src/cff/rules.mk +++ /dev/null @@ -1,75 +0,0 @@ -# -# FreeType 2 OpenType/CFF driver configuration rules -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# OpenType driver directory -# -CFF_DIR := $(SRC_DIR)/cff - - -CFF_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(CFF_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# CFF driver sources (i.e., C files) -# -CFF_DRV_SRC := $(CFF_DIR)/cffcmap.c \ - $(CFF_DIR)/cffdrivr.c \ - $(CFF_DIR)/cffgload.c \ - $(CFF_DIR)/cffload.c \ - $(CFF_DIR)/cffobjs.c \ - $(CFF_DIR)/cffparse.c - - -# CFF driver headers -# -CFF_DRV_H := $(CFF_DRV_SRC:%.c=%.h) \ - $(CFF_DIR)/cfferrs.h \ - $(CFF_DIR)/cfftoken.h - - -# CFF driver object(s) -# -# CFF_DRV_OBJ_M is used during `multi' builds -# CFF_DRV_OBJ_S is used during `single' builds -# -CFF_DRV_OBJ_M := $(CFF_DRV_SRC:$(CFF_DIR)/%.c=$(OBJ_DIR)/%.$O) -CFF_DRV_OBJ_S := $(OBJ_DIR)/cff.$O - -# CFF driver source file for single build -# -CFF_DRV_SRC_S := $(CFF_DIR)/cff.c - - -# CFF driver - single object -# -$(CFF_DRV_OBJ_S): $(CFF_DRV_SRC_S) $(CFF_DRV_SRC) $(FREETYPE_H) $(CFF_DRV_H) - $(CFF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(CFF_DRV_SRC_S)) - - -# CFF driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(CFF_DIR)/%.c $(FREETYPE_H) $(CFF_DRV_H) - $(CFF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(CFF_DRV_OBJ_S) -DRV_OBJS_M += $(CFF_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/cid/ciderrs.h b/thirdparty/freetype/src/cid/ciderrs.h index f698bb2293..2d762d9e1d 100644 --- a/thirdparty/freetype/src/cid/ciderrs.h +++ b/thirdparty/freetype/src/cid/ciderrs.h @@ -4,7 +4,7 @@ * * CID error codes (specification only). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cid/cidgload.c b/thirdparty/freetype/src/cid/cidgload.c index 54aa62f810..a46d063dfe 100644 --- a/thirdparty/freetype/src/cid/cidgload.c +++ b/thirdparty/freetype/src/cid/cidgload.c @@ -4,7 +4,7 @@ * * CID-keyed Type1 Glyph Loader (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -63,7 +63,7 @@ #endif - FT_TRACE1(( "cid_load_glyph: glyph index %d\n", glyph_index )); + FT_TRACE1(( "cid_load_glyph: glyph index %u\n", glyph_index )); #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -76,20 +76,17 @@ error = inc->funcs->get_glyph_data( inc->object, glyph_index, &glyph_data ); - if ( error ) + if ( error || glyph_data.length < cid->fd_bytes ) goto Exit; p = (FT_Byte*)glyph_data.pointer; - fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); + fd_select = cid_get_offset( &p, cid->fd_bytes ); - if ( glyph_data.length != 0 ) - { - glyph_length = (FT_ULong)( glyph_data.length - cid->fd_bytes ); - (void)FT_ALLOC( charstring, glyph_length ); - if ( !error ) - ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes, + glyph_length = glyph_data.length - cid->fd_bytes; + + if ( !FT_QALLOC( charstring, glyph_length ) ) + FT_MEM_COPY( charstring, glyph_data.pointer + cid->fd_bytes, glyph_length ); - } inc->funcs->free_glyph_data( inc->object, &glyph_data ); @@ -104,7 +101,7 @@ /* For ordinary fonts read the CID font dictionary index */ /* and charstring offset from the CIDMap. */ { - FT_UInt entry_len = (FT_UInt)( cid->fd_bytes + cid->gd_bytes ); + FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes; FT_ULong off1, off2; @@ -114,15 +111,15 @@ goto Exit; p = (FT_Byte*)stream->cursor; - fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); - off1 = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); + fd_select = cid_get_offset( &p, cid->fd_bytes ); + off1 = cid_get_offset( &p, cid->gd_bytes ); p += cid->fd_bytes; - off2 = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); + off2 = cid_get_offset( &p, cid->gd_bytes ); FT_FRAME_EXIT(); - if ( fd_select >= (FT_ULong)cid->num_dicts || - off2 > stream->size || - off1 > off2 ) + if ( fd_select >= cid->num_dicts || + off2 > stream->size || + off1 > off2 ) { FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" )); error = FT_THROW( Invalid_Offset ); @@ -130,11 +127,10 @@ } glyph_length = off2 - off1; - if ( glyph_length == 0 ) - goto Exit; - if ( FT_ALLOC( charstring, glyph_length ) ) - goto Exit; - if ( FT_STREAM_READ_AT( cid->data_offset + off1, + + if ( glyph_length == 0 || + FT_QALLOC( charstring, glyph_length ) || + FT_STREAM_READ_AT( cid->data_offset + off1, charstring, glyph_length ) ) goto Exit; } diff --git a/thirdparty/freetype/src/cid/cidgload.h b/thirdparty/freetype/src/cid/cidgload.h index da36e37e06..8b515efa01 100644 --- a/thirdparty/freetype/src/cid/cidgload.h +++ b/thirdparty/freetype/src/cid/cidgload.h @@ -4,7 +4,7 @@ * * OpenType Glyph Loader (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cid/cidload.c b/thirdparty/freetype/src/cid/cidload.c index bb9136a3df..496219de80 100644 --- a/thirdparty/freetype/src/cid/cidload.c +++ b/thirdparty/freetype/src/cid/cidload.c @@ -4,7 +4,7 @@ * * CID-keyed Type1 font loader (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -41,7 +41,7 @@ /* read a single offset */ FT_LOCAL_DEF( FT_ULong ) cid_get_offset( FT_Byte* *start, - FT_Byte offsize ) + FT_UInt offsize ) { FT_ULong result; FT_Byte* p = *start; @@ -113,7 +113,7 @@ CID_FaceDict dict; - if ( parser->num_dict < 0 || parser->num_dict >= cid->num_dicts ) + if ( parser->num_dict >= cid->num_dicts ) { FT_ERROR(( "cid_load_keyword: invalid use of `%s'\n", keyword->ident )); @@ -164,7 +164,7 @@ FT_Fixed temp_scale; - if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts ) + if ( parser->num_dict < face->cid.num_dicts ) { FT_Matrix* matrix; FT_Vector* offset; @@ -244,11 +244,11 @@ FT_Memory memory = face->root.memory; FT_Stream stream = parser->stream; FT_Error error = FT_Err_Ok; - FT_Long num_dicts; + FT_Long num_dicts, max_dicts; num_dicts = cid_parser_to_int( parser ); - if ( num_dicts < 0 ) + if ( num_dicts < 0 || num_dicts > FT_INT_MAX ) { FT_ERROR(( "parse_fd_array: invalid number of dictionaries\n" )); goto Exit; @@ -272,18 +272,18 @@ * need a `dup X' at the very beginning and a `put' at the end, so a * rough guess using 100 bytes as the minimum is justified. */ - if ( (FT_ULong)num_dicts > stream->size / 100 ) + max_dicts = (FT_Long)( stream->size / 100 ); + if ( num_dicts > max_dicts ) { FT_TRACE0(( "parse_fd_array: adjusting FDArray size" " (from %ld to %ld)\n", - num_dicts, - stream->size / 100 )); - num_dicts = (FT_Long)( stream->size / 100 ); + num_dicts, max_dicts )); + num_dicts = max_dicts; } if ( !cid->font_dicts ) { - FT_Int n; + FT_UInt n; if ( FT_NEW_ARRAY( cid->font_dicts, num_dicts ) ) @@ -322,7 +322,7 @@ CID_FaceDict dict; - if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts ) + if ( parser->num_dict < face->cid.num_dicts ) { dict = face->cid.font_dicts + parser->num_dict; @@ -345,7 +345,7 @@ CID_Parser* parser ) { #ifdef FT_DEBUG_LEVEL_TRACE - if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts ) + if ( parser->num_dict < face->cid.num_dicts ) { T1_TokenRec token; FT_UInt len; @@ -427,7 +427,7 @@ parser->num_dict++; #ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE4(( " FontDict %d", parser->num_dict )); + FT_TRACE4(( " FontDict %u", parser->num_dict )); if ( parser->num_dict > face->cid.num_dicts ) FT_TRACE4(( " (ignored)" )); FT_TRACE4(( "\n" )); @@ -517,7 +517,7 @@ FT_Memory memory = face->root.memory; FT_Stream stream = face->cid_stream; FT_Error error; - FT_Int n; + FT_UInt n; CID_Subrs subr; FT_UInt max_offsets = 0; FT_ULong* offsets = NULL; @@ -552,20 +552,20 @@ goto Fail; } - if ( FT_RENEW_ARRAY( offsets, max_offsets, new_max ) ) + if ( FT_QRENEW_ARRAY( offsets, max_offsets, new_max ) ) goto Fail; max_offsets = new_max; } /* read the subrmap's offsets */ - if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || - FT_FRAME_ENTER( ( num_subrs + 1 ) * (FT_UInt)dict->sd_bytes ) ) + if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || + FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) ) goto Fail; p = (FT_Byte*)stream->cursor; for ( count = 0; count <= num_subrs; count++ ) - offsets[count] = cid_get_offset( &p, (FT_Byte)dict->sd_bytes ); + offsets[count] = cid_get_offset( &p, dict->sd_bytes ); FT_FRAME_EXIT(); @@ -589,12 +589,12 @@ /* allocate, and read them */ data_len = offsets[num_subrs] - offsets[0]; - if ( FT_NEW_ARRAY( subr->code, num_subrs + 1 ) || - FT_ALLOC( subr->code[0], data_len ) ) + if ( FT_QNEW_ARRAY( subr->code, num_subrs + 1 ) || + FT_QALLOC( subr->code[0], data_len ) ) goto Fail; if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) || - FT_STREAM_READ( subr->code[0], data_len ) ) + FT_STREAM_READ( subr->code[0], data_len ) ) goto Fail; /* set up pointers */ @@ -665,17 +665,18 @@ static FT_Error - cid_hex_to_binary( FT_Byte* data, - FT_ULong data_len, - FT_ULong offset, - CID_Face face ) + cid_hex_to_binary( FT_Byte* data, + FT_ULong data_len, + FT_ULong offset, + CID_Face face, + FT_ULong* data_written ) { FT_Stream stream = face->root.stream; FT_Error error; FT_Byte buffer[256]; FT_Byte *p, *plimit; - FT_Byte *d, *dlimit; + FT_Byte *d = data, *dlimit; FT_Byte val; FT_Bool upper_nibble, done; @@ -684,7 +685,6 @@ if ( FT_STREAM_SEEK( offset ) ) goto Exit; - d = data; dlimit = d + data_len; p = buffer; plimit = p; @@ -758,6 +758,7 @@ error = FT_Err_Ok; Exit: + *data_written = (FT_ULong)( d - data ); return error; } @@ -770,12 +771,11 @@ CID_Parser* parser; FT_Memory memory = face->root.memory; FT_Error error; - FT_Int n; + FT_UInt n; CID_FaceInfo cid = &face->cid; FT_ULong binary_length; - FT_ULong entry_len; cid_init_loader( &loader, face ); @@ -803,8 +803,8 @@ if ( parser->binary_length > face->root.stream->size - parser->data_offset ) { - FT_TRACE0(( "cid_face_open: adjusting length of binary data\n" - " (from %ld to %ld bytes)\n", + FT_TRACE0(( "cid_face_open: adjusting length of binary data\n" )); + FT_TRACE0(( " (from %lu to %lu bytes)\n", parser->binary_length, face->root.stream->size - parser->data_offset )); parser->binary_length = face->root.stream->size - @@ -812,15 +812,16 @@ } /* we must convert the data section from hexadecimal to binary */ - if ( FT_ALLOC( face->binary_data, parser->binary_length ) || + if ( FT_QALLOC( face->binary_data, parser->binary_length ) || FT_SET_ERROR( cid_hex_to_binary( face->binary_data, parser->binary_length, parser->data_offset, - face ) ) ) + face, + &binary_length ) ) ) goto Exit; FT_Stream_OpenMemory( face->cid_stream, - face->binary_data, parser->binary_length ); + face->binary_data, binary_length ); cid->data_offset = 0; } else @@ -831,10 +832,10 @@ /* sanity tests */ - if ( cid->fd_bytes < 0 || cid->gd_bytes < 1 ) + if ( cid->gd_bytes == 0 ) { FT_ERROR(( "cid_face_open:" - " Invalid `FDBytes' or `GDBytes' value\n" )); + " Invalid `GDBytes' value\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } @@ -843,15 +844,32 @@ if ( cid->fd_bytes > 4 || cid->gd_bytes > 4 ) { FT_ERROR(( "cid_face_open:" - " Values of `FDBytes' or `GDBytes' larger than 4\n" - " " + " Values of `FDBytes' or `GDBytes' larger than 4\n" )); + FT_ERROR(( " " " are not supported\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } binary_length = face->cid_stream->size - cid->data_offset; - entry_len = (FT_ULong)( cid->fd_bytes + cid->gd_bytes ); + + if ( cid->cidmap_offset > binary_length ) + { + FT_ERROR(( "cid_face_open: Invalid `CIDMapOffset' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* the initial pre-check prevents the multiplication overflow */ + if ( cid->cid_count > FT_ULONG_MAX / 8 || + cid->cid_count * ( cid->fd_bytes + cid->gd_bytes ) > + binary_length - cid->cidmap_offset ) + { + FT_ERROR(( "cid_face_open: Invalid `CIDCount' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + for ( n = 0; n < cid->num_dicts; n++ ) { @@ -877,8 +895,7 @@ dict->private_dict.blue_fuzz = 1; } - if ( dict->sd_bytes < 0 || - ( dict->num_subrs && dict->sd_bytes < 1 ) ) + if ( dict->num_subrs && dict->sd_bytes == 0 ) { FT_ERROR(( "cid_face_open: Invalid `SDBytes' value\n" )); error = FT_THROW( Invalid_File_Format ); @@ -901,11 +918,10 @@ goto Exit; } - /* `num_subrs' is scanned as a signed integer */ - if ( (FT_Int)dict->num_subrs < 0 || - ( dict->sd_bytes && - dict->num_subrs > ( binary_length - dict->subrmap_offset ) / - (FT_UInt)dict->sd_bytes ) ) + /* the initial pre-check prevents the multiplication overflow */ + if ( dict->num_subrs > FT_UINT_MAX / 4 || + dict->num_subrs * dict->sd_bytes > + binary_length - dict->subrmap_offset ) { FT_ERROR(( "cid_face_open: Invalid `SubrCount' value\n" )); error = FT_THROW( Invalid_File_Format ); @@ -913,22 +929,6 @@ } } - if ( cid->cidmap_offset > binary_length ) - { - FT_ERROR(( "cid_face_open: Invalid `CIDMapOffset' value\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - if ( entry_len && - cid->cid_count > - ( binary_length - cid->cidmap_offset ) / entry_len ) - { - FT_ERROR(( "cid_face_open: Invalid `CIDCount' value\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - /* we can now safely proceed */ error = cid_read_subrs( face ); diff --git a/thirdparty/freetype/src/cid/cidload.h b/thirdparty/freetype/src/cid/cidload.h index 06fb9ef476..ee1d486505 100644 --- a/thirdparty/freetype/src/cid/cidload.h +++ b/thirdparty/freetype/src/cid/cidload.h @@ -4,7 +4,7 @@ * * CID-keyed Type1 font loader (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -37,7 +37,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_ULong ) cid_get_offset( FT_Byte** start, - FT_Byte offsize ); + FT_UInt offsize ); FT_LOCAL( FT_Error ) cid_face_open( CID_Face face, diff --git a/thirdparty/freetype/src/cid/cidobjs.c b/thirdparty/freetype/src/cid/cidobjs.c index 04b295eb8f..e3c29c22f6 100644 --- a/thirdparty/freetype/src/cid/cidobjs.c +++ b/thirdparty/freetype/src/cid/cidobjs.c @@ -4,7 +4,7 @@ * * CID objects manager (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -157,10 +157,14 @@ cid_size_request( FT_Size size, FT_Size_Request req ) { + FT_Error error; + PSH_Globals_Funcs funcs; - FT_Request_Metrics( size->face, req ); + error = FT_Request_Metrics( size->face, req ); + if ( error ) + goto Exit; funcs = cid_size_get_globals_funcs( (CID_Size)size ); @@ -170,7 +174,8 @@ size->metrics.y_scale, 0, 0 ); - return FT_Err_Ok; + Exit: + return error; } @@ -211,7 +216,7 @@ /* release subrs */ if ( face->subrs ) { - FT_Int n; + FT_UInt n; for ( n = 0; n < cid->num_dicts; n++ ) @@ -479,11 +484,7 @@ /* set default property values, cf. `ftt1drv.h' */ -#ifdef T1_CONFIG_OPTION_OLD_ENGINE - driver->hinting_engine = FT_HINTING_FREETYPE; -#else driver->hinting_engine = FT_HINTING_ADOBE; -#endif driver->no_stem_darkening = TRUE; diff --git a/thirdparty/freetype/src/cid/cidobjs.h b/thirdparty/freetype/src/cid/cidobjs.h index 6ae3061379..32f59cbcce 100644 --- a/thirdparty/freetype/src/cid/cidobjs.h +++ b/thirdparty/freetype/src/cid/cidobjs.h @@ -4,7 +4,7 @@ * * CID objects manager (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cid/cidparse.c b/thirdparty/freetype/src/cid/cidparse.c index 1fc098b448..852c9b6b96 100644 --- a/thirdparty/freetype/src/cid/cidparse.c +++ b/thirdparty/freetype/src/cid/cidparse.c @@ -4,7 +4,7 @@ * * CID-keyed Type1 parser (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -73,7 +73,11 @@ /* first of all, check the font format in the header */ if ( FT_FRAME_ENTER( 31 ) ) + { + FT_TRACE2(( " not a CID-keyed font\n" )); + error = FT_THROW( Unknown_File_Format ); goto Exit; + } if ( ft_strncmp( (char *)stream->cursor, "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) ) @@ -181,7 +185,7 @@ parser->root.base = parser->postscript; parser->root.cursor = parser->postscript; parser->root.limit = parser->root.cursor + ps_len; - parser->num_dict = -1; + parser->num_dict = FT_UINT_MAX; /* Finally, we check whether `StartData' or `/sfnts' was real -- */ /* it could be in a comment or string. We also get the arguments */ diff --git a/thirdparty/freetype/src/cid/cidparse.h b/thirdparty/freetype/src/cid/cidparse.h index 0b49bebf48..fbc437bc38 100644 --- a/thirdparty/freetype/src/cid/cidparse.h +++ b/thirdparty/freetype/src/cid/cidparse.h @@ -4,7 +4,7 @@ * * CID-keyed Type1 parser (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -78,7 +78,7 @@ FT_BEGIN_HEADER FT_ULong binary_length; CID_FaceInfo cid; - FT_Int num_dict; + FT_UInt num_dict; } CID_Parser; diff --git a/thirdparty/freetype/src/cid/cidriver.c b/thirdparty/freetype/src/cid/cidriver.c index d08cea1d7e..a0898dfa2f 100644 --- a/thirdparty/freetype/src/cid/cidriver.c +++ b/thirdparty/freetype/src/cid/cidriver.c @@ -4,7 +4,7 @@ * * CID driver interface (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cid/cidriver.h b/thirdparty/freetype/src/cid/cidriver.h index 0fc8ed37bf..3ff5f78e11 100644 --- a/thirdparty/freetype/src/cid/cidriver.h +++ b/thirdparty/freetype/src/cid/cidriver.h @@ -4,7 +4,7 @@ * * High-level CID driver interface (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cid/cidtoken.h b/thirdparty/freetype/src/cid/cidtoken.h index e9f068bb50..84c8258014 100644 --- a/thirdparty/freetype/src/cid/cidtoken.h +++ b/thirdparty/freetype/src/cid/cidtoken.h @@ -4,7 +4,7 @@ * * CID token definitions (specification only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/cid/module.mk b/thirdparty/freetype/src/cid/module.mk deleted file mode 100644 index 9fb02235e6..0000000000 --- a/thirdparty/freetype/src/cid/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 CID module definition -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += TYPE1CID_DRIVER - -define TYPE1CID_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, t1cid_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)cid $(ECHO_DRIVER_DESC)Postscript CID-keyed fonts, no known extension$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/cid/rules.mk b/thirdparty/freetype/src/cid/rules.mk deleted file mode 100644 index 94f663c80e..0000000000 --- a/thirdparty/freetype/src/cid/rules.mk +++ /dev/null @@ -1,73 +0,0 @@ -# -# FreeType 2 CID driver configuration rules -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# CID driver directory -# -CID_DIR := $(SRC_DIR)/cid - - -CID_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(CID_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# CID driver sources (i.e., C files) -# -CID_DRV_SRC := $(CID_DIR)/cidparse.c \ - $(CID_DIR)/cidload.c \ - $(CID_DIR)/cidriver.c \ - $(CID_DIR)/cidgload.c \ - $(CID_DIR)/cidobjs.c - -# CID driver headers -# -CID_DRV_H := $(CID_DRV_SRC:%.c=%.h) \ - $(CID_DIR)/cidtoken.h \ - $(CID_DIR)/ciderrs.h - - -# CID driver object(s) -# -# CID_DRV_OBJ_M is used during `multi' builds -# CID_DRV_OBJ_S is used during `single' builds -# -CID_DRV_OBJ_M := $(CID_DRV_SRC:$(CID_DIR)/%.c=$(OBJ_DIR)/%.$O) -CID_DRV_OBJ_S := $(OBJ_DIR)/type1cid.$O - -# CID driver source file for single build -# -CID_DRV_SRC_S := $(CID_DIR)/type1cid.c - - -# CID driver - single object -# -$(CID_DRV_OBJ_S): $(CID_DRV_SRC_S) $(CID_DRV_SRC) $(FREETYPE_H) $(CID_DRV_H) - $(CID_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(CID_DRV_SRC_S)) - - -# CID driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(CID_DIR)/%.c $(FREETYPE_H) $(CID_DRV_H) - $(CID_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(CID_DRV_OBJ_S) -DRV_OBJS_M += $(CID_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/cid/type1cid.c b/thirdparty/freetype/src/cid/type1cid.c index 082e8bfe5b..5405ecffc8 100644 --- a/thirdparty/freetype/src/cid/type1cid.c +++ b/thirdparty/freetype/src/cid/type1cid.c @@ -4,7 +4,7 @@ * * FreeType OpenType driver component (body only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/gxvalid/README b/thirdparty/freetype/src/gxvalid/README index 2a32bab204..7fb0296282 100644 --- a/thirdparty/freetype/src/gxvalid/README +++ b/thirdparty/freetype/src/gxvalid/README @@ -518,7 +518,7 @@ gxvalid: TrueType GX validator ------------------------------------------------------------------------ -Copyright (C) 2004-2020 by +Copyright (C) 2004-2021 by suzuki toshiya, Masatake YAMATO, Red hat K.K., David Turner, Robert Wilhelm, and Werner Lemberg. diff --git a/thirdparty/freetype/src/gxvalid/gxvalid.c b/thirdparty/freetype/src/gxvalid/gxvalid.c index 683b8a6972..309d517443 100644 --- a/thirdparty/freetype/src/gxvalid/gxvalid.c +++ b/thirdparty/freetype/src/gxvalid/gxvalid.c @@ -4,7 +4,7 @@ * * FreeType validator for TrueTypeGX/AAT tables (body only). * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/gxvalid/gxvalid.h b/thirdparty/freetype/src/gxvalid/gxvalid.h index ff2812da20..2c41c28668 100644 --- a/thirdparty/freetype/src/gxvalid/gxvalid.h +++ b/thirdparty/freetype/src/gxvalid/gxvalid.h @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT table validation (specification only). * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/gxvalid/gxvbsln.c b/thirdparty/freetype/src/gxvalid/gxvbsln.c index ac58d4615c..af69cb51df 100644 --- a/thirdparty/freetype/src/gxvalid/gxvbsln.c +++ b/thirdparty/freetype/src/gxvalid/gxvbsln.c @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT bsln table validation (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/gxvalid/gxvcommn.c b/thirdparty/freetype/src/gxvalid/gxvcommn.c index ead0f24cd3..18e42b0cd8 100644 --- a/thirdparty/freetype/src/gxvalid/gxvcommn.c +++ b/thirdparty/freetype/src/gxvalid/gxvcommn.c @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT common tables validation (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * @@ -46,16 +46,11 @@ /*************************************************************************/ /*************************************************************************/ - static int - gxv_compare_ushort_offset( FT_UShort* a, - FT_UShort* b ) + FT_COMPARE_DEF( int ) + gxv_compare_ushort_offset( const void* a, + const void* b ) { - if ( *a < *b ) - return -1; - else if ( *a > *b ) - return 1; - else - return 0; + return *(FT_UShort*)a - *(FT_UShort*)b; } @@ -78,7 +73,7 @@ buff[nmemb] = limit; ft_qsort( buff, ( nmemb + 1 ), sizeof ( FT_UShort ), - ( int(*)(const void*, const void*) )gxv_compare_ushort_offset ); + gxv_compare_ushort_offset ); if ( buff[nmemb] > limit ) FT_INVALID_OFFSET; @@ -111,13 +106,17 @@ /*************************************************************************/ /*************************************************************************/ - static int - gxv_compare_ulong_offset( FT_ULong* a, - FT_ULong* b ) + FT_COMPARE_DEF( int ) + gxv_compare_ulong_offset( const void* a, + const void* b ) { - if ( *a < *b ) + FT_ULong a_ = *(FT_ULong*)a; + FT_ULong b_ = *(FT_ULong*)b; + + + if ( a_ < b_ ) return -1; - else if ( *a > *b ) + else if ( a_ > b_ ) return 1; else return 0; @@ -143,7 +142,7 @@ buff[nmemb] = limit; ft_qsort( buff, ( nmemb + 1 ), sizeof ( FT_ULong ), - ( int(*)(const void*, const void*) )gxv_compare_ulong_offset ); + gxv_compare_ulong_offset ); if ( buff[nmemb] > limit ) FT_INVALID_OFFSET; @@ -439,7 +438,7 @@ GXV_LIMIT_CHECK( 2 ); if ( p + 2 >= limit ) /* some fonts have too-short fmt0 array */ { - GXV_TRACE(( "too short, glyphs %d - %d are missing\n", + GXV_TRACE(( "too short, glyphs %d - %ld are missing\n", i, gxvalid->face->num_glyphs )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); break; @@ -534,7 +533,7 @@ if ( lastGlyph < firstGlyph ) { - GXV_TRACE(( "reverse ordered range specification at unit %d:", + GXV_TRACE(( "reverse ordered range specification at unit %d:" " lastGlyph %d < firstGlyph %d ", unit, lastGlyph, firstGlyph )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); @@ -605,7 +604,7 @@ if ( lastGlyph < firstGlyph ) { - GXV_TRACE(( "reverse ordered range specification at unit %d:", + GXV_TRACE(( "reverse ordered range specification at unit %d:" " lastGlyph %d < firstGlyph %d ", unit, lastGlyph, firstGlyph )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); @@ -825,7 +824,7 @@ face = gxvalid->face; if ( face->num_glyphs < gid ) { - GXV_TRACE(( " gxv_glyphid_check() gid overflow: num_glyphs %d < %d\n", + GXV_TRACE(( " gxv_glyphid_check() gid overflow: num_glyphs %ld < %d\n", face->num_glyphs, gid )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); } @@ -1419,7 +1418,7 @@ GXV_NAME_ENTER( "XStateArray" ); GXV_TRACE(( "parse % 3d bytes by stateSize=% 3d maxClassID=% 3d\n", - (int)(*length_p), stateSize, (int)(maxClassID) )); + (int)(*length_p), (int)stateSize, (int)(maxClassID) )); /* * 2 states are predefined and must be described: @@ -1493,9 +1492,11 @@ state = (FT_UShort)( newState_idx / ( 1 + maxClassID ) ); if ( 0 != ( newState_idx % ( 1 + maxClassID ) ) ) { - FT_TRACE4(( "-> new state = %d (supposed)\n" - "but newState index 0x%04x is not aligned to %d-classes\n", - state, newState_idx, 1 + maxClassID )); + FT_TRACE4(( "-> new state = %d (supposed)\n", + state )); + FT_TRACE4(( "but newState index 0x%04x" + " is not aligned to %d-classes\n", + newState_idx, 1 + maxClassID )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); } @@ -1581,10 +1582,10 @@ stateArray = FT_NEXT_ULONG( p ); entryTable = FT_NEXT_ULONG( p ); - GXV_TRACE(( "nClasses =0x%08x\n", gxvalid->xstatetable.nClasses )); - GXV_TRACE(( "offset to classTable=0x%08x\n", classTable )); - GXV_TRACE(( "offset to stateArray=0x%08x\n", stateArray )); - GXV_TRACE(( "offset to entryTable=0x%08x\n", entryTable )); + GXV_TRACE(( "nClasses =0x%08lx\n", gxvalid->xstatetable.nClasses )); + GXV_TRACE(( "offset to classTable=0x%08lx\n", classTable )); + GXV_TRACE(( "offset to stateArray=0x%08lx\n", stateArray )); + GXV_TRACE(( "offset to entryTable=0x%08lx\n", entryTable )); if ( gxvalid->xstatetable.nClasses > 0xFFFFU ) FT_INVALID_DATA; diff --git a/thirdparty/freetype/src/gxvalid/gxvcommn.h b/thirdparty/freetype/src/gxvalid/gxvcommn.h index 59d149215c..b79b641142 100644 --- a/thirdparty/freetype/src/gxvalid/gxvcommn.h +++ b/thirdparty/freetype/src/gxvalid/gxvcommn.h @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT common tables validation (specification). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * @@ -61,8 +61,11 @@ FT_BEGIN_HEADER #undef GXV_LOAD_UNUSED_VARS /* debug purpose */ -#define IS_PARANOID_VALIDATION ( gxvalid->root->level >= FT_VALIDATE_PARANOID ) -#define GXV_SET_ERR_IF_PARANOID( err ) { if ( IS_PARANOID_VALIDATION ) ( err ); } +#define IS_PARANOID_VALIDATION \ + ( gxvalid->root->level >= FT_VALIDATE_PARANOID ) +#define GXV_SET_ERR_IF_PARANOID( err ) \ + do { if ( IS_PARANOID_VALIDATION ) ( err ); } while ( 0 ) + /*************************************************************************/ /*************************************************************************/ @@ -261,17 +264,17 @@ FT_BEGIN_HEADER } GXV_ValidatorRec; -#define GXV_TABLE_DATA( tag, field ) \ +#define GXV_TABLE_DATA( tag, field ) \ ( ( (GXV_ ## tag ## _Data)gxvalid->table_data )->field ) #undef FT_INVALID_ -#define FT_INVALID_( _error ) \ +#define FT_INVALID_( _error ) \ ft_validator_error( gxvalid->root, FT_THROW( _error ) ) -#define GXV_LIMIT_CHECK( _count ) \ - FT_BEGIN_STMNT \ +#define GXV_LIMIT_CHECK( _count ) \ + FT_BEGIN_STMNT \ if ( p + _count > ( limit? limit : gxvalid->root->limit ) ) \ - FT_INVALID_TOO_SHORT; \ + FT_INVALID_TOO_SHORT; \ FT_END_STMNT @@ -279,19 +282,19 @@ FT_BEGIN_HEADER #define GXV_INIT gxvalid->debug_indent = 0 -#define GXV_NAME_ENTER( name ) \ - FT_BEGIN_STMNT \ - gxvalid->debug_indent += 2; \ - FT_TRACE4(( "%*.s", gxvalid->debug_indent, 0 )); \ - FT_TRACE4(( "%s table\n", name )); \ +#define GXV_NAME_ENTER( name ) \ + FT_BEGIN_STMNT \ + gxvalid->debug_indent += 2; \ + FT_TRACE4(( "%*.s", gxvalid->debug_indent, "" )); \ + FT_TRACE4(( "%s table\n", name )); \ FT_END_STMNT #define GXV_EXIT gxvalid->debug_indent -= 2 -#define GXV_TRACE( s ) \ - FT_BEGIN_STMNT \ - FT_TRACE4(( "%*.s", gxvalid->debug_indent, 0 )); \ - FT_TRACE4( s ); \ +#define GXV_TRACE( s ) \ + FT_BEGIN_STMNT \ + FT_TRACE4(( "%*.s", gxvalid->debug_indent, "" )); \ + FT_TRACE4( s ); \ FT_END_STMNT #else /* !FT_DEBUG_LEVEL_TRACE */ diff --git a/thirdparty/freetype/src/gxvalid/gxverror.h b/thirdparty/freetype/src/gxvalid/gxverror.h index 5d8f0b6806..d20d395680 100644 --- a/thirdparty/freetype/src/gxvalid/gxverror.h +++ b/thirdparty/freetype/src/gxvalid/gxverror.h @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT validation module error codes (specification only). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/gxvalid/gxvfeat.c b/thirdparty/freetype/src/gxvalid/gxvfeat.c index 400ec8a3fb..0a8e2f201a 100644 --- a/thirdparty/freetype/src/gxvalid/gxvfeat.c +++ b/thirdparty/freetype/src/gxvalid/gxvfeat.c @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT feat table validation (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * @@ -90,7 +90,7 @@ if ( feature >= gxv_feat_registry_length ) { - GXV_TRACE(( "feature number %d is out of range %d\n", + GXV_TRACE(( "feature number %d is out of range %lu\n", feature, gxv_feat_registry_length )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); goto Exit; diff --git a/thirdparty/freetype/src/gxvalid/gxvfeat.h b/thirdparty/freetype/src/gxvalid/gxvfeat.h index 435dcefb09..f6d28fa71c 100644 --- a/thirdparty/freetype/src/gxvalid/gxvfeat.h +++ b/thirdparty/freetype/src/gxvalid/gxvfeat.h @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT feat table validation (specification). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/gxvalid/gxvfgen.c b/thirdparty/freetype/src/gxvalid/gxvfgen.c index fe05a6f3a1..b47cd0f7ba 100644 --- a/thirdparty/freetype/src/gxvalid/gxvfgen.c +++ b/thirdparty/freetype/src/gxvalid/gxvfgen.c @@ -5,7 +5,7 @@ * Generate feature registry data for gxv `feat' validator. * This program is derived from gxfeatreg.c in gxlayout. * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * Masatake YAMATO and Redhat K.K. * * This file may only be used, diff --git a/thirdparty/freetype/src/gxvalid/gxvjust.c b/thirdparty/freetype/src/gxvalid/gxvjust.c index 3c7f1f9534..ec289b8ebf 100644 --- a/thirdparty/freetype/src/gxvalid/gxvjust.c +++ b/thirdparty/freetype/src/gxvalid/gxvjust.c @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT just table validation (body). * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * @@ -78,7 +78,7 @@ return; GXV_TRACE(( "just table includes too large %s" - " GID=%d > %d (in maxp)\n", + " GID=%d > %ld (in maxp)\n", msg_tag, gid, gxvalid->face->num_glyphs )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); } @@ -140,7 +140,7 @@ count = FT_NEXT_ULONG( p ); for ( i = 0; i < count; i++ ) { - GXV_TRACE(( "validating wdc pair %d/%d\n", i + 1, count )); + GXV_TRACE(( "validating wdc pair %lu/%lu\n", i + 1, count )); gxv_just_wdp_entry_validate( p, limit, gxvalid ); p += gxvalid->subtable_length; } @@ -206,7 +206,8 @@ if ( lowerLimit >= upperLimit ) { GXV_TRACE(( "just table includes invalid range spec:" - " lowerLimit(%d) > upperLimit(%d)\n" )); + " lowerLimit(%ld) > upperLimit(%ld)\n", + lowerLimit, upperLimit )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); } @@ -294,14 +295,14 @@ gxvalid->subtable_length = (FT_ULong)( p - table ); if ( variantsAxis != 0x64756374L ) /* 'duct' */ - GXV_TRACE(( "variantsAxis 0x%08x is non default value", + GXV_TRACE(( "variantsAxis 0x%08lx is non default value", variantsAxis )); if ( minimumLimit > noStretchValue ) - GXV_TRACE(( "type4:minimumLimit 0x%08x > noStretchValue 0x%08x\n", + GXV_TRACE(( "type4:minimumLimit 0x%08lx > noStretchValue 0x%08lx\n", minimumLimit, noStretchValue )); else if ( noStretchValue > maximumLimit ) - GXV_TRACE(( "type4:noStretchValue 0x%08x > maximumLimit 0x%08x\n", + GXV_TRACE(( "type4:noStretchValue 0x%08lx > maximumLimit 0x%08lx\n", noStretchValue, maximumLimit )); else if ( !IS_PARANOID_VALIDATION ) return; @@ -389,7 +390,7 @@ GXV_LIMIT_CHECK( 4 ); actionCount = FT_NEXT_ULONG( p ); - GXV_TRACE(( "actionCount = %d\n", actionCount )); + GXV_TRACE(( "actionCount = %lu\n", actionCount )); for ( i = 0; i < actionCount; i++ ) { @@ -514,14 +515,14 @@ coverage = FT_NEXT_USHORT( p ); subFeatureFlags = FT_NEXT_ULONG( p ); - GXV_TRACE(( " justClassTable: coverage = 0x%04x (%s) ", coverage )); + GXV_TRACE(( " justClassTable: coverage = 0x%04x ", coverage )); if ( ( coverage & 0x4000 ) == 0 ) GXV_TRACE(( "ascending\n" )); else GXV_TRACE(( "descending\n" )); if ( subFeatureFlags ) - GXV_TRACE(( " justClassTable: nonzero value (0x%08x)" + GXV_TRACE(( " justClassTable: nonzero value (0x%08lx)" " in unused subFeatureFlags\n", subFeatureFlags )); gxvalid->statetable.optdata = NULL; @@ -684,7 +685,7 @@ /* Version 1.0 (always:2000) */ - GXV_TRACE(( " (version = 0x%08x)\n", version )); + GXV_TRACE(( " (version = 0x%08lx)\n", version )); if ( version != 0x00010000UL ) FT_INVALID_FORMAT; diff --git a/thirdparty/freetype/src/gxvalid/gxvkern.c b/thirdparty/freetype/src/gxvalid/gxvkern.c index cc0b3dfcb4..542e8bc095 100644 --- a/thirdparty/freetype/src/gxvalid/gxvkern.c +++ b/thirdparty/freetype/src/gxvalid/gxvkern.c @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT kern table validation (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * @@ -487,7 +487,7 @@ if ( gxvalid->face->num_glyphs != glyphCount ) { - GXV_TRACE(( "maxGID=%d, but glyphCount=%d\n", + GXV_TRACE(( "maxGID=%ld, but glyphCount=%d\n", gxvalid->face->num_glyphs, glyphCount )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); } @@ -745,7 +745,7 @@ #ifdef GXV_LOAD_TRACE_VARS FT_UShort version = 0; /* MS only: subtable version, unused */ #endif - FT_ULong length; /* MS: 16bit, Apple: 32bit*/ + FT_ULong length; /* MS: 16bit, Apple: 32bit */ FT_UShort coverage; #ifdef GXV_LOAD_TRACE_VARS FT_UShort tupleIndex = 0; /* Apple only */ @@ -772,7 +772,7 @@ tupleIndex = 0; #endif GXV_TRACE(( "Subtable version = %d\n", version )); - GXV_TRACE(( "Subtable length = %d\n", length )); + GXV_TRACE(( "Subtable length = %lu\n", length )); break; case KERN_DIALECT_APPLE: @@ -783,7 +783,7 @@ #ifdef GXV_LOAD_TRACE_VARS tupleIndex = 0; #endif - GXV_TRACE(( "Subtable length = %d\n", length )); + GXV_TRACE(( "Subtable length = %lu\n", length )); if ( KERN_IS_NEW( gxvalid ) ) { @@ -800,7 +800,7 @@ default: length = u16[1]; GXV_TRACE(( "cannot detect subtable dialect, " - "just skip %d byte\n", length )); + "just skip %lu byte\n", length )); goto Exit; } @@ -884,7 +884,7 @@ for ( i = 0; i < nTables; i++ ) { - GXV_TRACE(( "validating subtable %d/%d\n", i, nTables )); + GXV_TRACE(( "validating subtable %d/%lu\n", i, nTables )); /* p should be 32bit-aligned? */ gxv_kern_subtable_validate( p, 0, gxvalid ); p += gxvalid->subtable_length; diff --git a/thirdparty/freetype/src/gxvalid/gxvlcar.c b/thirdparty/freetype/src/gxvalid/gxvlcar.c index 82ac1907ab..9db839ba8a 100644 --- a/thirdparty/freetype/src/gxvalid/gxvlcar.c +++ b/thirdparty/freetype/src/gxvalid/gxvlcar.c @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT lcar table validation (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/gxvalid/gxvmod.c b/thirdparty/freetype/src/gxvalid/gxvmod.c index a467e87131..1a11426ccb 100644 --- a/thirdparty/freetype/src/gxvalid/gxvmod.c +++ b/thirdparty/freetype/src/gxvalid/gxvmod.c @@ -4,7 +4,7 @@ * * FreeType's TrueTypeGX/AAT validation module implementation (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * @@ -62,7 +62,7 @@ if ( error ) goto Exit; - if ( FT_ALLOC( *table, *table_len ) ) + if ( FT_QALLOC( *table, *table_len ) ) goto Exit; error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len ); @@ -76,27 +76,31 @@ FT_Byte* volatile _sfnt = NULL; \ FT_ULong len_ ## _sfnt = 0 -#define GXV_TABLE_LOAD( _sfnt ) \ - if ( ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) && \ - ( gx_flags & FT_VALIDATE_ ## _sfnt ) ) \ - { \ - error = gxv_load_table( face, TTAG_ ## _sfnt, \ - &_sfnt, &len_ ## _sfnt ); \ - if ( error ) \ - goto Exit; \ - } - -#define GXV_TABLE_VALIDATE( _sfnt ) \ - if ( _sfnt ) \ - { \ - ft_validator_init( &valid, _sfnt, _sfnt + len_ ## _sfnt, \ - FT_VALIDATE_DEFAULT ); \ - if ( ft_setjmp( valid.jump_buffer ) == 0 ) \ - gxv_ ## _sfnt ## _validate( _sfnt, face, &valid ); \ - error = valid.error; \ - if ( error ) \ - goto Exit; \ - } +#define GXV_TABLE_LOAD( _sfnt ) \ + FT_BEGIN_STMNT \ + if ( ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) && \ + ( gx_flags & FT_VALIDATE_ ## _sfnt ) ) \ + { \ + error = gxv_load_table( face, TTAG_ ## _sfnt, \ + &_sfnt, &len_ ## _sfnt ); \ + if ( error ) \ + goto Exit; \ + } \ + FT_END_STMNT + +#define GXV_TABLE_VALIDATE( _sfnt ) \ + FT_BEGIN_STMNT \ + if ( _sfnt ) \ + { \ + ft_validator_init( &valid, _sfnt, _sfnt + len_ ## _sfnt, \ + FT_VALIDATE_DEFAULT ); \ + if ( ft_setjmp( valid.jump_buffer ) == 0 ) \ + gxv_ ## _sfnt ## _validate( _sfnt, face, &valid ); \ + error = valid.error; \ + if ( error ) \ + goto Exit; \ + } \ + FT_END_STMNT #define GXV_TABLE_SET( _sfnt ) \ if ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) \ diff --git a/thirdparty/freetype/src/gxvalid/gxvmod.h b/thirdparty/freetype/src/gxvalid/gxvmod.h index f2982c96c2..90e0c10a28 100644 --- a/thirdparty/freetype/src/gxvalid/gxvmod.h +++ b/thirdparty/freetype/src/gxvalid/gxvmod.h @@ -5,7 +5,7 @@ * FreeType's TrueTypeGX/AAT validation module implementation * (specification). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/gxvalid/gxvmort.c b/thirdparty/freetype/src/gxvalid/gxvmort.c index aae7f01a89..d0db7f4d2d 100644 --- a/thirdparty/freetype/src/gxvalid/gxvmort.c +++ b/thirdparty/freetype/src/gxvalid/gxvmort.c @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT mort table validation (body). * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * @@ -288,7 +288,7 @@ for ( i = 0; i < nChains; i++ ) { - GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains )); + GXV_TRACE(( "validating chain %lu/%lu\n", i + 1, nChains )); GXV_32BIT_ALIGNMENT_VALIDATE( p - table ); gxv_mort_chain_validate( p, limit, gxvalid ); p += gxvalid->subtable_length; diff --git a/thirdparty/freetype/src/gxvalid/gxvmort.h b/thirdparty/freetype/src/gxvalid/gxvmort.h index 7237c58254..de5ab4ef02 100644 --- a/thirdparty/freetype/src/gxvalid/gxvmort.h +++ b/thirdparty/freetype/src/gxvalid/gxvmort.h @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT common definition for mort table (specification). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/gxvalid/gxvmort0.c b/thirdparty/freetype/src/gxvalid/gxvmort0.c index d452c1ccaa..0c695aa4c7 100644 --- a/thirdparty/freetype/src/gxvalid/gxvmort0.c +++ b/thirdparty/freetype/src/gxvalid/gxvmort0.c @@ -5,7 +5,7 @@ * TrueTypeGX/AAT mort table validation * body for type0 (Indic Script Rearrangement) subtable. * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/gxvalid/gxvmort1.c b/thirdparty/freetype/src/gxvalid/gxvmort1.c index d743f89f6e..0af22362f1 100644 --- a/thirdparty/freetype/src/gxvalid/gxvmort1.c +++ b/thirdparty/freetype/src/gxvalid/gxvmort1.c @@ -5,7 +5,7 @@ * TrueTypeGX/AAT mort table validation * body for type1 (Contextual Substitution) subtable. * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/gxvalid/gxvmort2.c b/thirdparty/freetype/src/gxvalid/gxvmort2.c index 9e69e1269d..73f418ea1e 100644 --- a/thirdparty/freetype/src/gxvalid/gxvmort2.c +++ b/thirdparty/freetype/src/gxvalid/gxvmort2.c @@ -5,7 +5,7 @@ * TrueTypeGX/AAT mort table validation * body for type2 (Ligature Substitution) subtable. * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * @@ -152,7 +152,7 @@ GXV_32BIT_ALIGNMENT_VALIDATE( ligActionOffset ); if ( p < lat_base ) { - GXV_TRACE(( "too short offset 0x%04x: p < lat_base (%d byte rewind)\n", + GXV_TRACE(( "too short offset 0x%04x: p < lat_base (%ld byte rewind)\n", ligActionOffset, lat_base - p )); /* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */ @@ -160,7 +160,7 @@ } else if ( lat_limit < p ) { - GXV_TRACE(( "too large offset 0x%04x: lat_limit < p (%d byte overrun)\n", + GXV_TRACE(( "too large offset 0x%04x: lat_limit < p (%ld byte overrun)\n", ligActionOffset, p - lat_limit )); /* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */ @@ -187,17 +187,17 @@ offset = lig_action & 0x3FFFFFFFUL; if ( offset * 2 < optdata->ligatureTable ) { - GXV_TRACE(( "too short offset 0x%08x:" - " 2 x offset < ligatureTable (%d byte rewind)\n", + GXV_TRACE(( "too short offset 0x%08lx:" + " 2 x offset < ligatureTable (%lu byte rewind)\n", offset, optdata->ligatureTable - offset * 2 )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); } else if ( offset * 2 > optdata->ligatureTable + optdata->ligatureTable_length ) { - GXV_TRACE(( "too long offset 0x%08x:" + GXV_TRACE(( "too long offset 0x%08lx:" " 2 x offset > ligatureTable + ligatureTable_length" - " (%d byte overrun)\n", + " (%lu byte overrun)\n", offset, optdata->ligatureTable + optdata->ligatureTable_length - offset * 2 )); diff --git a/thirdparty/freetype/src/gxvalid/gxvmort4.c b/thirdparty/freetype/src/gxvalid/gxvmort4.c index 4584d204cf..1b0dd3edab 100644 --- a/thirdparty/freetype/src/gxvalid/gxvmort4.c +++ b/thirdparty/freetype/src/gxvalid/gxvmort4.c @@ -5,7 +5,7 @@ * TrueTypeGX/AAT mort table validation * body for type4 (Non-Contextual Glyph Substitution) subtable. * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/gxvalid/gxvmort5.c b/thirdparty/freetype/src/gxvalid/gxvmort5.c index a15a24fe65..cfbf31208c 100644 --- a/thirdparty/freetype/src/gxvalid/gxvmort5.c +++ b/thirdparty/freetype/src/gxvalid/gxvmort5.c @@ -5,7 +5,7 @@ * TrueTypeGX/AAT mort table validation * body for type5 (Contextual Glyph Insertion) subtable. * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * @@ -63,7 +63,7 @@ *GXV_mort_subtable_type5_StateOptRecData; - FT_LOCAL_DEF( void ) + static void gxv_mort_subtable_type5_subtable_setup( FT_UShort table_size, FT_UShort classTable, FT_UShort stateArray, diff --git a/thirdparty/freetype/src/gxvalid/gxvmorx.c b/thirdparty/freetype/src/gxvalid/gxvmorx.c index 754d9f8bf1..babff51866 100644 --- a/thirdparty/freetype/src/gxvalid/gxvmorx.c +++ b/thirdparty/freetype/src/gxvalid/gxvmorx.c @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT morx table validation (body). * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * @@ -84,7 +84,7 @@ p += 4; #endif - GXV_TRACE(( "validating chain subtable %d/%d (%d bytes)\n", + GXV_TRACE(( "validating chain subtable %d/%d (%lu bytes)\n", i + 1, nSubtables, length )); type = coverage & 0x0007; @@ -99,7 +99,7 @@ func = fmt_funcs_table[type]; if ( !func ) - GXV_TRACE(( "morx type %d is reserved\n", type )); + GXV_TRACE(( "morx type %lu is reserved\n", type )); func( p, p + rest, gxvalid ); @@ -186,7 +186,7 @@ for ( i = 0; i < nChains; i++ ) { - GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains )); + GXV_TRACE(( "validating chain %lu/%lu\n", i + 1, nChains )); GXV_32BIT_ALIGNMENT_VALIDATE( p - table ); gxv_morx_chain_validate( p, limit, gxvalid ); p += gxvalid->subtable_length; diff --git a/thirdparty/freetype/src/gxvalid/gxvmorx.h b/thirdparty/freetype/src/gxvalid/gxvmorx.h index f747b1d636..f155f18460 100644 --- a/thirdparty/freetype/src/gxvalid/gxvmorx.h +++ b/thirdparty/freetype/src/gxvalid/gxvmorx.h @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT common definition for morx table (specification). * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/gxvalid/gxvmorx0.c b/thirdparty/freetype/src/gxvalid/gxvmorx0.c index 5a42e552e2..e93cea9cca 100644 --- a/thirdparty/freetype/src/gxvalid/gxvmorx0.c +++ b/thirdparty/freetype/src/gxvalid/gxvmorx0.c @@ -5,7 +5,7 @@ * TrueTypeGX/AAT morx table validation * body for type0 (Indic Script Rearrangement) subtable. * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/gxvalid/gxvmorx1.c b/thirdparty/freetype/src/gxvalid/gxvmorx1.c index 9f8b69067e..d380f8d1ad 100644 --- a/thirdparty/freetype/src/gxvalid/gxvmorx1.c +++ b/thirdparty/freetype/src/gxvalid/gxvmorx1.c @@ -5,7 +5,7 @@ * TrueTypeGX/AAT morx table validation * body for type1 (Contextual Substitution) subtable. * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/gxvalid/gxvmorx2.c b/thirdparty/freetype/src/gxvalid/gxvmorx2.c index 98b5c49c26..e7e008f069 100644 --- a/thirdparty/freetype/src/gxvalid/gxvmorx2.c +++ b/thirdparty/freetype/src/gxvalid/gxvmorx2.c @@ -5,7 +5,7 @@ * TrueTypeGX/AAT morx table validation * body for type2 (Ligature Substitution) subtable. * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * @@ -72,11 +72,11 @@ optdata->componentTable = FT_NEXT_ULONG( p ); optdata->ligatureTable = FT_NEXT_ULONG( p ); - GXV_TRACE(( "offset to ligActionTable=0x%08x\n", + GXV_TRACE(( "offset to ligActionTable=0x%08lx\n", optdata->ligActionTable )); - GXV_TRACE(( "offset to componentTable=0x%08x\n", + GXV_TRACE(( "offset to componentTable=0x%08lx\n", optdata->componentTable )); - GXV_TRACE(( "offset to ligatureTable=0x%08x\n", + GXV_TRACE(( "offset to ligatureTable=0x%08lx\n", optdata->ligatureTable )); } @@ -116,19 +116,19 @@ gxv_set_length_by_ulong_offset( o, l, buff, 6, table_size, gxvalid ); - GXV_TRACE(( "classTable: offset=0x%08x length=0x%08x\n", + GXV_TRACE(( "classTable: offset=0x%08lx length=0x%08lx\n", classTable, *classTable_length_p )); - GXV_TRACE(( "stateArray: offset=0x%08x length=0x%08x\n", + GXV_TRACE(( "stateArray: offset=0x%08lx length=0x%08lx\n", stateArray, *stateArray_length_p )); - GXV_TRACE(( "entryTable: offset=0x%08x length=0x%08x\n", + GXV_TRACE(( "entryTable: offset=0x%08lx length=0x%08lx\n", entryTable, *entryTable_length_p )); - GXV_TRACE(( "ligActionTable: offset=0x%08x length=0x%08x\n", + GXV_TRACE(( "ligActionTable: offset=0x%08lx length=0x%08lx\n", optdata->ligActionTable, optdata->ligActionTable_length )); - GXV_TRACE(( "componentTable: offset=0x%08x length=0x%08x\n", + GXV_TRACE(( "componentTable: offset=0x%08lx length=0x%08lx\n", optdata->componentTable, optdata->componentTable_length )); - GXV_TRACE(( "ligatureTable: offset=0x%08x length=0x%08x\n", + GXV_TRACE(( "ligatureTable: offset=0x%08lx length=0x%08lx\n", optdata->ligatureTable, optdata->ligatureTable_length )); @@ -157,12 +157,12 @@ if ( p < lat_base ) { - GXV_TRACE(( "p < lat_base (%d byte rewind)\n", lat_base - p )); + GXV_TRACE(( "p < lat_base (%ld byte rewind)\n", lat_base - p )); FT_INVALID_OFFSET; } else if ( lat_limit < p ) { - GXV_TRACE(( "lat_limit < p (%d byte overrun)\n", p - lat_limit )); + GXV_TRACE(( "lat_limit < p (%ld byte overrun)\n", p - lat_limit )); FT_INVALID_OFFSET; } @@ -196,7 +196,7 @@ GXV_TRACE(( "ligature action table includes" " too negative offset moving all GID" - " below defined range: 0x%04x\n", + " below defined range: 0x%04lx\n", offset & 0xFFFFU )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); } @@ -207,14 +207,14 @@ GXV_TRACE(( "ligature action table includes" " too large offset moving all GID" - " over defined range: 0x%04x\n", + " over defined range: 0x%04lx\n", offset & 0xFFFFU )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); } GXV_TRACE(( "ligature action table includes" " invalid offset to add to 16-bit GID:" - " 0x%08x\n", offset )); + " 0x%08lx\n", offset )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); } } diff --git a/thirdparty/freetype/src/gxvalid/gxvmorx4.c b/thirdparty/freetype/src/gxvalid/gxvmorx4.c index 857e4d4eb8..e632e8d42a 100644 --- a/thirdparty/freetype/src/gxvalid/gxvmorx4.c +++ b/thirdparty/freetype/src/gxvalid/gxvmorx4.c @@ -5,7 +5,7 @@ * TrueTypeGX/AAT morx table validation * body for "morx" type4 (Non-Contextual Glyph Substitution) subtable. * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/gxvalid/gxvmorx5.c b/thirdparty/freetype/src/gxvalid/gxvmorx5.c index 7ceba077af..5ad33976d7 100644 --- a/thirdparty/freetype/src/gxvalid/gxvmorx5.c +++ b/thirdparty/freetype/src/gxvalid/gxvmorx5.c @@ -5,7 +5,7 @@ * TrueTypeGX/AAT morx table validation * body for type5 (Contextual Glyph Insertion) subtable. * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/thirdparty/freetype/src/gxvalid/gxvopbd.c b/thirdparty/freetype/src/gxvalid/gxvopbd.c index a398fe0977..7a2feab468 100644 --- a/thirdparty/freetype/src/gxvalid/gxvopbd.c +++ b/thirdparty/freetype/src/gxvalid/gxvopbd.c @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT opbd table validation (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * @@ -188,7 +188,7 @@ /* only 0x00010000 is defined (1996) */ - GXV_TRACE(( "(version=0x%08x)\n", version )); + GXV_TRACE(( "(version=0x%08lx)\n", version )); if ( 0x00010000UL != version ) FT_INVALID_FORMAT; diff --git a/thirdparty/freetype/src/gxvalid/gxvprop.c b/thirdparty/freetype/src/gxvalid/gxvprop.c index bee8bab97b..98cd368845 100644 --- a/thirdparty/freetype/src/gxvalid/gxvprop.c +++ b/thirdparty/freetype/src/gxvalid/gxvprop.c @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT prop table validation (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * @@ -283,7 +283,7 @@ format = FT_NEXT_USHORT( p ); defaultProp = FT_NEXT_USHORT( p ); - GXV_TRACE(( " version 0x%08x\n", version )); + GXV_TRACE(( " version 0x%08lx\n", version )); GXV_TRACE(( " format 0x%04x\n", format )); GXV_TRACE(( " defaultProp 0x%04x\n", defaultProp )); @@ -309,7 +309,7 @@ if ( format == 0 ) { FT_TRACE3(( "(format 0, no per-glyph properties, " - "remaining %d bytes are skipped)", limit - p )); + "remaining %ld bytes are skipped)", limit - p )); goto Exit; } diff --git a/thirdparty/freetype/src/gxvalid/gxvtrak.c b/thirdparty/freetype/src/gxvalid/gxvtrak.c index 58a631c9e5..c1ed92872d 100644 --- a/thirdparty/freetype/src/gxvalid/gxvtrak.c +++ b/thirdparty/freetype/src/gxvalid/gxvtrak.c @@ -4,7 +4,7 @@ * * TrueTypeGX/AAT trak table validation (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * suzuki toshiya, Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * @@ -130,7 +130,7 @@ p = table + j * ( 4 + 2 + 2 ); t = FT_NEXT_LONG( p ); if ( t == track ) - GXV_TRACE(( "duplicated entries found for track value 0x%x\n", + GXV_TRACE(( "duplicated entries found for track value 0x%lx\n", track )); } } @@ -243,7 +243,7 @@ vertOffset = FT_NEXT_USHORT( p ); reserved = FT_NEXT_USHORT( p ); - GXV_TRACE(( " (version = 0x%08x)\n", version )); + GXV_TRACE(( " (version = 0x%08lx)\n", version )); GXV_TRACE(( " (format = 0x%04x)\n", format )); GXV_TRACE(( " (horizOffset = 0x%04x)\n", horizOffset )); GXV_TRACE(( " (vertOffset = 0x%04x)\n", vertOffset )); diff --git a/thirdparty/freetype/src/gxvalid/module.mk b/thirdparty/freetype/src/gxvalid/module.mk deleted file mode 100644 index e7d408df9d..0000000000 --- a/thirdparty/freetype/src/gxvalid/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 gxvalid module definition -# - -# Copyright (C) 2004-2020 by -# suzuki toshiya, Masatake YAMATO, Red Hat K.K., -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += GXVALID_MODULE - -define GXVALID_MODULE -$(OPEN_DRIVER) FT_Module_Class, gxv_module_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)gxvalid $(ECHO_DRIVER_DESC)TrueTypeGX/AAT validation module$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/gxvalid/rules.mk b/thirdparty/freetype/src/gxvalid/rules.mk deleted file mode 100644 index d55a4935e2..0000000000 --- a/thirdparty/freetype/src/gxvalid/rules.mk +++ /dev/null @@ -1,98 +0,0 @@ -# -# FreeType 2 TrueTypeGX/AAT validation driver configuration rules -# - - -# Copyright (C) 2004-2020 by -# suzuki toshiya, Masatake YAMATO, Red Hat K.K., -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# GXV driver directory -# -GXV_DIR := $(SRC_DIR)/gxvalid - - -# compilation flags for the driver -# -GXV_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(GXV_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# GXV driver sources (i.e., C files) -# -GXV_DRV_SRC := $(GXV_DIR)/gxvcommn.c \ - $(GXV_DIR)/gxvfeat.c \ - $(GXV_DIR)/gxvbsln.c \ - $(GXV_DIR)/gxvtrak.c \ - $(GXV_DIR)/gxvopbd.c \ - $(GXV_DIR)/gxvprop.c \ - $(GXV_DIR)/gxvjust.c \ - $(GXV_DIR)/gxvmort.c \ - $(GXV_DIR)/gxvmort0.c \ - $(GXV_DIR)/gxvmort1.c \ - $(GXV_DIR)/gxvmort2.c \ - $(GXV_DIR)/gxvmort4.c \ - $(GXV_DIR)/gxvmort5.c \ - $(GXV_DIR)/gxvmorx.c \ - $(GXV_DIR)/gxvmorx0.c \ - $(GXV_DIR)/gxvmorx1.c \ - $(GXV_DIR)/gxvmorx2.c \ - $(GXV_DIR)/gxvmorx4.c \ - $(GXV_DIR)/gxvmorx5.c \ - $(GXV_DIR)/gxvlcar.c \ - $(GXV_DIR)/gxvkern.c \ - $(GXV_DIR)/gxvmod.c - -# GXV driver headers -# -GXV_DRV_H := $(GXV_DIR)/gxvalid.h \ - $(GXV_DIR)/gxverror.h \ - $(GXV_DIR)/gxvcommn.h \ - $(GXV_DIR)/gxvfeat.h \ - $(GXV_DIR)/gxvmod.h \ - $(GXV_DIR)/gxvmort.h \ - $(GXV_DIR)/gxvmorx.h - - -# GXV driver object(s) -# -# GXV_DRV_OBJ_M is used during `multi' builds. -# GXV_DRV_OBJ_S is used during `single' builds. -# -GXV_DRV_OBJ_M := $(GXV_DRV_SRC:$(GXV_DIR)/%.c=$(OBJ_DIR)/%.$O) -GXV_DRV_OBJ_S := $(OBJ_DIR)/gxvalid.$O - -# GXV driver source file for single build -# -GXV_DRV_SRC_S := $(GXV_DIR)/gxvalid.c - - -# GXV driver - single object -# -$(GXV_DRV_OBJ_S): $(GXV_DRV_SRC_S) $(GXV_DRV_SRC) \ - $(FREETYPE_H) $(GXV_DRV_H) - $(GXV_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(GXV_DRV_SRC_S)) - - -# GXV driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(GXV_DIR)/%.c $(FREETYPE_H) $(GXV_DRV_H) - $(GXV_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(GXV_DRV_OBJ_S) -DRV_OBJS_M += $(GXV_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/gzip/ftgzip.c b/thirdparty/freetype/src/gzip/ftgzip.c index de7d0fdd5b..8f98a7d17b 100644 --- a/thirdparty/freetype/src/gzip/ftgzip.c +++ b/thirdparty/freetype/src/gzip/ftgzip.c @@ -8,7 +8,7 @@ * parse compressed PCF fonts, as found with many X11 server * distributions. * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -121,24 +121,29 @@ 'malloc/free' */ static voidpf - ft_gzip_alloc( FT_Memory memory, - uInt items, - uInt size ) + ft_gzip_alloc( voidpf opaque, + uInt items, + uInt size ) { - FT_ULong sz = (FT_ULong)size * items; + FT_Memory memory = (FT_Memory)opaque; + FT_ULong sz = (FT_ULong)size * items; FT_Error error; - FT_Pointer p = NULL; + FT_Pointer p = NULL; - (void)FT_ALLOC( p, sz ); + /* allocate and zero out */ + FT_MEM_ALLOC( p, sz ); return p; } static void - ft_gzip_free( FT_Memory memory, - voidpf address ) + ft_gzip_free( voidpf opaque, + voidpf address ) { + FT_Memory memory = (FT_Memory)opaque; + + FT_MEM_FREE( address ); } @@ -150,14 +155,14 @@ unsigned items, unsigned size ) { - return ft_gzip_alloc( (FT_Memory)opaque, items, size ); + return ft_gzip_alloc( opaque, items, size ); } local void zcfree( voidpf opaque, voidpf ptr ) { - ft_gzip_free( (FT_Memory)opaque, ptr ); + ft_gzip_free( opaque, ptr ); } #endif /* !SYSTEM_ZLIB && !USE_ZLIB_ZCALLOC */ @@ -304,8 +309,8 @@ } /* initialize zlib -- there is no zlib header in the compressed stream */ - zstream->zalloc = (alloc_func)ft_gzip_alloc; - zstream->zfree = (free_func) ft_gzip_free; + zstream->zalloc = ft_gzip_alloc; + zstream->zfree = ft_gzip_free; zstream->opaque = stream->memory; zstream->avail_in = 0; @@ -462,12 +467,13 @@ FT_ULong count ) { FT_Error error = FT_Err_Ok; - FT_ULong delta; for (;;) { - delta = (FT_ULong)( zip->limit - zip->cursor ); + FT_ULong delta = (FT_ULong)( zip->limit - zip->cursor ); + + if ( delta >= count ) delta = count; @@ -671,7 +677,7 @@ FT_Byte* zip_buff = NULL; - if ( !FT_ALLOC( zip_buff, zip_size ) ) + if ( !FT_QALLOC( zip_buff, zip_size ) ) { FT_ULong count; @@ -741,8 +747,8 @@ stream.next_out = output; stream.avail_out = (uInt)*output_len; - stream.zalloc = (alloc_func)ft_gzip_alloc; - stream.zfree = (free_func) ft_gzip_free; + stream.zalloc = ft_gzip_alloc; + stream.zfree = ft_gzip_free; stream.opaque = memory; /* This is a temporary fix and will be removed once the internal diff --git a/thirdparty/freetype/src/gzip/rules.mk b/thirdparty/freetype/src/gzip/rules.mk deleted file mode 100644 index 4ea823f8d3..0000000000 --- a/thirdparty/freetype/src/gzip/rules.mk +++ /dev/null @@ -1,83 +0,0 @@ -# -# FreeType 2 GZip support configuration rules -# - - -# Copyright (C) 2002-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# gzip driver directory -# -GZIP_DIR := $(SRC_DIR)/gzip - - -# compilation flags for the driver -# -ifeq ($(SYSTEM_ZLIB),) - GZIP_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(GZIP_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) -else - GZIP_COMPILE := $(CC) $(ANSIFLAGS) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) -endif - - -# gzip support sources -# -# All source and header files get loaded by `ftgzip.c' only if SYSTEM_ZLIB -# is not defined (regardless whether we have a `single' or a `multi' build). -# However, it doesn't harm if we add everything as a dependency -# unconditionally. -# -GZIP_DRV_SRCS := $(GZIP_DIR)/adler32.c \ - $(GZIP_DIR)/ftzconf.h \ - $(GZIP_DIR)/infblock.c \ - $(GZIP_DIR)/infblock.h \ - $(GZIP_DIR)/infcodes.c \ - $(GZIP_DIR)/infcodes.h \ - $(GZIP_DIR)/inffixed.h \ - $(GZIP_DIR)/inflate.c \ - $(GZIP_DIR)/inftrees.c \ - $(GZIP_DIR)/inftrees.h \ - $(GZIP_DIR)/infutil.c \ - $(GZIP_DIR)/infutil.h \ - $(GZIP_DIR)/zlib.h \ - $(GZIP_DIR)/zutil.c \ - $(GZIP_DIR)/zutil.h - - -# gzip driver object(s) -# -# GZIP_DRV_OBJ is used during both `single' and `multi' builds -# -GZIP_DRV_OBJ := $(OBJ_DIR)/ftgzip.$O - - -# gzip main source file -# -GZIP_DRV_SRC := $(GZIP_DIR)/ftgzip.c - - -# gzip support - object -# -$(GZIP_DRV_OBJ): $(GZIP_DRV_SRC) $(GZIP_DRV_SRCS) $(FREETYPE_H) - $(GZIP_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(GZIP_DRV_SRC)) - - -# update main driver object lists -# -DRV_OBJS_S += $(GZIP_DRV_OBJ) -DRV_OBJS_M += $(GZIP_DRV_OBJ) - - -# EOF diff --git a/thirdparty/freetype/src/lzw/ftlzw.c b/thirdparty/freetype/src/lzw/ftlzw.c index ddb81e6e97..e112418ab1 100644 --- a/thirdparty/freetype/src/lzw/ftlzw.c +++ b/thirdparty/freetype/src/lzw/ftlzw.c @@ -8,7 +8,7 @@ * be used to parse compressed PCF fonts, as found with many X11 server * distributions. * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * Albert Chin-A-Young. * * based on code in `src/gzip/ftgzip.c' @@ -383,7 +383,7 @@ stream->size = 0x7FFFFFFFL; /* don't know the real size! */ stream->pos = 0; - stream->base = 0; + stream->base = NULL; stream->read = ft_lzw_stream_io; stream->close = ft_lzw_stream_close; diff --git a/thirdparty/freetype/src/lzw/ftzopen.c b/thirdparty/freetype/src/lzw/ftzopen.c index 884d2ec74e..8b5b357f36 100644 --- a/thirdparty/freetype/src/lzw/ftzopen.c +++ b/thirdparty/freetype/src/lzw/ftzopen.c @@ -8,7 +8,7 @@ * be used to parse compressed PCF fonts, as found with many X11 server * distributions. * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * David Turner. * * This file is part of the FreeType project, and may only be used, @@ -127,6 +127,7 @@ new_size = new_size + ( new_size >> 1 ) + 4; + /* if relocating to heap */ if ( state->stack == state->stack_0 ) { state->stack = NULL; @@ -142,9 +143,13 @@ return -1; } - if ( FT_RENEW_ARRAY( state->stack, old_size, new_size ) ) + if ( FT_QRENEW_ARRAY( state->stack, old_size, new_size ) ) return -1; + /* if relocating to heap */ + if ( old_size == 0 ) + FT_MEM_COPY( state->stack, state->stack_0, FT_LZW_DEFAULT_STACK_SIZE ); + state->stack_size = new_size; } return 0; diff --git a/thirdparty/freetype/src/lzw/ftzopen.h b/thirdparty/freetype/src/lzw/ftzopen.h index d8768f7b47..9ada742c73 100644 --- a/thirdparty/freetype/src/lzw/ftzopen.h +++ b/thirdparty/freetype/src/lzw/ftzopen.h @@ -8,7 +8,7 @@ * be used to parse compressed PCF fonts, as found with many X11 server * distributions. * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * David Turner. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/lzw/rules.mk b/thirdparty/freetype/src/lzw/rules.mk deleted file mode 100644 index 3468ee024d..0000000000 --- a/thirdparty/freetype/src/lzw/rules.mk +++ /dev/null @@ -1,72 +0,0 @@ -# -# FreeType 2 LZW support configuration rules -# - - -# Copyright (C) 2004-2020 by -# Albert Chin-A-Young. -# -# based on `src/lzw/rules.mk' -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# LZW driver directory -# -LZW_DIR := $(SRC_DIR)/lzw - - -# compilation flags for the driver -# -LZW_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(LZW_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# LZW support sources (i.e., C files) -# -LZW_DRV_SRC := $(LZW_DIR)/ftlzw.c - -# LZW support headers -# -LZW_DRV_H := $(LZW_DIR)/ftzopen.h \ - $(LZW_DIR)/ftzopen.c - - -# LZW driver object(s) -# -# LZW_DRV_OBJ_M is used during `multi' builds -# LZW_DRV_OBJ_S is used during `single' builds -# -LZW_DRV_OBJ_M := $(OBJ_DIR)/ftlzw.$O -LZW_DRV_OBJ_S := $(OBJ_DIR)/ftlzw.$O - -# LZW support source file for single build -# -LZW_DRV_SRC_S := $(LZW_DIR)/ftlzw.c - - -# LZW support - single object -# -$(LZW_DRV_OBJ_S): $(LZW_DRV_SRC_S) $(LZW_DRV_SRC) $(FREETYPE_H) $(LZW_DRV_H) - $(LZW_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(LZW_DRV_SRC_S)) - - -# LZW support - multiple objects -# -$(OBJ_DIR)/%.$O: $(LZW_DIR)/%.c $(FREETYPE_H) $(LZW_DRV_H) - $(LZW_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(LZW_DRV_OBJ_S) -DRV_OBJS_M += $(LZW_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/otvalid/module.mk b/thirdparty/freetype/src/otvalid/module.mk deleted file mode 100644 index 67b9820d84..0000000000 --- a/thirdparty/freetype/src/otvalid/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 otvalid module definition -# - - -# Copyright (C) 2004-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += OTVALID_MODULE - -define OTVALID_MODULE -$(OPEN_DRIVER) FT_Module_Class, otv_module_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)otvalid $(ECHO_DRIVER_DESC)OpenType validation module$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/otvalid/otvalid.c b/thirdparty/freetype/src/otvalid/otvalid.c index d640209f68..869233ce8c 100644 --- a/thirdparty/freetype/src/otvalid/otvalid.c +++ b/thirdparty/freetype/src/otvalid/otvalid.c @@ -4,7 +4,7 @@ * * FreeType validator for OpenType tables (body only). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/otvalid/otvalid.h b/thirdparty/freetype/src/otvalid/otvalid.h index 8208ff0112..f8ca454d6e 100644 --- a/thirdparty/freetype/src/otvalid/otvalid.h +++ b/thirdparty/freetype/src/otvalid/otvalid.h @@ -4,7 +4,7 @@ * * OpenType table validation (specification only). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/otvalid/otvbase.c b/thirdparty/freetype/src/otvalid/otvbase.c index 250ae98ab5..83f998cdb1 100644 --- a/thirdparty/freetype/src/otvalid/otvbase.c +++ b/thirdparty/freetype/src/otvalid/otvbase.c @@ -4,7 +4,7 @@ * * OpenType BASE table validation (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/otvalid/otvcommn.c b/thirdparty/freetype/src/otvalid/otvcommn.c index faaa846871..40624bb159 100644 --- a/thirdparty/freetype/src/otvalid/otvcommn.c +++ b/thirdparty/freetype/src/otvalid/otvcommn.c @@ -4,7 +4,7 @@ * * OpenType common tables validation (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/otvalid/otvcommn.h b/thirdparty/freetype/src/otvalid/otvcommn.h index f9926034a9..3b096ecca8 100644 --- a/thirdparty/freetype/src/otvalid/otvcommn.h +++ b/thirdparty/freetype/src/otvalid/otvcommn.h @@ -4,7 +4,7 @@ * * OpenType common tables validation (specification). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -105,10 +105,11 @@ FT_BEGIN_HEADER FT_Byte* pp = (FT_Byte*)_size ## _p; \ \ \ - FT_TRACE3(( "\n" \ - "Invalid offset to optional table `%s'" \ - " set to zero.\n" \ - "\n", #_size )); \ + FT_TRACE3(( "\n" )); \ + FT_TRACE3(( "Invalid offset to optional table `%s'" \ + " set to zero.\n", \ + #_size )); \ + FT_TRACE3(( "\n" )); \ \ _size = pp[0] = pp[1] = 0; \ } \ @@ -127,10 +128,11 @@ FT_BEGIN_HEADER FT_Byte* pp = (FT_Byte*)_size ## _p; \ \ \ - FT_TRACE3(( "\n" \ - "Invalid offset to optional table `%s'" \ - " set to zero.\n" \ - "\n", #_size )); \ + FT_TRACE3(( "\n" )); \ + FT_TRACE3(( "Invalid offset to optional table `%s'" \ + " set to zero.\n", \ + #_size )); \ + FT_TRACE3(( "\n" )); \ \ _size = pp[0] = pp[1] = pp[2] = pp[3] = 0; \ } \ @@ -178,24 +180,24 @@ FT_BEGIN_HEADER #define OTV_ENTER \ FT_BEGIN_STMNT \ otvalid->debug_indent += 2; \ - FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \ + FT_TRACE4(( "%*.s", otvalid->debug_indent, "" )); \ FT_TRACE4(( "%s table\n", \ otvalid->debug_function_name[otvalid->nesting_level] )); \ FT_END_STMNT -#define OTV_NAME_ENTER( name ) \ - FT_BEGIN_STMNT \ - otvalid->debug_indent += 2; \ - FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \ - FT_TRACE4(( "%s table\n", name )); \ +#define OTV_NAME_ENTER( name ) \ + FT_BEGIN_STMNT \ + otvalid->debug_indent += 2; \ + FT_TRACE4(( "%*.s", otvalid->debug_indent, "" )); \ + FT_TRACE4(( "%s table\n", name )); \ FT_END_STMNT #define OTV_EXIT otvalid->debug_indent -= 2 -#define OTV_TRACE( s ) \ - FT_BEGIN_STMNT \ - FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \ - FT_TRACE4( s ); \ +#define OTV_TRACE( s ) \ + FT_BEGIN_STMNT \ + FT_TRACE4(( "%*.s", otvalid->debug_indent, "" )); \ + FT_TRACE4( s ); \ FT_END_STMNT #else /* !FT_DEBUG_LEVEL_TRACE */ diff --git a/thirdparty/freetype/src/otvalid/otverror.h b/thirdparty/freetype/src/otvalid/otverror.h index 979e9cbd9c..3e23234f36 100644 --- a/thirdparty/freetype/src/otvalid/otverror.h +++ b/thirdparty/freetype/src/otvalid/otverror.h @@ -4,7 +4,7 @@ * * OpenType validation module error codes (specification only). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/otvalid/otvgdef.c b/thirdparty/freetype/src/otvalid/otvgdef.c index 88874b8474..5a160a4142 100644 --- a/thirdparty/freetype/src/otvalid/otvgdef.c +++ b/thirdparty/freetype/src/otvalid/otvgdef.c @@ -4,7 +4,7 @@ * * OpenType GDEF table validation (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/otvalid/otvgpos.c b/thirdparty/freetype/src/otvalid/otvgpos.c index 29d56f91e8..e0d4e420de 100644 --- a/thirdparty/freetype/src/otvalid/otvgpos.c +++ b/thirdparty/freetype/src/otvalid/otvgpos.c @@ -4,7 +4,7 @@ * * OpenType GPOS table validation (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/otvalid/otvgpos.h b/thirdparty/freetype/src/otvalid/otvgpos.h index 06a03a0e6c..176a68883f 100644 --- a/thirdparty/freetype/src/otvalid/otvgpos.h +++ b/thirdparty/freetype/src/otvalid/otvgpos.h @@ -4,7 +4,7 @@ * * OpenType GPOS table validator (specification). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/otvalid/otvgsub.c b/thirdparty/freetype/src/otvalid/otvgsub.c index f0d563ba92..b426a17449 100644 --- a/thirdparty/freetype/src/otvalid/otvgsub.c +++ b/thirdparty/freetype/src/otvalid/otvgsub.c @@ -4,7 +4,7 @@ * * OpenType GSUB table validation (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/otvalid/otvjstf.c b/thirdparty/freetype/src/otvalid/otvjstf.c index 79de7b809d..404dda88a1 100644 --- a/thirdparty/freetype/src/otvalid/otvjstf.c +++ b/thirdparty/freetype/src/otvalid/otvjstf.c @@ -4,7 +4,7 @@ * * OpenType JSTF table validation (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/otvalid/otvmath.c b/thirdparty/freetype/src/otvalid/otvmath.c index dfdeaaba7e..b4bfabb62e 100644 --- a/thirdparty/freetype/src/otvalid/otvmath.c +++ b/thirdparty/freetype/src/otvalid/otvmath.c @@ -4,7 +4,7 @@ * * OpenType MATH table validation (body). * - * Copyright (C) 2007-2020 by + * Copyright (C) 2007-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * Written by George Williams. @@ -141,7 +141,7 @@ OTV_OPTIONAL_TABLE( DeviceTableOffset ); - /* OTV_NAME_ENTER( "MathKern" );*/ + /* OTV_NAME_ENTER( "MathKern" ); */ OTV_LIMIT_CHECK( 2 ); diff --git a/thirdparty/freetype/src/otvalid/otvmod.c b/thirdparty/freetype/src/otvalid/otvmod.c index 0188b27018..b7d674b5e2 100644 --- a/thirdparty/freetype/src/otvalid/otvmod.c +++ b/thirdparty/freetype/src/otvalid/otvmod.c @@ -4,7 +4,7 @@ * * FreeType's OpenType validation module implementation (body). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -53,7 +53,7 @@ if ( error ) goto Exit; - if ( FT_ALLOC( *table, *table_len ) ) + if ( FT_QALLOC( *table, *table_len ) ) goto Exit; error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len ); @@ -94,7 +94,7 @@ */ if ( face->num_glyphs > 0xFFFFL ) { - FT_TRACE1(( "otv_validate: Invalid glyphs index (0x0000FFFF - 0x%08x) ", + FT_TRACE1(( "otv_validate: Invalid glyphs index (0x0000FFFF - 0x%08lx) ", face->num_glyphs )); FT_TRACE1(( "are not handled by OpenType tables\n" )); num_glyphs = 0xFFFF; diff --git a/thirdparty/freetype/src/otvalid/otvmod.h b/thirdparty/freetype/src/otvalid/otvmod.h index efd6da035f..37c20e0023 100644 --- a/thirdparty/freetype/src/otvalid/otvmod.h +++ b/thirdparty/freetype/src/otvalid/otvmod.h @@ -5,7 +5,7 @@ * FreeType's OpenType validation module implementation * (specification). * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/otvalid/rules.mk b/thirdparty/freetype/src/otvalid/rules.mk deleted file mode 100644 index 7f0169fd89..0000000000 --- a/thirdparty/freetype/src/otvalid/rules.mk +++ /dev/null @@ -1,81 +0,0 @@ -# -# FreeType 2 OpenType validation driver configuration rules -# - - -# Copyright (C) 2004-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# OTV driver directory -# -OTV_DIR := $(SRC_DIR)/otvalid - - -# compilation flags for the driver -# -OTV_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(OTV_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# OTV driver sources (i.e., C files) -# -OTV_DRV_SRC := $(OTV_DIR)/otvbase.c \ - $(OTV_DIR)/otvcommn.c \ - $(OTV_DIR)/otvgdef.c \ - $(OTV_DIR)/otvgpos.c \ - $(OTV_DIR)/otvgsub.c \ - $(OTV_DIR)/otvjstf.c \ - $(OTV_DIR)/otvmath.c \ - $(OTV_DIR)/otvmod.c - -# OTV driver headers -# -OTV_DRV_H := $(OTV_DIR)/otvalid.h \ - $(OTV_DIR)/otvcommn.h \ - $(OTV_DIR)/otverror.h \ - $(OTV_DIR)/otvgpos.h \ - $(OTV_DIR)/otvmod.h - - -# OTV driver object(s) -# -# OTV_DRV_OBJ_M is used during `multi' builds. -# OTV_DRV_OBJ_S is used during `single' builds. -# -OTV_DRV_OBJ_M := $(OTV_DRV_SRC:$(OTV_DIR)/%.c=$(OBJ_DIR)/%.$O) -OTV_DRV_OBJ_S := $(OBJ_DIR)/otvalid.$O - -# OTV driver source file for single build -# -OTV_DRV_SRC_S := $(OTV_DIR)/otvalid.c - - -# OTV driver - single object -# -$(OTV_DRV_OBJ_S): $(OTV_DRV_SRC_S) $(OTV_DRV_SRC) \ - $(FREETYPE_H) $(OTV_DRV_H) - $(OTV_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(OTV_DRV_SRC_S)) - - -# OTV driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(OTV_DIR)/%.c $(FREETYPE_H) $(OTV_DRV_H) - $(OTV_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(OTV_DRV_OBJ_S) -DRV_OBJS_M += $(OTV_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/pcf/module.mk b/thirdparty/freetype/src/pcf/module.mk deleted file mode 100644 index df383ff0fb..0000000000 --- a/thirdparty/freetype/src/pcf/module.mk +++ /dev/null @@ -1,34 +0,0 @@ -# -# FreeType 2 PCF module definition -# - -# Copyright 2000, 2006 by -# Francesco Zappa Nardelli -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - - -FTMODULE_H_COMMANDS += PCF_DRIVER - -define PCF_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, pcf_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)pcf $(ECHO_DRIVER_DESC)pcf bitmap fonts$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/pcf/pcfdrivr.c b/thirdparty/freetype/src/pcf/pcfdrivr.c index e9dd51752e..2a40af9e99 100644 --- a/thirdparty/freetype/src/pcf/pcfdrivr.c +++ b/thirdparty/freetype/src/pcf/pcfdrivr.c @@ -606,7 +606,7 @@ THE SOFTWARE. if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) ) { - FT_TRACE1(( "pcf_get_bdf_property:" + FT_TRACE2(( "pcf_get_bdf_property:" " too large integer 0x%lx is truncated\n", prop->value.l )); } @@ -705,7 +705,7 @@ THE SOFTWARE. #endif /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */ - FT_TRACE0(( "pcf_property_set: missing property `%s'\n", + FT_TRACE2(( "pcf_property_set: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); } @@ -743,7 +743,7 @@ THE SOFTWARE. #endif /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */ - FT_TRACE0(( "pcf_property_get: missing property `%s'\n", + FT_TRACE2(( "pcf_property_get: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); } diff --git a/thirdparty/freetype/src/pcf/pcfread.c b/thirdparty/freetype/src/pcf/pcfread.c index 8817682cdf..e60a0a5141 100644 --- a/thirdparty/freetype/src/pcf/pcfread.c +++ b/thirdparty/freetype/src/pcf/pcfread.c @@ -127,7 +127,7 @@ THE SOFTWARE. toc->count = FT_MIN( stream->size >> 4, 9 ); } - if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) ) + if ( FT_QNEW_ARRAY( face->toc.tables, toc->count ) ) return error; tables = face->toc.tables; @@ -238,7 +238,7 @@ THE SOFTWARE. { for ( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); j++ ) - if ( tables[i].type == (FT_UInt)( 1 << j ) ) + if ( tables[i].type == 1UL << j ) name = tableNames[j]; FT_TRACE4(( " %d: type=%s, format=0x%lX," @@ -501,8 +501,8 @@ THE SOFTWARE. if ( FT_READ_ULONG_LE( format ) ) goto Bail; - FT_TRACE4(( "pcf_get_properties:\n" - " format: 0x%lX (%s)\n", + FT_TRACE4(( "pcf_get_properties:\n" )); + FT_TRACE4(( " format: 0x%lX (%s)\n", format, PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB" )); @@ -540,7 +540,7 @@ THE SOFTWARE. face->nprops = (int)nprops; - if ( FT_NEW_ARRAY( props, nprops ) ) + if ( FT_QNEW_ARRAY( props, nprops ) ) goto Bail; for ( i = 0; i < nprops; i++ ) @@ -607,13 +607,13 @@ THE SOFTWARE. } /* allocate one more byte so that we have a final null byte */ - if ( FT_NEW_ARRAY( strings, string_size + 1 ) ) + if ( FT_QALLOC( strings, string_size + 1 ) || + FT_STREAM_READ( strings, string_size ) ) goto Bail; - error = FT_Stream_Read( stream, (FT_Byte*)strings, string_size ); - if ( error ) - goto Bail; + strings[string_size] = '\0'; + /* zero out in case of failure */ if ( FT_NEW_ARRAY( properties, nprops ) ) goto Bail; @@ -697,8 +697,8 @@ THE SOFTWARE. if ( FT_READ_ULONG_LE( format ) ) goto Bail; - FT_TRACE4(( "pcf_get_metrics:\n" - " format: 0x%lX (%s, %s)\n", + FT_TRACE4(( "pcf_get_metrics:\n" )); + FT_TRACE4(( " format: 0x%lX (%s, %s)\n", format, PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB", PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) ? @@ -767,7 +767,7 @@ THE SOFTWARE. face->nmetrics = nmetrics + 1; - if ( FT_NEW_ARRAY( face->metrics, face->nmetrics ) ) + if ( FT_QNEW_ARRAY( face->metrics, face->nmetrics ) ) return error; /* we handle glyph index 0 later on */ @@ -840,17 +840,16 @@ THE SOFTWARE. FT_Stream_ExitFrame( stream ); - FT_TRACE4(( "pcf_get_bitmaps:\n" - " format: 0x%lX\n" - " (%s, %s,\n" - " padding=%d bit%s, scanning=%d bit%s)\n", - format, + FT_TRACE4(( "pcf_get_bitmaps:\n" )); + FT_TRACE4(( " format: 0x%lX\n", format )); + FT_TRACE4(( " (%s, %s,\n", PCF_BYTE_ORDER( format ) == MSBFirst ? "most significant byte first" : "least significant byte first", PCF_BIT_ORDER( format ) == MSBFirst ? "most significant bit first" - : "least significant bit first", + : "least significant bit first" )); + FT_TRACE4(( " padding=%d bit%s, scanning=%d bit%s)\n", 8 << PCF_GLYPH_PAD_INDEX( format ), ( 8 << PCF_GLYPH_PAD_INDEX( format ) ) == 1 ? "" : "s", 8 << PCF_SCAN_UNIT_INDEX( format ), @@ -1001,8 +1000,8 @@ THE SOFTWARE. if ( FT_READ_ULONG_LE( format ) ) goto Bail; - FT_TRACE4(( "pcf_get_encodings:\n" - " format: 0x%lX (%s)\n", + FT_TRACE4(( "pcf_get_encodings:\n" )); + FT_TRACE4(( " format: 0x%lX (%s)\n", format, PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB" )); @@ -1021,11 +1020,11 @@ THE SOFTWARE. goto Bail; } - FT_TRACE4(( " firstCol 0x%X, lastCol 0x%X\n" - " firstRow 0x%X, lastRow 0x%X\n" - " defaultChar 0x%X\n", - enc->firstCol, enc->lastCol, - enc->firstRow, enc->lastRow, + FT_TRACE4(( " firstCol 0x%X, lastCol 0x%X\n", + enc->firstCol, enc->lastCol )); + FT_TRACE4(( " firstRow 0x%X, lastRow 0x%X\n", + enc->firstRow, enc->lastRow )); + FT_TRACE4(( " defaultChar 0x%X\n", enc->defaultChar )); /* sanity checks; we limit numbers of rows and columns to 256 */ @@ -1088,8 +1087,8 @@ THE SOFTWARE. if ( defaultCharEncodingOffset == 0xFFFF ) { FT_TRACE0(( "pcf_get_encodings:" - " No glyph for default character,\n" - " " + " No glyph for default character,\n" )); + FT_TRACE0(( " " " setting it to the first glyph of the font\n" )); defaultCharEncodingOffset = 1; } @@ -1100,8 +1099,8 @@ THE SOFTWARE. if ( defaultCharEncodingOffset >= face->nmetrics ) { FT_TRACE0(( "pcf_get_encodings:" - " Invalid glyph index for default character,\n" - " " + " Invalid glyph index for default character,\n" )); + FT_TRACE0(( " " " setting it to the first glyph of the font\n" )); defaultCharEncodingOffset = 1; } @@ -1208,10 +1207,10 @@ THE SOFTWARE. if ( FT_READ_ULONG_LE( format ) ) goto Bail; - FT_TRACE4(( "pcf_get_accel%s:\n" - " format: 0x%lX (%s, %s)\n", + FT_TRACE4(( "pcf_get_accel%s:\n", type == PCF_BDF_ACCELERATORS ? " (getting BDF accelerators)" - : "", + : "" )); + FT_TRACE4(( " format: 0x%lX (%s, %s)\n", format, PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB", PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ? @@ -1233,16 +1232,16 @@ THE SOFTWARE. } FT_TRACE5(( " noOverlap=%s, constantMetrics=%s," - " terminalFont=%s, constantWidth=%s\n" - " inkInside=%s, inkMetrics=%s, drawDirection=%s\n" - " fontAscent=%ld, fontDescent=%ld, maxOverlap=%ld\n", + " terminalFont=%s, constantWidth=%s\n", accel->noOverlap ? "yes" : "no", accel->constantMetrics ? "yes" : "no", accel->terminalFont ? "yes" : "no", - accel->constantWidth ? "yes" : "no", + accel->constantWidth ? "yes" : "no" )); + FT_TRACE5(( " inkInside=%s, inkMetrics=%s, drawDirection=%s\n", accel->inkInside ? "yes" : "no", accel->inkMetrics ? "yes" : "no", - accel->drawDirection ? "RTL" : "LTR", + accel->drawDirection ? "RTL" : "LTR" )); + FT_TRACE5(( " fontAscent=%ld, fontDescent=%ld, maxOverlap=%ld\n", accel->fontAscent, accel->fontDescent, accel->maxOverlap )); @@ -1369,7 +1368,7 @@ THE SOFTWARE. char* s; - if ( FT_ALLOC( face->style_name, len ) ) + if ( FT_QALLOC( face->style_name, len ) ) return error; s = face->style_name; @@ -1533,7 +1532,7 @@ THE SOFTWARE. { l += ft_strlen( foundry_prop->value.atom ) + 1; - if ( FT_NEW_ARRAY( root->family_name, l ) ) + if ( FT_QALLOC( root->family_name, l ) ) goto Exit; ft_strcpy( root->family_name, foundry_prop->value.atom ); @@ -1542,7 +1541,7 @@ THE SOFTWARE. } else { - if ( FT_NEW_ARRAY( root->family_name, l ) ) + if ( FT_QALLOC( root->family_name, l ) ) goto Exit; ft_strcpy( root->family_name, prop->value.atom ); @@ -1566,7 +1565,7 @@ THE SOFTWARE. root->num_glyphs = (FT_Long)face->nmetrics; root->num_fixed_sizes = 1; - if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) + if ( FT_NEW( root->available_sizes ) ) goto Exit; { @@ -1574,8 +1573,6 @@ THE SOFTWARE. FT_Short resolution_x = 0, resolution_y = 0; - FT_ZERO( bsize ); - /* for simplicity, we take absolute values of integer properties */ #if 0 @@ -1616,7 +1613,7 @@ THE SOFTWARE. else { /* this is a heuristical value */ - bsize->width = (FT_Short)FT_MulDiv( bsize->height, 2, 3 ); + bsize->width = ( bsize->height * 2 + 1 ) / 3; } prop = pcf_find_property( face, "POINT_SIZE" ); diff --git a/thirdparty/freetype/src/pcf/rules.mk b/thirdparty/freetype/src/pcf/rules.mk deleted file mode 100644 index 1b55daf4f4..0000000000 --- a/thirdparty/freetype/src/pcf/rules.mk +++ /dev/null @@ -1,82 +0,0 @@ -# -# FreeType 2 pcf driver configuration rules -# - - -# Copyright (C) 2000, 2001, 2003, 2008 by -# Francesco Zappa Nardelli -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - - -# pcf driver directory -# -PCF_DIR := $(SRC_DIR)/pcf - - -PCF_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(PCF_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# pcf driver sources (i.e., C files) -# -PCF_DRV_SRC := $(PCF_DIR)/pcfdrivr.c \ - $(PCF_DIR)/pcfread.c \ - $(PCF_DIR)/pcfutil.c - -# pcf driver headers -# -PCF_DRV_H := $(PCF_DRV_SRC:%.c=%.h) \ - $(PCF_DIR)/pcf.h \ - $(PCF_DIR)/pcferror.h - -# pcf driver object(s) -# -# PCF_DRV_OBJ_M is used during `multi' builds -# PCF_DRV_OBJ_S is used during `single' builds -# -PCF_DRV_OBJ_M := $(PCF_DRV_SRC:$(PCF_DIR)/%.c=$(OBJ_DIR)/%.$O) -PCF_DRV_OBJ_S := $(OBJ_DIR)/pcf.$O - -# pcf driver source file for single build -# -PCF_DRV_SRC_S := $(PCF_DIR)/pcf.c - - -# pcf driver - single object -# -$(PCF_DRV_OBJ_S): $(PCF_DRV_SRC_S) $(PCF_DRV_SRC) $(FREETYPE_H) $(PCF_DRV_H) - $(PCF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PCF_DRV_SRC_S)) - - -# pcf driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(PCF_DIR)/%.c $(FREETYPE_H) $(PCF_DRV_H) - $(PCF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(PCF_DRV_OBJ_S) -DRV_OBJS_M += $(PCF_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/pfr/module.mk b/thirdparty/freetype/src/pfr/module.mk deleted file mode 100644 index 762353dda2..0000000000 --- a/thirdparty/freetype/src/pfr/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 PFR module definition -# - - -# Copyright (C) 2002-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += PFR_DRIVER - -define PFR_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, pfr_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)pfr $(ECHO_DRIVER_DESC)PFR/TrueDoc font files with extension *.pfr$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/pfr/pfr.c b/thirdparty/freetype/src/pfr/pfr.c index 9264c77df2..4058ad5652 100644 --- a/thirdparty/freetype/src/pfr/pfr.c +++ b/thirdparty/freetype/src/pfr/pfr.c @@ -4,7 +4,7 @@ * * FreeType PFR driver component. * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pfr/pfrcmap.c b/thirdparty/freetype/src/pfr/pfrcmap.c index ebc7b84393..6a7f573594 100644 --- a/thirdparty/freetype/src/pfr/pfrcmap.c +++ b/thirdparty/freetype/src/pfr/pfrcmap.c @@ -4,7 +4,7 @@ * * FreeType PFR cmap handling (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pfr/pfrcmap.h b/thirdparty/freetype/src/pfr/pfrcmap.h index a6d920c30b..17c02a2b4b 100644 --- a/thirdparty/freetype/src/pfr/pfrcmap.h +++ b/thirdparty/freetype/src/pfr/pfrcmap.h @@ -4,7 +4,7 @@ * * FreeType PFR cmap handling (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pfr/pfrdrivr.c b/thirdparty/freetype/src/pfr/pfrdrivr.c index b14320875a..16b8f79471 100644 --- a/thirdparty/freetype/src/pfr/pfrdrivr.c +++ b/thirdparty/freetype/src/pfr/pfrdrivr.c @@ -4,7 +4,7 @@ * * FreeType PFR driver interface (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pfr/pfrdrivr.h b/thirdparty/freetype/src/pfr/pfrdrivr.h index 7646b4d1bd..6ff16fea06 100644 --- a/thirdparty/freetype/src/pfr/pfrdrivr.h +++ b/thirdparty/freetype/src/pfr/pfrdrivr.h @@ -4,7 +4,7 @@ * * High-level Type PFR driver interface (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pfr/pfrerror.h b/thirdparty/freetype/src/pfr/pfrerror.h index 33460ef4fd..255696efed 100644 --- a/thirdparty/freetype/src/pfr/pfrerror.h +++ b/thirdparty/freetype/src/pfr/pfrerror.h @@ -4,7 +4,7 @@ * * PFR error codes (specification only). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pfr/pfrgload.c b/thirdparty/freetype/src/pfr/pfrgload.c index aa640c3b07..b400042a86 100644 --- a/thirdparty/freetype/src/pfr/pfrgload.c +++ b/thirdparty/freetype/src/pfr/pfrgload.c @@ -4,7 +4,7 @@ * * FreeType PFR glyph loader (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pfr/pfrgload.h b/thirdparty/freetype/src/pfr/pfrgload.h index f356b4c75b..b726d564fc 100644 --- a/thirdparty/freetype/src/pfr/pfrgload.h +++ b/thirdparty/freetype/src/pfr/pfrgload.h @@ -4,7 +4,7 @@ * * FreeType PFR glyph loader (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pfr/pfrload.c b/thirdparty/freetype/src/pfr/pfrload.c index a2832e55c7..a9c1e2834a 100644 --- a/thirdparty/freetype/src/pfr/pfrload.c +++ b/thirdparty/freetype/src/pfr/pfrload.c @@ -4,7 +4,7 @@ * * FreeType PFR loader (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -565,7 +565,7 @@ if ( phy_font->font_id ) goto Exit; - if ( FT_ALLOC( phy_font->font_id, len + 1 ) ) + if ( FT_QALLOC( phy_font->font_id, len + 1 ) ) goto Exit; /* copy font ID name, and terminate it for safety */ @@ -601,7 +601,7 @@ PFR_CHECK( count * 2 ); - if ( FT_NEW_ARRAY( snaps, count ) ) + if ( FT_QNEW_ARRAY( snaps, count ) ) goto Exit; phy_font->vertical.stem_snaps = snaps; @@ -761,7 +761,7 @@ if ( ok ) { - if ( FT_ALLOC( result, len + 1 ) ) + if ( FT_QALLOC( result, len + 1 ) ) goto Exit; FT_MEM_COPY( result, p, len ); @@ -953,7 +953,7 @@ PFR_CHECK( count * 2 ); - if ( FT_NEW_ARRAY( phy_font->blue_values, count ) ) + if ( FT_QNEW_ARRAY( phy_font->blue_values, count ) ) goto Fail; for ( n = 0; n < count; n++ ) diff --git a/thirdparty/freetype/src/pfr/pfrload.h b/thirdparty/freetype/src/pfr/pfrload.h index 7615b9ce14..4f467d1bad 100644 --- a/thirdparty/freetype/src/pfr/pfrload.h +++ b/thirdparty/freetype/src/pfr/pfrload.h @@ -4,7 +4,7 @@ * * FreeType PFR loader (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pfr/pfrobjs.c b/thirdparty/freetype/src/pfr/pfrobjs.c index 918e7fd496..3080cb650b 100644 --- a/thirdparty/freetype/src/pfr/pfrobjs.c +++ b/thirdparty/freetype/src/pfr/pfrobjs.c @@ -4,7 +4,7 @@ * * FreeType PFR object methods (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -83,7 +83,11 @@ /* load the header and check it */ error = pfr_header_load( &face->header, stream ); if ( error ) + { + FT_TRACE2(( " not a PFR font\n" )); + error = FT_THROW( Unknown_File_Format ); goto Exit; + } if ( !pfr_header_check( &face->header ) ) { @@ -213,7 +217,7 @@ FT_Memory memory = pfrface->stream->memory; - if ( FT_NEW_ARRAY( pfrface->available_sizes, count ) ) + if ( FT_QNEW_ARRAY( pfrface->available_sizes, count ) ) goto Exit; size = pfrface->available_sizes; diff --git a/thirdparty/freetype/src/pfr/pfrobjs.h b/thirdparty/freetype/src/pfr/pfrobjs.h index 808822f1c4..70b05395b8 100644 --- a/thirdparty/freetype/src/pfr/pfrobjs.h +++ b/thirdparty/freetype/src/pfr/pfrobjs.h @@ -4,7 +4,7 @@ * * FreeType PFR object methods (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pfr/pfrsbit.c b/thirdparty/freetype/src/pfr/pfrsbit.c index a6691e6d18..255fd58772 100644 --- a/thirdparty/freetype/src/pfr/pfrsbit.c +++ b/thirdparty/freetype/src/pfr/pfrsbit.c @@ -4,7 +4,7 @@ * * FreeType PFR bitmap loader (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -310,8 +310,8 @@ if ( lim > limit ) { FT_TRACE0(( "pfr_lookup_bitmap_data:" - " number of bitmap records too large,\n" - " " + " number of bitmap records too large,\n" )); + FT_TRACE0(( " " " thus ignoring all bitmaps in this strike\n" )); *flags &= ~PFR_BITMAP_VALID_CHARCODES; } @@ -328,8 +328,8 @@ if ( (FT_Long)code <= prev_code ) { FT_TRACE0(( "pfr_lookup_bitmap_data:" - " bitmap records are not sorted,\n" - " " + " bitmap records are not sorted,\n" )); + FT_TRACE0(( " " " thus ignoring all bitmaps in this strike\n" )); *flags &= ~PFR_BITMAP_VALID_CHARCODES; break; diff --git a/thirdparty/freetype/src/pfr/pfrsbit.h b/thirdparty/freetype/src/pfr/pfrsbit.h index 8cb0de0d25..f50d8013aa 100644 --- a/thirdparty/freetype/src/pfr/pfrsbit.h +++ b/thirdparty/freetype/src/pfr/pfrsbit.h @@ -4,7 +4,7 @@ * * FreeType PFR bitmap loader (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pfr/pfrtypes.h b/thirdparty/freetype/src/pfr/pfrtypes.h index 06fb82d51a..dc4fead700 100644 --- a/thirdparty/freetype/src/pfr/pfrtypes.h +++ b/thirdparty/freetype/src/pfr/pfrtypes.h @@ -4,7 +4,7 @@ * * FreeType PFR data structures (specification only). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -109,7 +109,7 @@ FT_BEGIN_HEADER #define PFR_BITMAP_2BYTE_SIZE 0x02U #define PFR_BITMAP_3BYTE_OFFSET 0x04U - /*not part of the specification but used for implementation */ + /* not part of the specification but used for implementation */ #define PFR_BITMAP_CHARCODES_VALIDATED 0x40U #define PFR_BITMAP_VALID_CHARCODES 0x80U diff --git a/thirdparty/freetype/src/pfr/rules.mk b/thirdparty/freetype/src/pfr/rules.mk deleted file mode 100644 index a1fe82baff..0000000000 --- a/thirdparty/freetype/src/pfr/rules.mk +++ /dev/null @@ -1,76 +0,0 @@ -# -# FreeType 2 PFR driver configuration rules -# - - -# Copyright (C) 2002-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# pfr driver directory -# -PFR_DIR := $(SRC_DIR)/pfr - - -# compilation flags for the driver -# -PFR_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(PFR_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# pfr driver sources (i.e., C files) -# -PFR_DRV_SRC := $(PFR_DIR)/pfrload.c \ - $(PFR_DIR)/pfrgload.c \ - $(PFR_DIR)/pfrcmap.c \ - $(PFR_DIR)/pfrdrivr.c \ - $(PFR_DIR)/pfrsbit.c \ - $(PFR_DIR)/pfrobjs.c - -# pfr driver headers -# -PFR_DRV_H := $(PFR_DRV_SRC:%.c=%.h) \ - $(PFR_DIR)/pfrerror.h \ - $(PFR_DIR)/pfrtypes.h - - -# Pfr driver object(s) -# -# PFR_DRV_OBJ_M is used during `multi' builds -# PFR_DRV_OBJ_S is used during `single' builds -# -PFR_DRV_OBJ_M := $(PFR_DRV_SRC:$(PFR_DIR)/%.c=$(OBJ_DIR)/%.$O) -PFR_DRV_OBJ_S := $(OBJ_DIR)/pfr.$O - -# pfr driver source file for single build -# -PFR_DRV_SRC_S := $(PFR_DIR)/pfr.c - - -# pfr driver - single object -# -$(PFR_DRV_OBJ_S): $(PFR_DRV_SRC_S) $(PFR_DRV_SRC) $(FREETYPE_H) $(PFR_DRV_H) - $(PFR_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PFR_DRV_SRC_S)) - - -# pfr driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(PFR_DIR)/%.c $(FREETYPE_H) $(PFR_DRV_H) - $(PFR_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(PFR_DRV_OBJ_S) -DRV_OBJS_M += $(PFR_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/psaux/afmparse.c b/thirdparty/freetype/src/psaux/afmparse.c index 2d6a0d9a12..0ad1760518 100644 --- a/thirdparty/freetype/src/psaux/afmparse.c +++ b/thirdparty/freetype/src/psaux/afmparse.c @@ -4,7 +4,7 @@ * * AFM parser (body). * - * Copyright (C) 2006-2020 by + * Copyright (C) 2006-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -29,6 +29,16 @@ /************************************************************************** * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ +#undef FT_COMPONENT +#define FT_COMPONENT afmparse + + + /************************************************************************** + * * AFM_Stream * * The use of AFM_Stream is largely inspired by parseAFM.[ch] from t1lib. @@ -586,21 +596,39 @@ static FT_Error afm_parse_track_kern( AFM_Parser parser ) { - AFM_FontInfo fi = parser->FontInfo; + AFM_FontInfo fi = parser->FontInfo; + AFM_Stream stream = parser->stream; AFM_TrackKern tk; - char* key; - FT_Offset len; - int n = -1; - FT_Int tmp; + + char* key; + FT_Offset len; + int n = -1; + FT_Int tmp; if ( afm_parser_read_int( parser, &tmp ) ) goto Fail; if ( tmp < 0 ) + { + FT_ERROR(( "afm_parse_track_kern: invalid number of track kerns\n" )); goto Fail; + } fi->NumTrackKern = (FT_UInt)tmp; + FT_TRACE3(( "afm_parse_track_kern: %u track kern%s expected\n", + fi->NumTrackKern, + fi->NumTrackKern == 1 ? "" : "s" )); + + /* Rough sanity check: The minimum line length of the `TrackKern` */ + /* command is 20 characters (including the EOL character). */ + if ( (FT_ULong)( stream->limit - stream->cursor ) / 20 < + fi->NumTrackKern ) + { + FT_ERROR(( "afm_parse_track_kern:" + " number of track kern entries exceeds stream size\n" )); + goto Fail; + } if ( fi->NumTrackKern ) { @@ -623,7 +651,10 @@ n++; if ( n >= (int)fi->NumTrackKern ) - goto Fail; + { + FT_ERROR(( "afm_parse_track_kern: too many track kern data\n" )); + goto Fail; + } tk = fi->TrackKerns + n; @@ -633,7 +664,12 @@ shared_vals[3].type = AFM_VALUE_TYPE_FIXED; shared_vals[4].type = AFM_VALUE_TYPE_FIXED; if ( afm_parser_read_vals( parser, shared_vals, 5 ) != 5 ) + { + FT_ERROR(( "afm_parse_track_kern:" + " insufficient number of parameters for entry %d\n", + n )); goto Fail; + } tk->degree = shared_vals[0].u.i; tk->min_ptsize = shared_vals[1].u.f; @@ -646,7 +682,19 @@ case AFM_TOKEN_ENDTRACKKERN: case AFM_TOKEN_ENDKERNDATA: case AFM_TOKEN_ENDFONTMETRICS: - fi->NumTrackKern = (FT_UInt)( n + 1 ); + tmp = n + 1; + if ( (FT_UInt)tmp != fi->NumTrackKern ) + { + FT_TRACE1(( "afm_parse_track_kern: %s%d track kern entr%s seen\n", + tmp == 0 ? "" : "only ", + tmp, + tmp == 1 ? "y" : "ies" )); + fi->NumTrackKern = (FT_UInt)tmp; + } + else + FT_TRACE3(( "afm_parse_track_kern: %d track kern entr%s seen\n", + tmp, + tmp == 1 ? "y" : "ies" )); return FT_Err_Ok; case AFM_TOKEN_UNKNOWN: @@ -667,7 +715,7 @@ /* compare two kerning pairs */ - FT_CALLBACK_DEF( int ) + FT_COMPARE_DEF( int ) afm_compare_kern_pairs( const void* a, const void* b ) { @@ -690,7 +738,8 @@ static FT_Error afm_parse_kern_pairs( AFM_Parser parser ) { - AFM_FontInfo fi = parser->FontInfo; + AFM_FontInfo fi = parser->FontInfo; + AFM_Stream stream = parser->stream; AFM_KernPair kp; char* key; FT_Offset len; @@ -702,9 +751,26 @@ goto Fail; if ( tmp < 0 ) + { + FT_ERROR(( "afm_parse_kern_pairs: invalid number of kern pairs\n" )); goto Fail; + } fi->NumKernPair = (FT_UInt)tmp; + FT_TRACE3(( "afm_parse_kern_pairs: %u kern pair%s expected\n", + fi->NumKernPair, + fi->NumKernPair == 1 ? "" : "s" )); + + /* Rough sanity check: The minimum line length of the `KP`, */ + /* `KPH`,`KPX`, and `KPY` commands is 10 characters (including */ + /* the EOL character). */ + if ( (FT_ULong)( stream->limit - stream->cursor ) / 10 < + fi->NumKernPair ) + { + FT_ERROR(( "afm_parse_kern_pairs:" + " number of kern pairs exceeds stream size\n" )); + goto Fail; + } if ( fi->NumKernPair ) { @@ -734,7 +800,10 @@ n++; if ( n >= (int)fi->NumKernPair ) + { + FT_ERROR(( "afm_parse_kern_pairs: too many kern pairs\n" )); goto Fail; + } kp = fi->KernPairs + n; @@ -744,7 +813,12 @@ shared_vals[3].type = AFM_VALUE_TYPE_INTEGER; r = afm_parser_read_vals( parser, shared_vals, 4 ); if ( r < 3 ) + { + FT_ERROR(( "afm_parse_kern_pairs:" + " insufficient number of parameters for entry %d\n", + n )); goto Fail; + } /* index values can't be negative */ kp->index1 = shared_vals[0].u.u; @@ -766,7 +840,20 @@ case AFM_TOKEN_ENDKERNPAIRS: case AFM_TOKEN_ENDKERNDATA: case AFM_TOKEN_ENDFONTMETRICS: - fi->NumKernPair = (FT_UInt)( n + 1 ); + tmp = n + 1; + if ( (FT_UInt)tmp != fi->NumKernPair ) + { + FT_TRACE1(( "afm_parse_kern_pairs: %s%d kern pair%s seen\n", + tmp == 0 ? "" : "only ", + tmp, + tmp == 1 ? "" : "s" )); + fi->NumKernPair = (FT_UInt)tmp; + } + else + FT_TRACE3(( "afm_parse_kern_pairs: %d kern pair%s seen\n", + tmp, + tmp == 1 ? "" : "s" )); + ft_qsort( fi->KernPairs, fi->NumKernPair, sizeof ( AFM_KernPairRec ), afm_compare_kern_pairs ); @@ -792,22 +879,43 @@ char* key; FT_Offset len; + int have_trackkern = 0; + int have_kernpairs = 0; + while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) { switch ( afm_tokenize( key, len ) ) { case AFM_TOKEN_STARTTRACKKERN: + if ( have_trackkern ) + { + FT_ERROR(( "afm_parse_kern_data:" + " invalid second horizontal track kern section\n" )); + goto Fail; + } + error = afm_parse_track_kern( parser ); if ( error ) return error; + + have_trackkern = 1; break; case AFM_TOKEN_STARTKERNPAIRS: case AFM_TOKEN_STARTKERNPAIRS0: + if ( have_kernpairs ) + { + FT_ERROR(( "afm_parse_kern_data:" + " invalid second horizontal kern pair section\n" )); + goto Fail; + } + error = afm_parse_kern_pairs( parser ); if ( error ) return error; + + have_kernpairs = 1; break; case AFM_TOKEN_ENDKERNDATA: diff --git a/thirdparty/freetype/src/psaux/afmparse.h b/thirdparty/freetype/src/psaux/afmparse.h index 16a3a3e902..44b05b2cac 100644 --- a/thirdparty/freetype/src/psaux/afmparse.h +++ b/thirdparty/freetype/src/psaux/afmparse.h @@ -4,7 +4,7 @@ * * AFM parser (specification). * - * Copyright (C) 2006-2020 by + * Copyright (C) 2006-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/psaux/cffdecode.c b/thirdparty/freetype/src/psaux/cffdecode.c index 3d2da1e03c..29b68a8e4f 100644 --- a/thirdparty/freetype/src/psaux/cffdecode.c +++ b/thirdparty/freetype/src/psaux/cffdecode.c @@ -4,7 +4,7 @@ * * PostScript CFF (Type 2) decoding routines (body). * - * Copyright (C) 2017-2020 by + * Copyright (C) 2017-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -1871,7 +1871,7 @@ case cff_op_put: { FT_Fixed val = args[0]; - FT_Int idx = (FT_Int)( args[1] >> 16 ); + FT_UInt idx = (FT_UInt)( args[1] >> 16 ); FT_TRACE4(( " put\n" )); @@ -1880,20 +1880,20 @@ /* didn't give a hard-coded size limit of the temporary */ /* storage array; instead, an argument of the */ /* `MultipleMaster' operator set the size */ - if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) + if ( idx < CFF_MAX_TRANS_ELEMENTS ) decoder->buildchar[idx] = val; } break; case cff_op_get: { - FT_Int idx = (FT_Int)( args[0] >> 16 ); + FT_UInt idx = (FT_UInt)( args[0] >> 16 ); FT_Fixed val = 0; FT_TRACE4(( " get\n" )); - if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) + if ( idx < CFF_MAX_TRANS_ELEMENTS ) val = decoder->buildchar[idx]; args[0] = val; @@ -1914,9 +1914,9 @@ /* this operator was removed from the Type2 specification */ /* in version 16-March-2000 */ { - FT_Int reg_idx = (FT_Int)args[0]; - FT_Int idx = (FT_Int)args[1]; - FT_Int count = (FT_Int)args[2]; + FT_UInt reg_idx = (FT_UInt)args[0]; + FT_UInt idx = (FT_UInt)args[1]; + FT_UInt count = (FT_UInt)args[2]; FT_TRACE4(( " load\n" )); @@ -1924,11 +1924,11 @@ /* since we currently don't handle interpolation of multiple */ /* master fonts, we store a vector [1 0 0 ...] in the */ /* temporary storage array regardless of the Registry index */ - if ( reg_idx >= 0 && reg_idx <= 2 && - idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS && - count >= 0 && count <= num_axes ) + if ( reg_idx <= 2 && + idx < CFF_MAX_TRANS_ELEMENTS && + count <= num_axes ) { - FT_Int end, i; + FT_UInt end, i; end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS ); @@ -2153,7 +2153,7 @@ decoder->locals_bias ); - FT_TRACE4(( " callsubr (idx %d, entering level %d)\n", + FT_TRACE4(( " callsubr (idx %d, entering level %ld)\n", idx, zone - decoder->zones + 1 )); @@ -2197,7 +2197,7 @@ decoder->globals_bias ); - FT_TRACE4(( " callgsubr (idx %d, entering level %d)\n", + FT_TRACE4(( " callgsubr (idx %d, entering level %ld)\n", idx, zone - decoder->zones + 1 )); @@ -2236,7 +2236,7 @@ break; case cff_op_return: - FT_TRACE4(( " return (leaving level %d)\n", + FT_TRACE4(( " return (leaving level %ld)\n", decoder->zone - decoder->zones )); if ( decoder->zone <= decoder->zones ) @@ -2271,7 +2271,8 @@ } /* while ip < limit */ - FT_TRACE4(( "..end..\n\n" )); + FT_TRACE4(( "..end..\n" )); + FT_TRACE4(( "\n" )); Fail: return error; diff --git a/thirdparty/freetype/src/psaux/cffdecode.h b/thirdparty/freetype/src/psaux/cffdecode.h index 77a4962698..b1314ed1c1 100644 --- a/thirdparty/freetype/src/psaux/cffdecode.h +++ b/thirdparty/freetype/src/psaux/cffdecode.h @@ -4,7 +4,7 @@ * * PostScript CFF (Type 2) decoding routines (specification). * - * Copyright (C) 2017-2020 by + * Copyright (C) 2017-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/psaux/module.mk b/thirdparty/freetype/src/psaux/module.mk deleted file mode 100644 index 651db01426..0000000000 --- a/thirdparty/freetype/src/psaux/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 PSaux module definition -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += PSAUX_MODULE - -define PSAUX_MODULE -$(OPEN_DRIVER) FT_Module_Class, psaux_module_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)psaux $(ECHO_DRIVER_DESC)Postscript Type 1 & Type 2 helper module$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/psaux/psarrst.c b/thirdparty/freetype/src/psaux/psarrst.c index 8751d275fb..70313d283a 100644 --- a/thirdparty/freetype/src/psaux/psarrst.c +++ b/thirdparty/freetype/src/psaux/psarrst.c @@ -65,7 +65,6 @@ arrstack->error = error; arrstack->sizeItem = sizeItem; arrstack->allocated = 0; - arrstack->chunk = 10; /* chunks of 10 items */ arrstack->count = 0; arrstack->totalSize = 0; arrstack->ptr = NULL; @@ -110,7 +109,7 @@ FT_ASSERT( newSize > 0 ); /* avoid realloc with zero size */ - if ( !FT_REALLOC( arrstack->ptr, arrstack->totalSize, newSize ) ) + if ( !FT_QREALLOC( arrstack->ptr, arrstack->totalSize, newSize ) ) { arrstack->allocated = numElements; arrstack->totalSize = newSize; @@ -216,9 +215,9 @@ if ( arrstack->count == arrstack->allocated ) { - /* grow the buffer by one chunk */ + /* increase the buffer size */ if ( !cf2_arrstack_setNumElements( - arrstack, arrstack->allocated + arrstack->chunk ) ) + arrstack, arrstack->allocated * 2 + 16 ) ) { /* on error, ignore the push */ return; diff --git a/thirdparty/freetype/src/psaux/psarrst.h b/thirdparty/freetype/src/psaux/psarrst.h index 098617b257..31e5330cc3 100644 --- a/thirdparty/freetype/src/psaux/psarrst.h +++ b/thirdparty/freetype/src/psaux/psarrst.h @@ -55,7 +55,6 @@ FT_BEGIN_HEADER size_t sizeItem; /* bytes per element */ size_t allocated; /* items allocated */ - size_t chunk; /* allocation increment in items */ size_t count; /* number of elements allocated */ size_t totalSize; /* total bytes allocated */ diff --git a/thirdparty/freetype/src/psaux/psaux.c b/thirdparty/freetype/src/psaux/psaux.c index f4282222a6..2960c8b696 100644 --- a/thirdparty/freetype/src/psaux/psaux.c +++ b/thirdparty/freetype/src/psaux/psaux.c @@ -4,7 +4,7 @@ * * FreeType auxiliary PostScript driver component (body only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/psaux/psauxerr.h b/thirdparty/freetype/src/psaux/psauxerr.h index 8b9a958aec..e8ee29166c 100644 --- a/thirdparty/freetype/src/psaux/psauxerr.h +++ b/thirdparty/freetype/src/psaux/psauxerr.h @@ -4,7 +4,7 @@ * * PS auxiliary module error codes (specification only). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/psaux/psauxmod.c b/thirdparty/freetype/src/psaux/psauxmod.c index e73ba22451..52da23365e 100644 --- a/thirdparty/freetype/src/psaux/psauxmod.c +++ b/thirdparty/freetype/src/psaux/psauxmod.c @@ -4,7 +4,7 @@ * * FreeType auxiliary PostScript module implementation (body). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/psaux/psauxmod.h b/thirdparty/freetype/src/psaux/psauxmod.h index a6bebe4b94..e3e8063220 100644 --- a/thirdparty/freetype/src/psaux/psauxmod.h +++ b/thirdparty/freetype/src/psaux/psauxmod.h @@ -4,7 +4,7 @@ * * FreeType auxiliary PostScript module implementation (specification). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/psaux/psblues.c b/thirdparty/freetype/src/psaux/psblues.c index 3878e9bde0..f9c864fea9 100644 --- a/thirdparty/freetype/src/psaux/psblues.c +++ b/thirdparty/freetype/src/psaux/psblues.c @@ -506,7 +506,8 @@ /* guarantee minimum of 1 pixel overshoot */ dsNew = FT_MIN( cf2_fixedRound( bottomHintEdge->dsCoord ), - blues->zone[i].dsFlatEdge - cf2_intToFixed( 1 ) ); + SUB_INT32( blues->zone[i].dsFlatEdge, + cf2_intToFixed( 1 ) ) ); } else diff --git a/thirdparty/freetype/src/psaux/psconv.c b/thirdparty/freetype/src/psaux/psconv.c index 4cf5cd5d88..c28d65df29 100644 --- a/thirdparty/freetype/src/psaux/psconv.c +++ b/thirdparty/freetype/src/psaux/psconv.c @@ -4,7 +4,7 @@ * * Some convenience conversions (body). * - * Copyright (C) 2006-2020 by + * Copyright (C) 2006-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/psaux/psconv.h b/thirdparty/freetype/src/psaux/psconv.h index 833e827364..cd91a7bb56 100644 --- a/thirdparty/freetype/src/psaux/psconv.h +++ b/thirdparty/freetype/src/psaux/psconv.h @@ -4,7 +4,7 @@ * * Some convenience conversions (specification). * - * Copyright (C) 2006-2020 by + * Copyright (C) 2006-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/psaux/psft.c b/thirdparty/freetype/src/psaux/psft.c index 41c16542c1..ac72d8259c 100644 --- a/thirdparty/freetype/src/psaux/psft.c +++ b/thirdparty/freetype/src/psaux/psft.c @@ -742,13 +742,13 @@ /* For ordinary fonts get the character data stored in the face record. */ { glyph_data.pointer = type1->charstrings[glyph_index]; - glyph_data.length = (FT_Int)type1->charstrings_len[glyph_index]; + glyph_data.length = type1->charstrings_len[glyph_index]; } if ( !error ) { FT_Byte* charstring_base = (FT_Byte*)glyph_data.pointer; - FT_ULong charstring_len = (FT_ULong)glyph_data.length; + FT_ULong charstring_len = glyph_data.length; FT_ASSERT( charstring_base + charstring_len >= charstring_base ); @@ -778,7 +778,7 @@ face = (T1_Face)decoder->builder.face; data.pointer = buf->start; - data.length = (FT_Int)( buf->end - buf->start ); + data.length = (FT_UInt)( buf->end - buf->start ); if ( face->root.internal->incremental_interface ) face->root.internal->incremental_interface->funcs->free_glyph_data( diff --git a/thirdparty/freetype/src/psaux/pshints.c b/thirdparty/freetype/src/psaux/pshints.c index ce8cfca715..ad472c98df 100644 --- a/thirdparty/freetype/src/psaux/pshints.c +++ b/thirdparty/freetype/src/psaux/pshints.c @@ -412,6 +412,12 @@ { FT_Bool isPair = cf2_hint_isPair( &hintmap->edge[i] ); + /* final amount to move edge or edge pair */ + CF2_Fixed move = 0; + + CF2_Fixed dsCoord_i; + CF2_Fixed dsCoord_j; + /* index of upper edge (same value for ghost hint) */ j = isPair ? i + 1 : i; @@ -422,11 +428,14 @@ FT_ASSERT( cf2_hint_isLocked( &hintmap->edge[i] ) == cf2_hint_isLocked( &hintmap->edge[j] ) ); + dsCoord_i = hintmap->edge[i].dsCoord; + dsCoord_j = hintmap->edge[j].dsCoord; + if ( !cf2_hint_isLocked( &hintmap->edge[i] ) ) { /* hint edge is not locked, we can adjust it */ - CF2_Fixed fracDown = cf2_fixedFraction( hintmap->edge[i].dsCoord ); - CF2_Fixed fracUp = cf2_fixedFraction( hintmap->edge[j].dsCoord ); + CF2_Fixed fracDown = cf2_fixedFraction( dsCoord_i ); + CF2_Fixed fracUp = cf2_fixedFraction( dsCoord_j ); /* calculate all four possibilities; moves down are negative */ CF2_Fixed downMoveDown = 0 - fracDown; @@ -443,9 +452,6 @@ /* smallest move down */ CF2_Fixed moveDown = FT_MAX( downMoveDown, upMoveDown ); - /* final amount to move edge or edge pair */ - CF2_Fixed move; - CF2_Fixed downMinCounter = CF2_MIN_COUNTER; CF2_Fixed upMinCounter = CF2_MIN_COUNTER; FT_Bool saveEdge = FALSE; @@ -467,16 +473,14 @@ /* is there room to move up? */ /* there is if we are at top of array or the next edge is at or */ /* beyond proposed move up? */ - if ( j >= hintmap->count - 1 || + if ( j >= hintmap->count - 1 || hintmap->edge[j + 1].dsCoord >= - ADD_INT32( hintmap->edge[j].dsCoord, - moveUp + upMinCounter ) ) + ADD_INT32( dsCoord_j, moveUp + upMinCounter ) ) { /* there is room to move up; is there also room to move down? */ - if ( i == 0 || + if ( i == 0 || hintmap->edge[i - 1].dsCoord <= - ADD_INT32( hintmap->edge[i].dsCoord, - moveDown - downMinCounter ) ) + ADD_INT32( dsCoord_i, moveDown - downMinCounter ) ) { /* move smaller absolute amount */ move = ( -moveDown < moveUp ) ? moveDown : moveUp; /* optimum */ @@ -487,10 +491,9 @@ else { /* is there room to move down? */ - if ( i == 0 || + if ( i == 0 || hintmap->edge[i - 1].dsCoord <= - ADD_INT32( hintmap->edge[i].dsCoord, - moveDown - downMinCounter ) ) + ADD_INT32( dsCoord_i, moveDown - downMinCounter ) ) { move = moveDown; /* true if non-optimum move */ @@ -524,17 +527,21 @@ } /* move the edge(s) */ - hintmap->edge[i].dsCoord = ADD_INT32( hintmap->edge[i].dsCoord, - move ); + hintmap->edge[i].dsCoord = ADD_INT32( dsCoord_i, move ); if ( isPair ) - hintmap->edge[j].dsCoord = ADD_INT32( hintmap->edge[j].dsCoord, - move ); + hintmap->edge[j].dsCoord = ADD_INT32( dsCoord_j, move ); } - /* assert there are no overlaps in device space */ + /* assert there are no overlaps in device space; */ + /* ignore tests if there was overflow (that is, if */ + /* operands have the same sign but the sum does not) */ FT_ASSERT( i == 0 || + ( ( dsCoord_i ^ move ) >= 0 && + ( dsCoord_i ^ hintmap->edge[i].dsCoord ) < 0 ) || hintmap->edge[i - 1].dsCoord <= hintmap->edge[i].dsCoord ); FT_ASSERT( i < j || + ( ( dsCoord_j ^ move ) >= 0 && + ( dsCoord_j ^ hintmap->edge[j].dsCoord ) < 0 ) || hintmap->edge[i].dsCoord <= hintmap->edge[j].dsCoord ); /* adjust the scales, avoiding divide by zero */ @@ -1022,10 +1029,17 @@ } } - FT_TRACE6(( "%s\n", initialMap ? "flags: [p]air [g]host [t]op" - " [b]ottom [L]ocked [S]ynthetic\n" - "Initial hintmap" - : "Hints:" )); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( initialMap ) + { + FT_TRACE6(( "flags: [p]air [g]host [t]op" + " [b]ottom [L]ocked [S]ynthetic\n" )); + FT_TRACE6(( "Initial hintmap" )); + } + else + FT_TRACE6(( "Hints:" )); +#endif + cf2_hintmap_dump( hintmap ); /* diff --git a/thirdparty/freetype/src/psaux/psintrp.c b/thirdparty/freetype/src/psaux/psintrp.c index 519c694447..c550533a0f 100644 --- a/thirdparty/freetype/src/psaux/psintrp.c +++ b/thirdparty/freetype/src/psaux/psintrp.c @@ -469,7 +469,7 @@ */ FT_LOCAL_DEF( void ) cf2_interpT2CharString( CF2_Font font, - CF2_Buffer buf, + const CF2_Buffer buf, CF2_OutlineCallbacks callbacks, const FT_Vector* translation, FT_Bool doingSeac, @@ -1340,9 +1340,9 @@ if ( decoder->glyph_names == 0 ) #endif /* FT_CONFIG_OPTION_INCREMENTAL */ { - FT_ERROR(( - "cf2_interpT2CharString: (Type 1 seac)" - " glyph names table not available in this font\n" )); + FT_ERROR(( "cf2_interpT2CharString:\n" )); + FT_ERROR(( " (Type 1 seac) glyph names table" + " not available in this font\n" )); lastError = FT_THROW( Invalid_Glyph_Format ); goto exit; } @@ -1368,9 +1368,9 @@ if ( bchar_index < 0 || achar_index < 0 ) { - FT_ERROR(( - "cf2_interpT2CharString: (Type 1 seac)" - " invalid seac character code arguments\n" )); + FT_ERROR(( "cf2_interpT2CharString:\n" )); + FT_ERROR(( " (Type 1 seac) invalid" + " seac character code arguments\n" )); lastError = FT_THROW( Invalid_Glyph_Format ); goto exit; } @@ -1670,7 +1670,13 @@ */ count = cf2_stack_count( opStack ); - FT_ASSERT( (CF2_UInt)arg_cnt <= count ); + if ( (CF2_UInt)arg_cnt > count ) + { + FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):" + " stack underflow\n" )); + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } opIdx += count - (CF2_UInt)arg_cnt; @@ -1893,18 +1899,17 @@ /* cvi( <idx> ) of BuildCharArray with */ /* WeightVector */ { - FT_Int idx; + FT_UInt idx; PS_Blend blend = decoder->blend; if ( arg_cnt != 1 || !blend ) goto Unexpected_OtherSubr; - idx = cf2_stack_popInt( opStack ); + idx = (FT_UInt)cf2_stack_popInt( opStack ); - if ( idx < 0 || - (FT_UInt)idx + blend->num_designs > - decoder->len_buildchar ) + if ( idx + blend->num_designs > + decoder->len_buildchar ) goto Unexpected_OtherSubr; ft_memcpy( &decoder->buildchar[idx], @@ -2004,17 +2009,16 @@ /* <val> <idx> 2 24 callothersubr */ /* ==> set BuildCharArray[cvi( <idx> )] = <val> */ { - CF2_Int idx; + CF2_UInt idx; PS_Blend blend = decoder->blend; if ( arg_cnt != 2 || !blend ) goto Unexpected_OtherSubr; - idx = cf2_stack_popInt( opStack ); + idx = (CF2_UInt)cf2_stack_popInt( opStack ); - if ( idx < 0 || - (FT_UInt)idx >= decoder->len_buildchar ) + if ( idx >= decoder->len_buildchar ) goto Unexpected_OtherSubr; decoder->buildchar[idx] = @@ -2027,17 +2031,16 @@ /* ==> push BuildCharArray[cvi( idx )] */ /* onto T1 stack */ { - CF2_Int idx; + CF2_UInt idx; PS_Blend blend = decoder->blend; if ( arg_cnt != 1 || !blend ) goto Unexpected_OtherSubr; - idx = cf2_stack_popInt( opStack ); + idx = (CF2_UInt)cf2_stack_popInt( opStack ); - if ( idx < 0 || - (FT_UInt)idx >= decoder->len_buildchar ) + if ( idx >= decoder->len_buildchar ) goto Unexpected_OtherSubr; cf2_stack_pushFixed( opStack, @@ -2179,29 +2182,29 @@ case cf2_escPUT: { CF2_F16Dot16 val; - CF2_Int idx; + CF2_UInt idx; FT_TRACE4(( " put\n" )); - idx = cf2_stack_popInt( opStack ); + idx = (CF2_UInt)cf2_stack_popInt( opStack ); val = cf2_stack_popFixed( opStack ); - if ( idx >= 0 && idx < CF2_STORAGE_SIZE ) + if ( idx < CF2_STORAGE_SIZE ) storage[idx] = val; } continue; /* do not clear the stack */ case cf2_escGET: { - CF2_Int idx; + CF2_UInt idx; FT_TRACE4(( " get\n" )); - idx = cf2_stack_popInt( opStack ); + idx = (CF2_UInt)cf2_stack_popInt( opStack ); - if ( idx >= 0 && idx < CF2_STORAGE_SIZE ) + if ( idx < CF2_STORAGE_SIZE ) cf2_stack_pushFixed( opStack, storage[idx] ); } continue; /* do not clear the stack */ diff --git a/thirdparty/freetype/src/psaux/psintrp.h b/thirdparty/freetype/src/psaux/psintrp.h index 669c09c0ae..d8b9342ecb 100644 --- a/thirdparty/freetype/src/psaux/psintrp.h +++ b/thirdparty/freetype/src/psaux/psintrp.h @@ -65,7 +65,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) cf2_interpT2CharString( CF2_Font font, - CF2_Buffer charstring, + const CF2_Buffer buf, CF2_OutlineCallbacks callbacks, const FT_Vector* translation, FT_Bool doingSeac, diff --git a/thirdparty/freetype/src/psaux/psobjs.c b/thirdparty/freetype/src/psaux/psobjs.c index defc4d4fce..30f501916a 100644 --- a/thirdparty/freetype/src/psaux/psobjs.c +++ b/thirdparty/freetype/src/psaux/psobjs.c @@ -4,7 +4,7 @@ * * Auxiliary functions for PostScript fonts (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -251,7 +251,7 @@ if ( !old_base ) return; - if ( FT_ALLOC( table->block, table->cursor ) ) + if ( FT_QALLOC( table->block, table->cursor ) ) return; FT_MEM_COPY( table->block, old_base, table->cursor ); shift_elements( table, old_base ); @@ -595,10 +595,10 @@ if ( cur < limit && cur == parser->cursor ) { FT_ERROR(( "ps_parser_skip_PS_token:" - " current token is `%c' which is self-delimiting\n" - " " - " but invalid at this point\n", + " current token is `%c' which is self-delimiting\n", *cur )); + FT_ERROR(( " " + " but invalid at this point\n" )); error = FT_THROW( Invalid_File_Format ); } @@ -979,7 +979,7 @@ } len = (FT_UInt)( cur - *cursor ); - if ( cur >= limit || FT_ALLOC( result, len + 1 ) ) + if ( cur >= limit || FT_QALLOC( result, len + 1 ) ) return 0; /* now copy the string */ @@ -1175,8 +1175,8 @@ else { FT_ERROR(( "ps_parser_load_field:" - " expected a name or string\n" - " " + " expected a name or string\n" )); + FT_ERROR(( " " " but found token of type %d instead\n", token.type )); error = FT_THROW( Invalid_File_Format ); @@ -1193,7 +1193,7 @@ *(FT_String**)q = NULL; } - if ( FT_ALLOC( string, len + 1 ) ) + if ( FT_QALLOC( string, len + 1 ) ) goto Exit; FT_MEM_COPY( string, cur, len ); @@ -1248,7 +1248,7 @@ FT_UInt i; - if ( FT_NEW_ARRAY( temp, max_objects * 4 ) ) + if ( FT_QNEW_ARRAY( temp, max_objects * 4 ) ) goto Exit; for ( i = 0; i < 4; i++ ) @@ -1258,14 +1258,14 @@ if ( result < 0 || (FT_UInt)result < max_objects ) { FT_ERROR(( "ps_parser_load_field:" - " expected %d integer%s in the %s subarray\n" - " " - " of /FontBBox in the /Blend dictionary\n", + " expected %d integer%s in the %s subarray\n", max_objects, max_objects > 1 ? "s" : "", i == 0 ? "first" : ( i == 1 ? "second" : ( i == 2 ? "third" : "fourth" ) ) )); + FT_ERROR(( " " + " of /FontBBox in the /Blend dictionary\n" )); error = FT_THROW( Invalid_File_Format ); FT_FREE( temp ); diff --git a/thirdparty/freetype/src/psaux/psobjs.h b/thirdparty/freetype/src/psaux/psobjs.h index fdad672b6d..99d16959a7 100644 --- a/thirdparty/freetype/src/psaux/psobjs.h +++ b/thirdparty/freetype/src/psaux/psobjs.h @@ -4,7 +4,7 @@ * * Auxiliary functions for PostScript fonts (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/psaux/psstack.c b/thirdparty/freetype/src/psaux/psstack.c index 7ae5256ef1..797486588a 100644 --- a/thirdparty/freetype/src/psaux/psstack.c +++ b/thirdparty/freetype/src/psaux/psstack.c @@ -54,20 +54,18 @@ FT_Error* e, FT_UInt stackSize ) { - FT_Error error = FT_Err_Ok; /* for FT_NEW */ - + FT_Error error; /* for FT_QNEW */ CF2_Stack stack = NULL; - if ( FT_NEW( stack ) ) + if ( FT_QNEW( stack ) ) return NULL; - /* initialize the structure; FT_NEW zeroes it */ stack->memory = memory; stack->error = e; /* allocate the stack buffer */ - if ( FT_NEW_ARRAY( stack->buffer, stackSize ) ) + if ( FT_QNEW_ARRAY( stack->buffer, stackSize ) ) { FT_FREE( stack ); return NULL; diff --git a/thirdparty/freetype/src/psaux/rules.mk b/thirdparty/freetype/src/psaux/rules.mk deleted file mode 100644 index f49aecbc79..0000000000 --- a/thirdparty/freetype/src/psaux/rules.mk +++ /dev/null @@ -1,89 +0,0 @@ -# -# FreeType 2 PSaux driver configuration rules -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# PSAUX driver directory -# -PSAUX_DIR := $(SRC_DIR)/psaux - - -# compilation flags for the driver -# -PSAUX_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(PSAUX_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# PSAUX driver sources (i.e., C files) -# -PSAUX_DRV_SRC := $(PSAUX_DIR)/psobjs.c \ - $(PSAUX_DIR)/t1decode.c \ - $(PSAUX_DIR)/t1cmap.c \ - $(PSAUX_DIR)/afmparse.c \ - $(PSAUX_DIR)/psconv.c \ - $(PSAUX_DIR)/psauxmod.c \ - $(PSAUX_DIR)/psarrst.c \ - $(PSAUX_DIR)/psblues.c \ - $(PSAUX_DIR)/pserror.c \ - $(PSAUX_DIR)/psfont.c \ - $(PSAUX_DIR)/psft.c \ - $(PSAUX_DIR)/pshints.c \ - $(PSAUX_DIR)/psintrp.c \ - $(PSAUX_DIR)/psread.c \ - $(PSAUX_DIR)/psstack.c \ - $(PSAUX_DIR)/cffdecode.c - -# PSAUX driver headers -# -PSAUX_DRV_H := $(PSAUX_DRV_SRC:%c=%h) \ - $(PSAUX_DIR)/psauxerr.h \ - $(PSAUX_DIR)/psfixed.h \ - $(PSAUX_DIR)/psglue.h \ - $(PSAUX_DIR)/pstypes.h - - -# PSAUX driver object(s) -# -# PSAUX_DRV_OBJ_M is used during `multi' builds. -# PSAUX_DRV_OBJ_S is used during `single' builds. -# -PSAUX_DRV_OBJ_M := $(PSAUX_DRV_SRC:$(PSAUX_DIR)/%.c=$(OBJ_DIR)/%.$O) -PSAUX_DRV_OBJ_S := $(OBJ_DIR)/psaux.$O - -# PSAUX driver source file for single build -# -PSAUX_DRV_SRC_S := $(PSAUX_DIR)/psaux.c - - -# PSAUX driver - single object -# -$(PSAUX_DRV_OBJ_S): $(PSAUX_DRV_SRC_S) $(PSAUX_DRV_SRC) \ - $(FREETYPE_H) $(PSAUX_DRV_H) - $(PSAUX_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PSAUX_DRV_SRC_S)) - - -# PSAUX driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(PSAUX_DIR)/%.c $(FREETYPE_H) $(PSAUX_DRV_H) - $(PSAUX_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(PSAUX_DRV_OBJ_S) -DRV_OBJS_M += $(PSAUX_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/psaux/t1cmap.c b/thirdparty/freetype/src/psaux/t1cmap.c index e21e93ca26..3e7c577a18 100644 --- a/thirdparty/freetype/src/psaux/t1cmap.c +++ b/thirdparty/freetype/src/psaux/t1cmap.c @@ -4,7 +4,7 @@ * * Type 1 character map support (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/psaux/t1cmap.h b/thirdparty/freetype/src/psaux/t1cmap.h index 031796510f..8f69600ca4 100644 --- a/thirdparty/freetype/src/psaux/t1cmap.h +++ b/thirdparty/freetype/src/psaux/t1cmap.h @@ -4,7 +4,7 @@ * * Type 1 character map support (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/psaux/t1decode.c b/thirdparty/freetype/src/psaux/t1decode.c index 2ed27ca19e..7e65bde632 100644 --- a/thirdparty/freetype/src/psaux/t1decode.c +++ b/thirdparty/freetype/src/psaux/t1decode.c @@ -4,7 +4,7 @@ * * PostScript Type 1 decoding routines (body). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -27,8 +27,11 @@ #include "psauxerr.h" + /* ensure proper sign extension */ -#define Fix2Int( f ) ( (FT_Int)(FT_Short)( (f) >> 16 ) ) +#define Fix2Int( f ) ( (FT_Int) (FT_Short)( (f) >> 16 ) ) +#define Fix2UInt( f ) ( (FT_UInt)(FT_Short)( (f) >> 16 ) ) + /************************************************************************** * @@ -517,7 +520,7 @@ #ifdef FT_DEBUG_LEVEL_TRACE if ( bol ) { - FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); + FT_TRACE5(( " (%ld)", decoder->top - decoder->stack )); bol = FALSE; } #endif @@ -1025,16 +1028,16 @@ /* <val> <idx> 2 24 callothersubr */ /* ==> set BuildCharArray[cvi( <idx> )] = <val> */ { - FT_Int idx; + FT_UInt idx; PS_Blend blend = decoder->blend; if ( arg_cnt != 2 || !blend ) goto Unexpected_OtherSubr; - idx = Fix2Int( top[1] ); + idx = Fix2UInt( top[1] ); - if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) + if ( idx >= decoder->len_buildchar ) goto Unexpected_OtherSubr; decoder->buildchar[idx] = top[0]; @@ -1046,16 +1049,16 @@ /* ==> push BuildCharArray[cvi( idx )] */ /* onto T1 stack */ { - FT_Int idx; + FT_UInt idx; PS_Blend blend = decoder->blend; if ( arg_cnt != 1 || !blend ) goto Unexpected_OtherSubr; - idx = Fix2Int( top[0] ); + idx = Fix2UInt( top[0] ); - if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) + if ( idx >= decoder->len_buildchar ) goto Unexpected_OtherSubr; top[0] = decoder->buildchar[idx]; @@ -1162,9 +1165,9 @@ if ( top - decoder->stack != num_args ) FT_TRACE0(( "t1_decoder_parse_charstrings:" " too much operands on the stack" - " (seen %d, expected %d)\n", + " (seen %ld, expected %d)\n", top - decoder->stack, num_args )); - break; + break; } #endif /* FT_DEBUG_LEVEL_TRACE */ @@ -1209,7 +1212,7 @@ FT_TRACE4(( "BuildCharArray = [ " )); for ( i = 0; i < decoder->len_buildchar; i++ ) - FT_TRACE4(( "%d ", decoder->buildchar[i] )); + FT_TRACE4(( "%ld ", decoder->buildchar[i] )); FT_TRACE4(( "]\n" )); } @@ -1650,7 +1653,8 @@ } /* while ip < limit */ - FT_TRACE4(( "..end..\n\n" )); + FT_TRACE4(( "..end..\n" )); + FT_TRACE4(( "\n" )); Fail: return error; @@ -2070,7 +2074,8 @@ } /* while ip < limit */ - FT_TRACE4(( "..end..\n\n" )); + FT_TRACE4(( "..end..\n" )); + FT_TRACE4(( "\n" )); No_Width: FT_ERROR(( "t1_decoder_parse_metrics:" diff --git a/thirdparty/freetype/src/psaux/t1decode.h b/thirdparty/freetype/src/psaux/t1decode.h index b793504ac6..eea9d34b04 100644 --- a/thirdparty/freetype/src/psaux/t1decode.h +++ b/thirdparty/freetype/src/psaux/t1decode.h @@ -4,7 +4,7 @@ * * PostScript Type 1 decoding routines (specification). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pshinter/module.mk b/thirdparty/freetype/src/pshinter/module.mk deleted file mode 100644 index b440d2e76a..0000000000 --- a/thirdparty/freetype/src/pshinter/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 PSHinter module definition -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += PSHINTER_MODULE - -define PSHINTER_MODULE -$(OPEN_DRIVER) FT_Module_Class, pshinter_module_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)pshinter $(ECHO_DRIVER_DESC)Postscript hinter module$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/pshinter/pshalgo.c b/thirdparty/freetype/src/pshinter/pshalgo.c index 920b9a74b5..227caeae33 100644 --- a/thirdparty/freetype/src/pshinter/pshalgo.c +++ b/thirdparty/freetype/src/pshinter/pshalgo.c @@ -4,7 +4,7 @@ * * PostScript hinting algorithm (body). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used @@ -305,17 +305,18 @@ /* now, sort the hints; they are guaranteed to not overlap */ /* so we can compare their "org_pos" field directly */ { - FT_Int i1, i2; + FT_UInt i1, i2; PSH_Hint hint1, hint2; PSH_Hint* sort = table->sort; /* a simple bubble sort will do, since in 99% of cases, the hints */ /* will be already sorted -- and the sort will be linear */ - for ( i1 = 1; i1 < (FT_Int)count; i1++ ) + for ( i1 = 1; i1 < count; i1++ ) { hint1 = sort[i1]; - for ( i2 = i1 - 1; i2 >= 0; i2-- ) + /* this loop stops when i2 wraps around after reaching 0 */ + for ( i2 = i1 - 1; i2 < i1; i2-- ) { hint2 = sort[i2]; @@ -869,7 +870,7 @@ return; } -#endif /* DEBUG_HINTER*/ +#endif /* DEBUG_HINTER */ hint = table->hints; count = table->max_hints; @@ -1049,12 +1050,12 @@ } - static int + static PSH_Dir psh_compute_dir( FT_Pos dx, FT_Pos dy ) { - FT_Pos ax, ay; - int result = PSH_DIR_NONE; + FT_Pos ax, ay; + PSH_Dir result = PSH_DIR_NONE; ax = FT_ABS( dx ); @@ -1233,12 +1234,12 @@ dxi = vec[n].x - vec[n_prev].x; dyi = vec[n].y - vec[n_prev].y; - point->dir_in = (FT_Char)psh_compute_dir( dxi, dyi ); + point->dir_in = psh_compute_dir( dxi, dyi ); dxo = vec[n_next].x - vec[n].x; dyo = vec[n_next].y - vec[n].y; - point->dir_out = (FT_Char)psh_compute_dir( dxo, dyo ); + point->dir_out = psh_compute_dir( dxo, dyo ); /* detect smooth points */ if ( point->flags & PSH_POINT_OFF ) @@ -1403,16 +1404,13 @@ } - /* major_dir is the direction for points on the bottom/left of the stem; */ - /* Points on the top/right of the stem will have a direction of */ - /* -major_dir. */ - + /* the min and max are based on contour orientation and fill rule */ static void psh_hint_table_find_strong_points( PSH_Hint_Table table, PSH_Point point, FT_UInt count, FT_Int threshold, - FT_Int major_dir ) + PSH_Dir major_dir ) { PSH_Hint* sort = table->sort; FT_UInt num_hints = table->num_hints; @@ -1420,59 +1418,53 @@ for ( ; count > 0; count--, point++ ) { - FT_Int point_dir = 0; - FT_Pos org_u = point->org_u; + PSH_Dir point_dir; + FT_Pos org_u = point->org_u; if ( psh_point_is_strong( point ) ) continue; - if ( PSH_DIR_COMPARE( point->dir_in, major_dir ) ) - point_dir = point->dir_in; - - else if ( PSH_DIR_COMPARE( point->dir_out, major_dir ) ) - point_dir = point->dir_out; + point_dir = + (PSH_Dir)( ( point->dir_in | point->dir_out ) & major_dir ); - if ( point_dir ) + if ( point_dir & ( PSH_DIR_DOWN | PSH_DIR_RIGHT ) ) { - if ( point_dir == major_dir ) - { - FT_UInt nn; + FT_UInt nn; - for ( nn = 0; nn < num_hints; nn++ ) - { - PSH_Hint hint = sort[nn]; - FT_Pos d = org_u - hint->org_pos; + for ( nn = 0; nn < num_hints; nn++ ) + { + PSH_Hint hint = sort[nn]; + FT_Pos d = org_u - hint->org_pos; - if ( d < threshold && -d < threshold ) - { - psh_point_set_strong( point ); - point->flags2 |= PSH_POINT_EDGE_MIN; - point->hint = hint; - break; - } + if ( d < threshold && -d < threshold ) + { + psh_point_set_strong( point ); + point->flags2 |= PSH_POINT_EDGE_MIN; + point->hint = hint; + break; } } - else if ( point_dir == -major_dir ) - { - FT_UInt nn; + } + else if ( point_dir & ( PSH_DIR_UP | PSH_DIR_LEFT ) ) + { + FT_UInt nn; - for ( nn = 0; nn < num_hints; nn++ ) - { - PSH_Hint hint = sort[nn]; - FT_Pos d = org_u - hint->org_pos - hint->org_len; + for ( nn = 0; nn < num_hints; nn++ ) + { + PSH_Hint hint = sort[nn]; + FT_Pos d = org_u - hint->org_pos - hint->org_len; - if ( d < threshold && -d < threshold ) - { - psh_point_set_strong( point ); - point->flags2 |= PSH_POINT_EDGE_MAX; - point->hint = hint; - break; - } + if ( d < threshold && -d < threshold ) + { + psh_point_set_strong( point ); + point->flags2 |= PSH_POINT_EDGE_MAX; + point->hint = hint; + break; } } } @@ -1571,7 +1563,7 @@ PS_Mask mask = table->hint_masks->masks; FT_UInt num_masks = table->hint_masks->num_masks; FT_UInt first = 0; - FT_Int major_dir = ( dimension == 0 ) ? PSH_DIR_VERTICAL + PSH_Dir major_dir = ( dimension == 0 ) ? PSH_DIR_VERTICAL : PSH_DIR_HORIZONTAL; PSH_Dimension dim = &glyph->globals->dimension[dimension]; FT_Fixed scale = dim->scale_mult; @@ -1656,8 +1648,8 @@ /* check tangents */ - if ( !PSH_DIR_COMPARE( point->dir_in, PSH_DIR_HORIZONTAL ) && - !PSH_DIR_COMPARE( point->dir_out, PSH_DIR_HORIZONTAL ) ) + if ( !( point->dir_in & PSH_DIR_HORIZONTAL ) && + !( point->dir_out & PSH_DIR_HORIZONTAL ) ) continue; /* skip strong points */ diff --git a/thirdparty/freetype/src/pshinter/pshalgo.h b/thirdparty/freetype/src/pshinter/pshalgo.h index 5367a5d164..999c60192b 100644 --- a/thirdparty/freetype/src/pshinter/pshalgo.h +++ b/thirdparty/freetype/src/pshinter/pshalgo.h @@ -4,7 +4,7 @@ * * PostScript hinting algorithm (specification). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -93,21 +93,17 @@ FT_BEGIN_HEADER typedef struct PSH_PointRec_* PSH_Point; typedef struct PSH_ContourRec_* PSH_Contour; - enum + typedef enum PSH_Dir_ { - PSH_DIR_NONE = 4, - PSH_DIR_UP = -1, - PSH_DIR_DOWN = 1, - PSH_DIR_LEFT = -2, - PSH_DIR_RIGHT = 2 - }; + PSH_DIR_NONE = 0, + PSH_DIR_UP = 1, + PSH_DIR_DOWN = 2, + PSH_DIR_VERTICAL = 1 | 2, + PSH_DIR_LEFT = 4, + PSH_DIR_RIGHT = 8, + PSH_DIR_HORIZONTAL = 4 | 8 -#define PSH_DIR_HORIZONTAL 2 -#define PSH_DIR_VERTICAL 1 - -#define PSH_DIR_COMPARE( d1, d2 ) ( (d1) == (d2) || (d1) == -(d2) ) -#define PSH_DIR_IS_HORIZONTAL( d ) PSH_DIR_COMPARE( d, PSH_DIR_HORIZONTAL ) -#define PSH_DIR_IS_VERTICAL( d ) PSH_DIR_COMPARE( d, PSH_DIR_VERTICAL ) + } PSH_Dir; /* the following bit-flags are computed once by the glyph */ @@ -160,8 +156,8 @@ FT_BEGIN_HEADER PSH_Contour contour; FT_UInt flags; FT_UInt flags2; - FT_Char dir_in; - FT_Char dir_out; + PSH_Dir dir_in; + PSH_Dir dir_out; PSH_Hint hint; FT_Pos org_u; FT_Pos org_v; @@ -199,10 +195,6 @@ FT_BEGIN_HEADER PSH_Globals globals; PSH_Hint_TableRec hint_tables[2]; - FT_Bool vertical; - FT_Int major_dir; - FT_Int minor_dir; - FT_Bool do_horz_hints; FT_Bool do_vert_hints; FT_Bool do_horz_snapping; diff --git a/thirdparty/freetype/src/pshinter/pshglob.c b/thirdparty/freetype/src/pshinter/pshglob.c index cdc1c3af0e..2ca0f665c6 100644 --- a/thirdparty/freetype/src/pshinter/pshglob.c +++ b/thirdparty/freetype/src/pshinter/pshglob.c @@ -5,7 +5,7 @@ * PostScript hinter global hinting management (body). * Inspired by the new auto-hinter module. * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used diff --git a/thirdparty/freetype/src/pshinter/pshglob.h b/thirdparty/freetype/src/pshinter/pshglob.h index 8181324e5e..a8f9953fa0 100644 --- a/thirdparty/freetype/src/pshinter/pshglob.h +++ b/thirdparty/freetype/src/pshinter/pshglob.h @@ -4,7 +4,7 @@ * * PostScript hinter global hinting management. * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pshinter/pshinter.c b/thirdparty/freetype/src/pshinter/pshinter.c index 3cca0ad7c2..705143dcdc 100644 --- a/thirdparty/freetype/src/pshinter/pshinter.c +++ b/thirdparty/freetype/src/pshinter/pshinter.c @@ -4,7 +4,7 @@ * * FreeType PostScript Hinting module * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pshinter/pshmod.c b/thirdparty/freetype/src/pshinter/pshmod.c index e0abd386f9..6674041f7e 100644 --- a/thirdparty/freetype/src/pshinter/pshmod.c +++ b/thirdparty/freetype/src/pshinter/pshmod.c @@ -4,7 +4,7 @@ * * FreeType PostScript hinter module implementation (body). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pshinter/pshmod.h b/thirdparty/freetype/src/pshinter/pshmod.h index 2a6eb1c469..8b229bb077 100644 --- a/thirdparty/freetype/src/pshinter/pshmod.h +++ b/thirdparty/freetype/src/pshinter/pshmod.h @@ -4,7 +4,7 @@ * * PostScript hinter module interface (specification). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pshinter/pshnterr.h b/thirdparty/freetype/src/pshinter/pshnterr.h index d67955c410..567d765132 100644 --- a/thirdparty/freetype/src/pshinter/pshnterr.h +++ b/thirdparty/freetype/src/pshinter/pshnterr.h @@ -4,7 +4,7 @@ * * PS Hinter error codes (specification only). * - * Copyright (C) 2003-2020 by + * Copyright (C) 2003-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pshinter/pshrec.c b/thirdparty/freetype/src/pshinter/pshrec.c index bddccf2a6e..1faabdaafa 100644 --- a/thirdparty/freetype/src/pshinter/pshrec.c +++ b/thirdparty/freetype/src/pshinter/pshrec.c @@ -4,7 +4,7 @@ * * FreeType PostScript hints recorder (body). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -499,23 +499,18 @@ ps_mask_table_merge_all( PS_Mask_Table table, FT_Memory memory ) { - FT_Int index1, index2; + FT_UInt index1, index2; FT_Error error = FT_Err_Ok; - /* both loops go down to 0, thus FT_Int for index1 and index2 */ - for ( index1 = (FT_Int)table->num_masks - 1; index1 > 0; index1-- ) + /* the loops stop when unsigned indices wrap around after 0 */ + for ( index1 = table->num_masks - 1; index1 < table->num_masks; index1-- ) { - for ( index2 = index1 - 1; index2 >= 0; index2-- ) + for ( index2 = index1 - 1; index2 < index1; index2-- ) { - if ( ps_mask_table_test_intersect( table, - (FT_UInt)index1, - (FT_UInt)index2 ) ) + if ( ps_mask_table_test_intersect( table, index1, index2 ) ) { - error = ps_mask_table_merge( table, - (FT_UInt)index2, - (FT_UInt)index1, - memory ); + error = ps_mask_table_merge( table, index2, index1, memory ); if ( error ) goto Exit; diff --git a/thirdparty/freetype/src/pshinter/pshrec.h b/thirdparty/freetype/src/pshinter/pshrec.h index b13c7be13c..e483981d9d 100644 --- a/thirdparty/freetype/src/pshinter/pshrec.h +++ b/thirdparty/freetype/src/pshinter/pshrec.h @@ -4,7 +4,7 @@ * * Postscript (Type1/Type2) hints recorder (specification). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/pshinter/rules.mk b/thirdparty/freetype/src/pshinter/rules.mk deleted file mode 100644 index c845c255cd..0000000000 --- a/thirdparty/freetype/src/pshinter/rules.mk +++ /dev/null @@ -1,75 +0,0 @@ -# -# FreeType 2 PSHinter driver configuration rules -# - - -# Copyright (C) 2001-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# PSHINTER driver directory -# -PSHINTER_DIR := $(SRC_DIR)/pshinter - - -# compilation flags for the driver -# -PSHINTER_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(PSHINTER_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# PSHINTER driver sources (i.e., C files) -# -PSHINTER_DRV_SRC := $(PSHINTER_DIR)/pshalgo.c \ - $(PSHINTER_DIR)/pshglob.c \ - $(PSHINTER_DIR)/pshmod.c \ - $(PSHINTER_DIR)/pshrec.c - - -# PSHINTER driver headers -# -PSHINTER_DRV_H := $(PSHINTER_DRV_SRC:%c=%h) \ - $(PSHINTER_DIR)/pshnterr.h - - -# PSHINTER driver object(s) -# -# PSHINTER_DRV_OBJ_M is used during `multi' builds. -# PSHINTER_DRV_OBJ_S is used during `single' builds. -# -PSHINTER_DRV_OBJ_M := $(PSHINTER_DRV_SRC:$(PSHINTER_DIR)/%.c=$(OBJ_DIR)/%.$O) -PSHINTER_DRV_OBJ_S := $(OBJ_DIR)/pshinter.$O - -# PSHINTER driver source file for single build -# -PSHINTER_DRV_SRC_S := $(PSHINTER_DIR)/pshinter.c - - -# PSHINTER driver - single object -# -$(PSHINTER_DRV_OBJ_S): $(PSHINTER_DRV_SRC_S) $(PSHINTER_DRV_SRC) \ - $(FREETYPE_H) $(PSHINTER_DRV_H) - $(PSHINTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PSHINTER_DRV_SRC_S)) - - -# PSHINTER driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(PSHINTER_DIR)/%.c $(FREETYPE_H) $(PSHINTER_DRV_H) - $(PSHINTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(PSHINTER_DRV_OBJ_S) -DRV_OBJS_M += $(PSHINTER_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/psnames/module.mk b/thirdparty/freetype/src/psnames/module.mk deleted file mode 100644 index 675bb37131..0000000000 --- a/thirdparty/freetype/src/psnames/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 PSnames module definition -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += PSNAMES_MODULE - -define PSNAMES_MODULE -$(OPEN_DRIVER) FT_Module_Class, psnames_module_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)psnames $(ECHO_DRIVER_DESC)Postscript & Unicode Glyph name handling$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/psnames/psmodule.c b/thirdparty/freetype/src/psnames/psmodule.c index b38f9d3b1c..74adefa15b 100644 --- a/thirdparty/freetype/src/psnames/psmodule.c +++ b/thirdparty/freetype/src/psnames/psmodule.c @@ -4,7 +4,7 @@ * * psnames module implementation (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -155,31 +155,30 @@ /* Look for a non-initial dot in the glyph name in order to */ /* find variants like `A.swash', `e.final', etc. */ { - const char* p = glyph_name; - const char* dot = NULL; + FT_UInt32 value = 0; + const char* p = glyph_name; + + for ( ; *p && *p != '.'; p++ ) + ; - for ( ; *p; p++ ) + /* now look up the glyph in the Adobe Glyph List; */ + /* `.notdef', `.null' and the empty name are short cut */ + if ( p > glyph_name ) { - if ( *p == '.' && p > glyph_name ) - { - dot = p; - break; - } + value = (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p ); + + if ( *p == '.' ) + value |= (FT_UInt32)VARIANT_BIT; } - /* now look up the glyph in the Adobe Glyph List */ - if ( !dot ) - return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p ); - else - return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) | - VARIANT_BIT ); + return value; } } /* ft_qsort callback to sort the unicode map */ - FT_CALLBACK_DEF( int ) + FT_COMPARE_DEF( int ) compare_uni_maps( const void* a, const void* b ) { @@ -326,9 +325,8 @@ /* we first allocate the table */ table->num_maps = 0; - table->maps = NULL; - if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) ) + if ( !FT_QNEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) ) { FT_UInt n; FT_UInt count; @@ -343,7 +341,7 @@ const char* gname = get_glyph_name( glyph_data, n ); - if ( gname ) + if ( gname && *gname ) { ps_check_extra_glyph_name( gname, n, extra_glyphs, extra_glyph_list_states ); @@ -391,9 +389,9 @@ /* Reallocate if the number of used entries is much smaller. */ if ( count < num_glyphs / 2 ) { - (void)FT_RENEW_ARRAY( table->maps, - num_glyphs + EXTRA_GLYPH_LIST_SIZE, - count ); + FT_MEM_QRENEW_ARRAY( table->maps, + num_glyphs + EXTRA_GLYPH_LIST_SIZE, + count ); error = FT_Err_Ok; } diff --git a/thirdparty/freetype/src/psnames/psmodule.h b/thirdparty/freetype/src/psnames/psmodule.h index c85a9ecad7..e92a975e9d 100644 --- a/thirdparty/freetype/src/psnames/psmodule.h +++ b/thirdparty/freetype/src/psnames/psmodule.h @@ -4,7 +4,7 @@ * * High-level psnames module interface (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/psnames/psnamerr.h b/thirdparty/freetype/src/psnames/psnamerr.h index 154c701d04..888b76c4f6 100644 --- a/thirdparty/freetype/src/psnames/psnamerr.h +++ b/thirdparty/freetype/src/psnames/psnamerr.h @@ -4,7 +4,7 @@ * * PS names module error codes (specification only). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/psnames/psnames.c b/thirdparty/freetype/src/psnames/psnames.c index cff36851ba..e7be6707d6 100644 --- a/thirdparty/freetype/src/psnames/psnames.c +++ b/thirdparty/freetype/src/psnames/psnames.c @@ -4,7 +4,7 @@ * * FreeType psnames module component (body only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/psnames/pstables.h b/thirdparty/freetype/src/psnames/pstables.h index c215f16ffc..0bcadca9cc 100644 --- a/thirdparty/freetype/src/psnames/pstables.h +++ b/thirdparty/freetype/src/psnames/pstables.h @@ -4,7 +4,7 @@ * * PostScript glyph names. * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/psnames/rules.mk b/thirdparty/freetype/src/psnames/rules.mk deleted file mode 100644 index 14cdda3ad1..0000000000 --- a/thirdparty/freetype/src/psnames/rules.mk +++ /dev/null @@ -1,73 +0,0 @@ -# -# FreeType 2 psnames driver configuration rules -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# psnames driver directory -# -PSNAMES_DIR := $(SRC_DIR)/psnames - - -# compilation flags for the driver -# -PSNAMES_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(PSNAMES_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# psnames driver sources (i.e., C files) -# -PSNAMES_DRV_SRC := $(PSNAMES_DIR)/psmodule.c - - -# psnames driver headers -# -PSNAMES_DRV_H := $(PSNAMES_DRV_SRC:%.c=%.h) \ - $(PSNAMES_DIR)/psnamerr.h \ - $(PSNAMES_DIR)/pstables.h - - -# psnames driver object(s) -# -# PSNAMES_DRV_OBJ_M is used during `multi' builds -# PSNAMES_DRV_OBJ_S is used during `single' builds -# -PSNAMES_DRV_OBJ_M := $(PSNAMES_DRV_SRC:$(PSNAMES_DIR)/%.c=$(OBJ_DIR)/%.$O) -PSNAMES_DRV_OBJ_S := $(OBJ_DIR)/psnames.$O - -# psnames driver source file for single build -# -PSNAMES_DRV_SRC_S := $(PSNAMES_DIR)/psnames.c - - -# psnames driver - single object -# -$(PSNAMES_DRV_OBJ_S): $(PSNAMES_DRV_SRC_S) $(PSNAMES_DRV_SRC) \ - $(FREETYPE_H) $(PSNAMES_DRV_H) - $(PSNAMES_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PSNAMES_DRV_SRC_S)) - - -# psnames driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(PSNAMES_DIR)/%.c $(FREETYPE_H) $(PSNAMES_DRV_H) - $(PSNAMES_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(PSNAMES_DRV_OBJ_S) -DRV_OBJS_M += $(PSNAMES_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/raster/ftmisc.h b/thirdparty/freetype/src/raster/ftmisc.h index 6efe4a9a5a..b12a051234 100644 --- a/thirdparty/freetype/src/raster/ftmisc.h +++ b/thirdparty/freetype/src/raster/ftmisc.h @@ -5,7 +5,7 @@ * Miscellaneous macros for stand-alone rasterizer (specification * only). * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used @@ -47,11 +47,8 @@ typedef signed long FT_F26Dot6; typedef int FT_Error; -#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ - ( ( (FT_ULong)_x1 << 24 ) | \ - ( (FT_ULong)_x2 << 16 ) | \ - ( (FT_ULong)_x3 << 8 ) | \ - (FT_ULong)_x4 ) + +#define FT_STATIC_BYTE_CAST( type, var ) (type)(FT_Byte)(var) /* from include/freetype/ftsystem.h */ diff --git a/thirdparty/freetype/src/raster/ftraster.c b/thirdparty/freetype/src/raster/ftraster.c index 9f0a7976fa..bfc059c1e8 100644 --- a/thirdparty/freetype/src/raster/ftraster.c +++ b/thirdparty/freetype/src/raster/ftraster.c @@ -4,7 +4,7 @@ * * The FreeType glyph rasterizer (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -149,9 +149,6 @@ /*************************************************************************/ /*************************************************************************/ - /* define DEBUG_RASTER if you want to compile a debugging version */ -/* #define DEBUG_RASTER */ - /*************************************************************************/ /*************************************************************************/ @@ -200,12 +197,13 @@ #define FT_THROW( e ) FT_ERR_CAT( Raster_Err_, e ) #endif -#define Raster_Err_None 0 -#define Raster_Err_Not_Ini -1 -#define Raster_Err_Overflow -2 -#define Raster_Err_Neg_Height -3 -#define Raster_Err_Invalid -4 -#define Raster_Err_Unsupported -5 +#define Raster_Err_Ok 0 +#define Raster_Err_Invalid_Outline -1 +#define Raster_Err_Cannot_Render_Glyph -2 +#define Raster_Err_Invalid_Argument -3 +#define Raster_Err_Raster_Overflow -4 +#define Raster_Err_Raster_Uninitialized -5 +#define Raster_Err_Raster_Negative_Height -6 #define ft_memset memset @@ -230,13 +228,6 @@ #include "rasterrs.h" -#define Raster_Err_None FT_Err_Ok -#define Raster_Err_Not_Ini Raster_Err_Raster_Uninitialized -#define Raster_Err_Overflow Raster_Err_Raster_Overflow -#define Raster_Err_Neg_Height Raster_Err_Raster_Negative_Height -#define Raster_Err_Invalid Raster_Err_Invalid_Outline -#define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph - #endif /* !STANDALONE_ */ @@ -375,16 +366,6 @@ typedef PProfile* PProfileList; - /* Simple record used to implement a stack of bands, required */ - /* by the sub-banding mechanism */ - typedef struct black_TBand_ - { - Short y_min; /* band's minimum */ - Short y_max; /* band's maximum */ - - } black_TBand; - - #define AlignProfileSize \ ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( Long ) ) @@ -426,8 +407,8 @@ /* prototypes used for sweep function dispatch */ typedef void - Function_Sweep_Init( RAS_ARGS Short* min, - Short* max ); + Function_Sweep_Init( RAS_ARGS Short min, + Short max ); typedef void Function_Sweep_Span( RAS_ARGS Short y, @@ -492,10 +473,11 @@ Int numTurns; /* number of Y-turns in outline */ - TPoint* arc; /* current Bezier arc pointer */ + Byte dropOutControl; /* current drop_out control method */ UShort bWidth; /* target bitmap width */ PByte bOrigin; /* target bitmap bottom-left origin */ + PByte bLine; /* target bitmap current line */ Long lastX, lastY; Long minY, maxY; @@ -517,9 +499,6 @@ FT_Bitmap target; /* description of target bit/pixmap */ FT_Outline outline; - Long traceOfs; /* current offset in target bitmap */ - Short traceIncr; /* sweep's increment in target bitmap */ - /* dispatch variables */ Function_Sweep_Init* Proc_Sweep_Init; @@ -527,18 +506,6 @@ Function_Sweep_Span* Proc_Sweep_Drop; Function_Sweep_Step* Proc_Sweep_Step; - Byte dropOutControl; /* current drop_out control method */ - - Bool second_pass; /* indicates whether a horizontal pass */ - /* should be performed to control */ - /* drop-out accurately when calling */ - /* Render_Glyph. */ - - TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ - - black_TBand band_stack[16]; /* band stack used for sub-banding */ - Int band_top; /* band stack top */ - }; @@ -660,7 +627,7 @@ if ( ras.top >= ras.maxBuff ) { - ras.error = FT_THROW( Overflow ); + ras.error = FT_THROW( Raster_Overflow ); return FAILURE; } @@ -689,7 +656,7 @@ default: FT_ERROR(( "New_Profile: invalid profile direction\n" )); - ras.error = FT_THROW( Invalid ); + ras.error = FT_THROW( Invalid_Outline ); return FAILURE; } @@ -731,7 +698,7 @@ if ( h < 0 ) { FT_ERROR(( "End_Profile: negative height encountered\n" )); - ras.error = FT_THROW( Neg_Height ); + ras.error = FT_THROW( Raster_Negative_Height ); return FAILURE; } @@ -767,7 +734,7 @@ if ( ras.top >= ras.maxBuff ) { FT_TRACE1(( "overflow in End_Profile\n" )); - ras.error = FT_THROW( Overflow ); + ras.error = FT_THROW( Raster_Overflow ); return FAILURE; } @@ -822,7 +789,7 @@ ras.maxBuff--; if ( ras.maxBuff <= ras.top ) { - ras.error = FT_THROW( Overflow ); + ras.error = FT_THROW( Raster_Overflow ); return FAILURE; } ras.numTurns++; @@ -1086,7 +1053,7 @@ size = e2 - e1 + 1; if ( ras.top + size >= ras.maxBuff ) { - ras.error = FT_THROW( Overflow ); + ras.error = FT_THROW( Raster_Overflow ); return FAILURE; } @@ -1209,6 +1176,7 @@ */ static Bool Bezier_Up( RAS_ARGS Int degree, + TPoint* arc, TSplitter splitter, Long miny, Long maxy ) @@ -1216,13 +1184,11 @@ Long y1, y2, e, e2, e0; Short f1; - TPoint* arc; TPoint* start_arc; PLong top; - arc = ras.arc; y1 = arc[degree].y; y2 = arc[0].y; top = ras.top; @@ -1271,7 +1237,7 @@ if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff ) { ras.top = top; - ras.error = FT_THROW( Overflow ); + ras.error = FT_THROW( Raster_Overflow ); return FAILURE; } @@ -1314,7 +1280,6 @@ Fin: ras.top = top; - ras.arc -= degree; return SUCCESS; } @@ -1346,11 +1311,11 @@ */ static Bool Bezier_Down( RAS_ARGS Int degree, + TPoint* arc, TSplitter splitter, Long miny, Long maxy ) { - TPoint* arc = ras.arc; Bool result, fresh; @@ -1362,7 +1327,7 @@ fresh = ras.fresh; - result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny ); + result = Bezier_Up( RAS_VARS degree, arc, splitter, -maxy, -miny ); if ( fresh && !ras.fresh ) ras.cProfile->start = -ras.cProfile->start; @@ -1503,22 +1468,24 @@ { Long y1, y2, y3, x3, ymin, ymax; TStates state_bez; + TPoint arcs[2 * MaxBezier + 1]; /* The Bezier stack */ + TPoint* arc; /* current Bezier arc pointer */ - ras.arc = ras.arcs; - ras.arc[2].x = ras.lastX; - ras.arc[2].y = ras.lastY; - ras.arc[1].x = cx; - ras.arc[1].y = cy; - ras.arc[0].x = x; - ras.arc[0].y = y; + arc = arcs; + arc[2].x = ras.lastX; + arc[2].y = ras.lastY; + arc[1].x = cx; + arc[1].y = cy; + arc[0].x = x; + arc[0].y = y; do { - y1 = ras.arc[2].y; - y2 = ras.arc[1].y; - y3 = ras.arc[0].y; - x3 = ras.arc[0].x; + y1 = arc[2].y; + y2 = arc[1].y; + y3 = arc[0].y; + x3 = arc[0].x; /* first, categorize the Bezier arc */ @@ -1536,13 +1503,13 @@ if ( y2 < ymin || y2 > ymax ) { /* this arc has no given direction, split it! */ - Split_Conic( ras.arc ); - ras.arc += 2; + Split_Conic( arc ); + arc += 2; } else if ( y1 == y3 ) { /* this arc is flat, ignore it and pop it from the Bezier stack */ - ras.arc -= 2; + arc -= 2; } else { @@ -1569,15 +1536,18 @@ /* now call the appropriate routine */ if ( state_bez == Ascending_State ) { - if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) + if ( Bezier_Up( RAS_VARS 2, arc, Split_Conic, + ras.minY, ras.maxY ) ) goto Fail; } else - if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) + if ( Bezier_Down( RAS_VARS 2, arc, Split_Conic, + ras.minY, ras.maxY ) ) goto Fail; + arc -= 2; } - } while ( ras.arc >= ras.arcs ); + } while ( arc >= arcs ); ras.lastX = x3; ras.lastY = y3; @@ -1632,25 +1602,27 @@ { Long y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2; TStates state_bez; + TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ + TPoint* arc; /* current Bezier arc pointer */ - ras.arc = ras.arcs; - ras.arc[3].x = ras.lastX; - ras.arc[3].y = ras.lastY; - ras.arc[2].x = cx1; - ras.arc[2].y = cy1; - ras.arc[1].x = cx2; - ras.arc[1].y = cy2; - ras.arc[0].x = x; - ras.arc[0].y = y; + arc = arcs; + arc[3].x = ras.lastX; + arc[3].y = ras.lastY; + arc[2].x = cx1; + arc[2].y = cy1; + arc[1].x = cx2; + arc[1].y = cy2; + arc[0].x = x; + arc[0].y = y; do { - y1 = ras.arc[3].y; - y2 = ras.arc[2].y; - y3 = ras.arc[1].y; - y4 = ras.arc[0].y; - x4 = ras.arc[0].x; + y1 = arc[3].y; + y2 = arc[2].y; + y3 = arc[1].y; + y4 = arc[0].y; + x4 = arc[0].x; /* first, categorize the Bezier arc */ @@ -1679,13 +1651,13 @@ if ( ymin2 < ymin1 || ymax2 > ymax1 ) { /* this arc has no given direction, split it! */ - Split_Cubic( ras.arc ); - ras.arc += 3; + Split_Cubic( arc ); + arc += 3; } else if ( y1 == y4 ) { /* this arc is flat, ignore it and pop it from the Bezier stack */ - ras.arc -= 3; + arc -= 3; } else { @@ -1711,15 +1683,18 @@ /* compute intersections */ if ( state_bez == Ascending_State ) { - if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) + if ( Bezier_Up( RAS_VARS 3, arc, Split_Cubic, + ras.minY, ras.maxY ) ) goto Fail; } else - if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) + if ( Bezier_Down( RAS_VARS 3, arc, Split_Cubic, + ras.minY, ras.maxY ) ) goto Fail; + arc -= 3; } - } while ( ras.arc >= ras.arcs ); + } while ( arc >= arcs ); ras.lastX = x4; ras.lastY = y4; @@ -1967,7 +1942,7 @@ return SUCCESS; Invalid_Outline: - ras.error = FT_THROW( Invalid ); + ras.error = FT_THROW( Invalid_Outline ); Fail: return FAILURE; @@ -2120,8 +2095,8 @@ * Removes an old profile from a linked list. */ static void - DelOld( PProfileList list, - PProfile profile ) + DelOld( PProfileList list, + const PProfile profile ) { PProfile *old, current; @@ -2214,16 +2189,13 @@ */ static void - Vertical_Sweep_Init( RAS_ARGS Short* min, - Short* max ) + Vertical_Sweep_Init( RAS_ARGS Short min, + Short max ) { - Long pitch = ras.target.pitch; - FT_UNUSED( max ); - ras.traceIncr = (Short)-pitch; - ras.traceOfs = -*min * pitch; + ras.bLine = ras.bOrigin - min * ras.target.pitch; } @@ -2234,8 +2206,7 @@ PProfile left, PProfile right ) { - Long e1, e2; - Byte* target; + Long e1, e2; Int dropOutControl = left->flags & 7; @@ -2268,6 +2239,8 @@ if ( e2 >= 0 && e1 < ras.bWidth ) { + Byte* target; + Int c1, c2; Byte f1, f2; @@ -2285,7 +2258,7 @@ f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); - target = ras.bOrigin + ras.traceOfs + c1; + target = ras.bLine + c1; c2 -= c1; if ( c2 > 0 ) @@ -2437,8 +2410,8 @@ c1 = (Short)( e1 >> 3 ); f1 = (Short)( e1 & 7 ); - if ( e1 >= 0 && e1 < ras.bWidth && - ras.bOrigin[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) + if ( e1 >= 0 && e1 < ras.bWidth && + ras.bLine[c1] & ( 0x80 >> f1 ) ) goto Exit; } else @@ -2454,7 +2427,7 @@ c1 = (Short)( e1 >> 3 ); f1 = (Short)( e1 & 7 ); - ras.bOrigin[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); + ras.bLine[c1] |= (char)( 0x80 >> f1 ); } Exit: @@ -2465,7 +2438,7 @@ static void Vertical_Sweep_Step( RAS_ARG ) { - ras.traceOfs += ras.traceIncr; + ras.bLine -= ras.target.pitch; } @@ -2479,8 +2452,8 @@ */ static void - Horizontal_Sweep_Init( RAS_ARGS Short* min, - Short* max ) + Horizontal_Sweep_Init( RAS_ARGS Short min, + Short max ) { /* nothing, really */ FT_UNUSED_RASTER; @@ -2744,13 +2717,13 @@ /* check the Y-turns */ if ( ras.numTurns == 0 ) { - ras.error = FT_THROW( Invalid ); + ras.error = FT_THROW( Invalid_Outline ); return FAILURE; } /* now initialize the sweep */ - ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y ); + ras.Proc_Sweep_Init( RAS_VARS min_Y, max_Y ); /* then compute the distance of each profile from min_Y */ @@ -2977,11 +2950,11 @@ FT_Outline_Get_CBox( const FT_Outline* outline, FT_BBox *acbox ) { - Long xMin, yMin, xMax, yMax; - - if ( outline && acbox ) { + Long xMin, yMin, xMax, yMax; + + if ( outline->n_points == 0 ) { xMin = 0; @@ -3039,63 +3012,54 @@ * Renderer error code. */ static int - Render_Single_Pass( RAS_ARGS Bool flipped ) + Render_Single_Pass( RAS_ARGS Bool flipped, + Int y_min, + Int y_max ) { - Short i, j, k; + Int y_mid; + Int band_top = 0; + Int band_stack[32]; /* enough to bisect 32-bit int bands */ - while ( ras.band_top >= 0 ) + while ( 1 ) { - ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision; - ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision; + ras.minY = (Long)y_min * ras.precision; + ras.maxY = (Long)y_max * ras.precision; ras.top = ras.buff; - ras.error = Raster_Err_None; + ras.error = Raster_Err_Ok; if ( Convert_Glyph( RAS_VARS flipped ) ) { - if ( ras.error != Raster_Err_Overflow ) - return FAILURE; - - ras.error = Raster_Err_None; + if ( ras.error != Raster_Err_Raster_Overflow ) + return ras.error; /* sub-banding */ -#ifdef DEBUG_RASTER - ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) ); -#endif + if ( y_min == y_max ) + return ras.error; /* still Raster_Overflow */ - i = ras.band_stack[ras.band_top].y_min; - j = ras.band_stack[ras.band_top].y_max; + y_mid = ( y_min + y_max ) >> 1; - k = (Short)( ( i + j ) / 2 ); - - if ( ras.band_top >= 7 || k < i ) - { - ras.band_top = 0; - ras.error = FT_THROW( Invalid ); - - return ras.error; - } - - ras.band_stack[ras.band_top + 1].y_min = k; - ras.band_stack[ras.band_top + 1].y_max = j; - - ras.band_stack[ras.band_top].y_max = (Short)( k - 1 ); - - ras.band_top++; + band_stack[band_top++] = y_min; + y_min = y_mid + 1; } else { if ( ras.fProfile ) if ( Draw_Sweep( RAS_VAR ) ) return ras.error; - ras.band_top--; + + if ( --band_top < 0 ) + break; + + y_max = y_min - 1; + y_min = band_stack[band_top]; } } - return SUCCESS; + return Raster_Err_Ok; } @@ -3132,9 +3096,6 @@ ras.dropOutControl += 1; } - ras.second_pass = (Bool)( !( ras.outline.flags & - FT_OUTLINE_SINGLE_PASS ) ); - /* Vertical Sweep */ FT_TRACE7(( "Vertical pass (ftraster)\n" )); @@ -3143,21 +3104,18 @@ ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; ras.Proc_Sweep_Step = Vertical_Sweep_Step; - ras.band_top = 0; - ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = (Short)( ras.target.rows - 1 ); - ras.bWidth = (UShort)ras.target.width; ras.bOrigin = (Byte*)ras.target.buffer; if ( ras.target.pitch > 0 ) ras.bOrigin += (Long)( ras.target.rows - 1 ) * ras.target.pitch; - if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 ) + error = Render_Single_Pass( RAS_VARS 0, 0, (Int)ras.target.rows - 1 ); + if ( error ) return error; /* Horizontal Sweep */ - if ( ras.second_pass && ras.dropOutControl != 2 ) + if ( !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ) ) { FT_TRACE7(( "Horizontal pass (ftraster)\n" )); @@ -3166,22 +3124,12 @@ ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop; ras.Proc_Sweep_Step = Horizontal_Sweep_Step; - ras.band_top = 0; - ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = (Short)( ras.target.width - 1 ); - - if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 ) + error = Render_Single_Pass( RAS_VARS 1, 0, (Int)ras.target.width - 1 ); + if ( error ) return error; } - return Raster_Err_None; - } - - - static void - ft_black_init( black_PRaster raster ) - { - FT_UNUSED( raster ); + return Raster_Err_Ok; } @@ -3202,7 +3150,6 @@ *araster = (FT_Raster)&the_raster; FT_ZERO( &the_raster ); - ft_black_init( &the_raster ); return 0; } @@ -3227,14 +3174,10 @@ black_PRaster raster = NULL; - *araster = 0; if ( !FT_NEW( raster ) ) - { raster->memory = memory; - ft_black_init( raster ); - *araster = raster; - } + *araster = raster; return error; } @@ -3292,38 +3235,36 @@ if ( !raster ) - return FT_THROW( Not_Ini ); + return FT_THROW( Raster_Uninitialized ); if ( !outline ) - return FT_THROW( Invalid ); + return FT_THROW( Invalid_Outline ); /* return immediately if the outline is empty */ if ( outline->n_points == 0 || outline->n_contours <= 0 ) - return Raster_Err_None; + return Raster_Err_Ok; if ( !outline->contours || !outline->points ) - return FT_THROW( Invalid ); + return FT_THROW( Invalid_Outline ); if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 ) - return FT_THROW( Invalid ); + return FT_THROW( Invalid_Outline ); /* this version of the raster does not support direct rendering, sorry */ - if ( params->flags & FT_RASTER_FLAG_DIRECT ) - return FT_THROW( Unsupported ); - - if ( params->flags & FT_RASTER_FLAG_AA ) - return FT_THROW( Unsupported ); + if ( params->flags & FT_RASTER_FLAG_DIRECT || + params->flags & FT_RASTER_FLAG_AA ) + return FT_THROW( Cannot_Render_Glyph ); if ( !target_map ) - return FT_THROW( Invalid ); + return FT_THROW( Invalid_Argument ); /* nothing to do */ if ( !target_map->width || !target_map->rows ) - return Raster_Err_None; + return Raster_Err_Ok; if ( !target_map->buffer ) - return FT_THROW( Invalid ); + return FT_THROW( Invalid_Argument ); ras.outline = *outline; ras.target = *target_map; diff --git a/thirdparty/freetype/src/raster/ftraster.h b/thirdparty/freetype/src/raster/ftraster.h index 1b2ee3c016..4affd48b51 100644 --- a/thirdparty/freetype/src/raster/ftraster.h +++ b/thirdparty/freetype/src/raster/ftraster.h @@ -4,7 +4,7 @@ * * The FreeType glyph rasterizer (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used diff --git a/thirdparty/freetype/src/raster/ftrend1.c b/thirdparty/freetype/src/raster/ftrend1.c index 57fed9bc14..236a8daf0a 100644 --- a/thirdparty/freetype/src/raster/ftrend1.c +++ b/thirdparty/freetype/src/raster/ftrend1.c @@ -4,7 +4,7 @@ * * The FreeType glyph rasterizer interface (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/raster/ftrend1.h b/thirdparty/freetype/src/raster/ftrend1.h index 3f6be53675..e4cea53741 100644 --- a/thirdparty/freetype/src/raster/ftrend1.h +++ b/thirdparty/freetype/src/raster/ftrend1.h @@ -4,7 +4,7 @@ * * The FreeType glyph rasterizer interface (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/raster/module.mk b/thirdparty/freetype/src/raster/module.mk deleted file mode 100644 index 3600732b16..0000000000 --- a/thirdparty/freetype/src/raster/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 renderer module definition -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += RASTER_MODULE - -define RASTER_MODULE -$(OPEN_DRIVER) FT_Renderer_Class, ft_raster1_renderer_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)raster $(ECHO_DRIVER_DESC)monochrome bitmap renderer$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/raster/raster.c b/thirdparty/freetype/src/raster/raster.c index cd37943bf6..ad81a39414 100644 --- a/thirdparty/freetype/src/raster/raster.c +++ b/thirdparty/freetype/src/raster/raster.c @@ -4,7 +4,7 @@ * * FreeType monochrome rasterer module component (body only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/raster/rasterrs.h b/thirdparty/freetype/src/raster/rasterrs.h index a29651a6c5..852dd5bc31 100644 --- a/thirdparty/freetype/src/raster/rasterrs.h +++ b/thirdparty/freetype/src/raster/rasterrs.h @@ -4,7 +4,7 @@ * * monochrome renderer error codes (specification only). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/raster/rules.mk b/thirdparty/freetype/src/raster/rules.mk deleted file mode 100644 index 3e949d7741..0000000000 --- a/thirdparty/freetype/src/raster/rules.mk +++ /dev/null @@ -1,72 +0,0 @@ -# -# FreeType 2 renderer module build rules -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# raster driver directory -# -RASTER_DIR := $(SRC_DIR)/raster - -# compilation flags for the driver -# -RASTER_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(RASTER_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# raster driver sources (i.e., C files) -# -RASTER_DRV_SRC := $(RASTER_DIR)/ftraster.c \ - $(RASTER_DIR)/ftrend1.c - - -# raster driver headers -# -RASTER_DRV_H := $(RASTER_DRV_SRC:%.c=%.h) \ - $(RASTER_DIR)/rasterrs.h - - -# raster driver object(s) -# -# RASTER_DRV_OBJ_M is used during `multi' builds. -# RASTER_DRV_OBJ_S is used during `single' builds. -# -RASTER_DRV_OBJ_M := $(RASTER_DRV_SRC:$(RASTER_DIR)/%.c=$(OBJ_DIR)/%.$O) -RASTER_DRV_OBJ_S := $(OBJ_DIR)/raster.$O - -# raster driver source file for single build -# -RASTER_DRV_SRC_S := $(RASTER_DIR)/raster.c - - -# raster driver - single object -# -$(RASTER_DRV_OBJ_S): $(RASTER_DRV_SRC_S) $(RASTER_DRV_SRC) \ - $(FREETYPE_H) $(RASTER_DRV_H) - $(RASTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(RASTER_DRV_SRC_S)) - - -# raster driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(RASTER_DIR)/%.c $(FREETYPE_H) $(RASTER_DRV_H) - $(RASTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(RASTER_DRV_OBJ_S) -DRV_OBJS_M += $(RASTER_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/sdf/ftbsdf.c b/thirdparty/freetype/src/sdf/ftbsdf.c new file mode 100644 index 0000000000..8da5c9d9e0 --- /dev/null +++ b/thirdparty/freetype/src/sdf/ftbsdf.c @@ -0,0 +1,1347 @@ +/**************************************************************************** + * + * ftbsdf.c + * + * Signed Distance Field support for bitmap fonts (body only). + * + * Copyright (C) 2020-2021 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Written by Anuj Verma. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#include <freetype/internal/ftobjs.h> +#include <freetype/internal/ftdebug.h> +#include <freetype/internal/ftmemory.h> +#include <freetype/fttrigon.h> + +#include "ftsdf.h" +#include "ftsdferrs.h" +#include "ftsdfcommon.h" + + + /************************************************************************** + * + * A brief technical overview of how the BSDF rasterizer works + * ----------------------------------------------------------- + * + * [Notes]: + * * SDF stands for Signed Distance Field everywhere. + * + * * BSDF stands for Bitmap to Signed Distance Field rasterizer. + * + * * This renderer converts rasterized bitmaps to SDF. There is another + * renderer called 'sdf', which generates SDF directly from outlines; + * see file `ftsdf.c` for more. + * + * * The idea of generating SDF from bitmaps is taken from two research + * papers, where one is dependent on the other: + * + * - Per-Erik Danielsson: Euclidean Distance Mapping + * http://webstaff.itn.liu.se/~stegu/JFA/Danielsson.pdf + * + * From this paper we use the eight-point sequential Euclidean + * distance mapping (8SED). This is the heart of the process used + * in this rasterizer. + * + * - Stefan Gustavson, Robin Strand: Anti-aliased Euclidean distance transform. + * http://weber.itn.liu.se/~stegu/aadist/edtaa_preprint.pdf + * + * The original 8SED algorithm discards the pixels' alpha values, + * which can contain information about the actual outline of the + * glyph. This paper takes advantage of those alpha values and + * approximates outline pretty accurately. + * + * * This rasterizer also works for monochrome bitmaps. However, the + * result is not as accurate since we don't have any way to + * approximate outlines from binary bitmaps. + * + * ======================================================================== + * + * Generating SDF from bitmap is done in several steps. + * + * (1) The only information we have is the bitmap itself. It can + * be monochrome or anti-aliased. If it is anti-aliased, pixel values + * are nothing but coverage values. These coverage values can be used + * to extract information about the outline of the image. For + * example, if the pixel's alpha value is 0.5, then we can safely + * assume that the outline passes through the center of the pixel. + * + * (2) Find edge pixels in the bitmap (see `bsdf_is_edge` for more). For + * all edge pixels we use the Anti-aliased Euclidean distance + * transform algorithm and compute approximate edge distances (see + * `compute_edge_distance` and/or the second paper for more). + * + * (3) Now that we have computed approximate distances for edge pixels we + * use the 8SED algorithm to basically sweep the entire bitmap and + * compute distances for the rest of the pixels. (Since the algorithm + * is pretty convoluted it is only explained briefly in a comment to + * function `edt8`. To see the actual algorithm refer to the first + * paper.) + * + * (4) Finally, compute the sign for each pixel. This is done in function + * `finalize_sdf`. The basic idea is that if a pixel's original + * alpha/coverage value is greater than 0.5 then it is 'inside' (and + * 'outside' otherwise). + * + * Pseudo Code: + * + * ``` + * b = source bitmap; + * t = target bitmap; + * dm = list of distances; // dimension equal to b + * + * foreach grid_point (x, y) in b: + * { + * if (is_edge(x, y)): + * dm = approximate_edge_distance(b, x, y); + * + * // do the 8SED on the distances + * edt8(dm); + * + * // determine the signs + * determine_signs(dm): + * + * // copy SDF data to the target bitmap + * copy(dm to t); + * } + * + */ + + + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ +#undef FT_COMPONENT +#define FT_COMPONENT bsdf + + + /************************************************************************** + * + * useful macros + * + */ + +#define ONE 65536 /* 1 in 16.16 */ + + + /************************************************************************** + * + * structs + * + */ + + + /************************************************************************** + * + * @Struct: + * BSDF_TRaster + * + * @Description: + * This struct is used in place of @FT_Raster and is stored within the + * internal FreeType renderer struct. While rasterizing this is passed + * to the @FT_Raster_RenderFunc function, which then can be used however + * we want. + * + * @Fields: + * memory :: + * Used internally to allocate intermediate memory while raterizing. + * + */ + typedef struct BSDF_TRaster_ + { + FT_Memory memory; + + } BSDF_TRaster, *BSDF_PRaster; + + + /************************************************************************** + * + * @Struct: + * ED + * + * @Description: + * Euclidean distance. It gets used for Euclidean distance transforms; + * it can also be interpreted as an edge distance. + * + * @Fields: + * dist :: + * Vector length of the `near` parameter. Can be squared or absolute + * depending on the `USE_SQUARED_DISTANCES` macro defined in file + * `ftsdfcommon.h`. + * + * near :: + * Vector to the nearest edge. Can also be interpreted as shortest + * distance of a point. + * + * alpha :: + * Alpha value of the original bitmap from which we generate SDF. + * Needed for computing the gradient and determining the proper sign + * of a pixel. + * + */ + typedef struct ED_ + { + FT_16D16 dist; + FT_16D16_Vec near; + FT_Byte alpha; + + } ED; + + + /************************************************************************** + * + * @Struct: + * BSDF_Worker + * + * @Description: + * A convenience struct that is passed to functions while generating + * SDF; most of those functions require the same parameters. + * + * @Fields: + * distance_map :: + * A one-dimensional array that gets interpreted as two-dimensional + * one. It contains the Euclidean distances of all points of the + * bitmap. + * + * width :: + * Width of the above `distance_map`. + * + * rows :: + * Number of rows in the above `distance_map`. + * + * params :: + * Internal parameters and properties required by the rasterizer. See + * file `ftsdf.h` for more. + * + */ + typedef struct BSDF_Worker_ + { + ED* distance_map; + + FT_Int width; + FT_Int rows; + + SDF_Raster_Params params; + + } BSDF_Worker; + + + /************************************************************************** + * + * initializer + * + */ + + static const ED zero_ed = { 0, { 0, 0 }, 0 }; + + + /************************************************************************** + * + * rasterizer functions + * + */ + + /************************************************************************** + * + * @Function: + * bsdf_is_edge + * + * @Description: + * Check whether a pixel is an edge pixel, i.e., whether it is + * surrounded by a completely black pixel (zero alpha), and the current + * pixel is not a completely black pixel. + * + * @Input: + * dm :: + * Array of distances. The parameter must point to the current + * pixel, i.e., the pixel that is to be checked for being an edge. + * + * x :: + * The x position of the current pixel. + * + * y :: + * The y position of the current pixel. + * + * w :: + * Width of the bitmap. + * + * r :: + * Number of rows in the bitmap. + * + * @Return: + * 1~if the current pixel is an edge pixel, 0~otherwise. + * + */ + +#ifdef CHECK_NEIGHBOR +#undef CHECK_NEIGHBOR +#endif + +#define CHECK_NEIGHBOR( x_offset, y_offset ) \ + do \ + { \ + if ( x + x_offset >= 0 && x + x_offset < w && \ + y + y_offset >= 0 && y + y_offset < r ) \ + { \ + num_neighbors++; \ + \ + to_check = dm + y_offset * w + x_offset; \ + if ( to_check->alpha == 0 ) \ + { \ + is_edge = 1; \ + goto Done; \ + } \ + } \ + } while ( 0 ) + + static FT_Bool + bsdf_is_edge( ED* dm, /* distance map */ + FT_Int x, /* x index of point to check */ + FT_Int y, /* y index of point to check */ + FT_Int w, /* width */ + FT_Int r ) /* rows */ + { + FT_Bool is_edge = 0; + ED* to_check = NULL; + FT_Int num_neighbors = 0; + + + if ( dm->alpha == 0 ) + goto Done; + + if ( dm->alpha > 0 && dm->alpha < 255 ) + { + is_edge = 1; + goto Done; + } + + /* up */ + CHECK_NEIGHBOR( 0, -1 ); + + /* down */ + CHECK_NEIGHBOR( 0, 1 ); + + /* left */ + CHECK_NEIGHBOR( -1, 0 ); + + /* right */ + CHECK_NEIGHBOR( 1, 0 ); + + /* up left */ + CHECK_NEIGHBOR( -1, -1 ); + + /* up right */ + CHECK_NEIGHBOR( 1, -1 ); + + /* down left */ + CHECK_NEIGHBOR( -1, 1 ); + + /* down right */ + CHECK_NEIGHBOR( 1, 1 ); + + if ( num_neighbors != 8 ) + is_edge = 1; + + Done: + return is_edge; + } + +#undef CHECK_NEIGHBOR + + + /************************************************************************** + * + * @Function: + * compute_edge_distance + * + * @Description: + * Approximate the outline and compute the distance from `current` + * to the approximated outline. + * + * @Input: + * current :: + * Array of Euclidean distances. `current` must point to the position + * for which the distance is to be caculated. We treat this array as + * a two-dimensional array mapped to a one-dimensional array. + * + * x :: + * The x coordinate of the `current` parameter in the array. + * + * y :: + * The y coordinate of the `current` parameter in the array. + * + * w :: + * The width of the distances array. + * + * r :: + * Number of rows in the distances array. + * + * @Return: + * A vector pointing to the approximate edge distance. + * + * @Note: + * This is a computationally expensive function. Try to reduce the + * number of calls to this function. Moreover, this must only be used + * for edge pixel positions. + * + */ + static FT_16D16_Vec + compute_edge_distance( ED* current, + FT_Int x, + FT_Int y, + FT_Int w, + FT_Int r ) + { + /* + * This function, based on the paper presented by Stefan Gustavson and + * Robin Strand, gets used to approximate edge distances from + * anti-aliased bitmaps. + * + * The algorithm is as follows. + * + * (1) In anti-aliased images, the pixel's alpha value is the coverage + * of the pixel by the outline. For example, if the alpha value is + * 0.5f we can assume that the outline passes through the center of + * the pixel. + * + * (2) For this reason we can use that alpha value to approximate the real + * distance of the pixel to edge pretty accurately. A simple + * approximation is `(0.5f - alpha)`, assuming that the outline is + * parallel to the x or y~axis. However, in this algorithm we use a + * different approximation which is quite accurate even for + * non-axis-aligned edges. + * + * (3) The only remaining piece of information that we cannot + * approximate directly from the alpha is the direction of the edge. + * This is where we use Sobel's operator to compute the gradient of + * the pixel. The gradient give us a pretty good approximation of + * the edge direction. We use a 3x3 kernel filter to compute the + * gradient. + * + * (4) After the above two steps we have both the direction and the + * distance to the edge which is used to generate the Signed + * Distance Field. + * + * References: + * + * - Anti-Aliased Euclidean Distance Transform: + * http://weber.itn.liu.se/~stegu/aadist/edtaa_preprint.pdf + * - Sobel Operator: + * https://en.wikipedia.org/wiki/Sobel_operator + */ + + FT_16D16_Vec g = { 0, 0 }; + FT_16D16 dist, current_alpha; + FT_16D16 a1, temp; + FT_16D16 gx, gy; + FT_16D16 alphas[9]; + + + /* Since our spread cannot be 0, this condition */ + /* can never be true. */ + if ( x <= 0 || x >= w - 1 || + y <= 0 || y >= r - 1 ) + return g; + + /* initialize the alphas */ + alphas[0] = 256 * (FT_16D16)current[-w - 1].alpha; + alphas[1] = 256 * (FT_16D16)current[-w ].alpha; + alphas[2] = 256 * (FT_16D16)current[-w + 1].alpha; + alphas[3] = 256 * (FT_16D16)current[ -1].alpha; + alphas[4] = 256 * (FT_16D16)current[ 0].alpha; + alphas[5] = 256 * (FT_16D16)current[ 1].alpha; + alphas[6] = 256 * (FT_16D16)current[ w - 1].alpha; + alphas[7] = 256 * (FT_16D16)current[ w ].alpha; + alphas[8] = 256 * (FT_16D16)current[ w + 1].alpha; + + current_alpha = alphas[4]; + + /* Compute the gradient using the Sobel operator. */ + /* In this case we use the following 3x3 filters: */ + /* */ + /* For x: | -1 0 -1 | */ + /* | -root(2) 0 root(2) | */ + /* | -1 0 1 | */ + /* */ + /* For y: | -1 -root(2) -1 | */ + /* | 0 0 0 | */ + /* | 1 root(2) 1 | */ + /* */ + /* [Note]: 92681 is root(2) in 16.16 format. */ + g.x = -alphas[0] - + FT_MulFix( alphas[3], 92681 ) - + alphas[6] + + alphas[2] + + FT_MulFix( alphas[5], 92681 ) + + alphas[8]; + + g.y = -alphas[0] - + FT_MulFix( alphas[1], 92681 ) - + alphas[2] + + alphas[6] + + FT_MulFix( alphas[7], 92681 ) + + alphas[8]; + + FT_Vector_NormLen( &g ); + + /* The gradient gives us the direction of the */ + /* edge for the current pixel. Once we have the */ + /* approximate direction of the edge, we can */ + /* approximate the edge distance much better. */ + + if ( g.x == 0 || g.y == 0 ) + dist = ONE / 2 - alphas[4]; + else + { + gx = g.x; + gy = g.y; + + gx = FT_ABS( gx ); + gy = FT_ABS( gy ); + + if ( gx < gy ) + { + temp = gx; + gx = gy; + gy = temp; + } + + a1 = FT_DivFix( gy, gx ) / 2; + + if ( current_alpha < a1 ) + dist = ( gx + gy ) / 2 - + square_root( 2 * FT_MulFix( gx, + FT_MulFix( gy, + current_alpha ) ) ); + + else if ( current_alpha < ( ONE - a1 ) ) + dist = FT_MulFix( ONE / 2 - current_alpha, gx ); + + else + dist = -( gx + gy ) / 2 + + square_root( 2 * FT_MulFix( gx, + FT_MulFix( gy, + ONE - current_alpha ) ) ); + } + + g.x = FT_MulFix( g.x, dist ); + g.y = FT_MulFix( g.y, dist ); + + return g; + } + + + /************************************************************************** + * + * @Function: + * bsdf_approximate_edge + * + * @Description: + * Loops over all the pixels and call `compute_edge_distance` only for + * edge pixels. This maked the process a lot faster since + * `compute_edge_distance` uses functions such as `FT_Vector_NormLen', + * which are quite slow. + * + * @InOut: + * worker :: + * Contains the distance map as well as all the relevant parameters + * required by the function. + * + * @Return: + * FreeType error, 0 means success. + * + * @Note: + * The function directly manipulates `worker->distance_map`. + * + */ + static FT_Error + bsdf_approximate_edge( BSDF_Worker* worker ) + { + FT_Error error = FT_Err_Ok; + FT_Int i, j; + FT_Int index; + ED* ed; + + + if ( !worker || !worker->distance_map ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + ed = worker->distance_map; + + for ( j = 0; j < worker->rows; j++ ) + { + for ( i = 0; i < worker->width; i++ ) + { + index = j * worker->width + i; + + if ( bsdf_is_edge( worker->distance_map + index, + i, j, + worker->width, + worker->rows ) ) + { + /* approximate the edge distance for edge pixels */ + ed[index].near = compute_edge_distance( ed + index, + i, j, + worker->width, + worker->rows ); + ed[index].dist = VECTOR_LENGTH_16D16( ed[index].near ); + } + else + { + /* for non-edge pixels assign far away distances */ + ed[index].dist = 400 * ONE; + ed[index].near.x = 200 * ONE; + ed[index].near.y = 200 * ONE; + } + } + } + + Exit: + return error; + } + + + /************************************************************************** + * + * @Function: + * bsdf_init_distance_map + * + * @Description: + * Initialize the distance map according to the '8-point sequential + * Euclidean distance mapping' (8SED) algorithm. Basically it copies + * the `source` bitmap alpha values to the `distance_map->alpha` + * parameter of `worker`. + * + * @Input: + * source :: + * Source bitmap to copy the data from. + * + * @Output: + * worker :: + * Target distance map to copy the data to. + * + * @Return: + * FreeType error, 0 means success. + * + */ + static FT_Error + bsdf_init_distance_map( const FT_Bitmap* source, + BSDF_Worker* worker ) + { + FT_Error error = FT_Err_Ok; + + FT_Int x_diff, y_diff; + FT_Int t_i, t_j, s_i, s_j; + FT_Byte* s; + ED* t; + + + /* again check the parameters (probably unnecessary) */ + if ( !source || !worker ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* Because of the way we convert a bitmap to SDF, */ + /* i.e., aligning the source to the center of the */ + /* target, the target's width and rows must be */ + /* checked before copying. */ + if ( worker->width < (FT_Int)source->width || + worker->rows < (FT_Int)source->rows ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* check pixel mode */ + if ( source->pixel_mode == FT_PIXEL_MODE_NONE ) + { + FT_ERROR(( "bsdf_copy_source_to_target:" + " Invalid pixel mode of source bitmap" )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( source->pixel_mode == FT_PIXEL_MODE_MONO ) + { + FT_TRACE0(( "bsdf_copy_source_to_target:" + " The `bsdf' renderer can convert monochrome\n" )); + FT_TRACE0(( " " + " bitmaps to SDF but the results are not perfect\n" )); + FT_TRACE0(( " " + " because there is no way to approximate actual\n" )); + FT_TRACE0(( " " + " outlines from monochrome bitmaps. Consider\n" )); + FT_TRACE0(( " " + " using an anti-aliased bitmap instead.\n" )); + } +#endif + + /* Calculate the width and row differences */ + /* between target and source. */ + x_diff = worker->width - (int)source->width; + y_diff = worker->rows - (int)source->rows; + + x_diff /= 2; + y_diff /= 2; + + t = (ED*)worker->distance_map; + s = source->buffer; + + /* For now we only support pixel mode `FT_PIXEL_MODE_MONO` */ + /* and `FT_PIXEL_MODE_GRAY`. More will be added later. */ + /* */ + /* [NOTE]: We can also use @FT_Bitmap_Convert to convert */ + /* bitmap to 8bpp. To avoid extra allocation and */ + /* since the target bitmap can be 16bpp we manually */ + /* convert the source bitmap to the desired bpp. */ + + switch ( source->pixel_mode ) + { + case FT_PIXEL_MODE_MONO: + { + FT_Int t_width = worker->width; + FT_Int t_rows = worker->rows; + FT_Int s_width = (int)source->width; + FT_Int s_rows = (int)source->rows; + + + for ( t_j = 0; t_j < t_rows; t_j++ ) + { + for ( t_i = 0; t_i < t_width; t_i++ ) + { + FT_Int t_index = t_j * t_width + t_i; + FT_Int s_index; + FT_Int div, mod; + FT_Byte pixel, byte; + + + t[t_index] = zero_ed; + + s_i = t_i - x_diff; + s_j = t_j - y_diff; + + /* Assign 0 to padding similar to */ + /* the source bitmap. */ + if ( s_i < 0 || s_i >= s_width || + s_j < 0 || s_j >= s_rows ) + continue; + + if ( worker->params.flip_y ) + s_index = ( s_rows - s_j - 1 ) * source->pitch; + else + s_index = s_j * source->pitch; + + div = s_index + s_i / 8; + mod = 7 - s_i % 8; + + pixel = s[div]; + byte = (FT_Byte)( 1 << mod ); + + t[t_index].alpha = pixel & byte ? 255 : 0; + + pixel = 0; + } + } + } + break; + + case FT_PIXEL_MODE_GRAY: + { + FT_Int t_width = worker->width; + FT_Int t_rows = worker->rows; + FT_Int s_width = (int)source->width; + FT_Int s_rows = (int)source->rows; + + + /* loop over all pixels and assign pixel values from source */ + for ( t_j = 0; t_j < t_rows; t_j++ ) + { + for ( t_i = 0; t_i < t_width; t_i++ ) + { + FT_Int t_index = t_j * t_width + t_i; + FT_Int s_index; + + + t[t_index] = zero_ed; + + s_i = t_i - x_diff; + s_j = t_j - y_diff; + + /* Assign 0 to padding similar to */ + /* the source bitmap. */ + if ( s_i < 0 || s_i >= s_width || + s_j < 0 || s_j >= s_rows ) + continue; + + if ( worker->params.flip_y ) + s_index = ( s_rows - s_j - 1 ) * s_width + s_i; + else + s_index = s_j * s_width + s_i; + + /* simply copy the alpha values */ + t[t_index].alpha = s[s_index]; + } + } + } + break; + + default: + FT_ERROR(( "bsdf_copy_source_to_target:" + " unsopported pixel mode of source bitmap\n" )); + + error = FT_THROW( Unimplemented_Feature ); + break; + } + + Exit: + return error; + } + + + /************************************************************************** + * + * @Function: + * compare_neighbor + * + * @Description: + * Compare neighbor pixel (which is defined by the offset) and update + * `current` distance if the new distance is shorter than the original. + * + * @Input: + * x_offset :: + * X offset of the neighbor to be checked. The offset is relative to + * the `current`. + * + * y_offset :: + * Y offset of the neighbor to be checked. The offset is relative to + * the `current`. + * + * width :: + * Width of the `current` array. + * + * @InOut: + * current :: + * Pointer into array of distances. This parameter must point to the + * position whose neighbor is to be checked. The array is treated as + * a two-dimensional array. + * + */ + static void + compare_neighbor( ED* current, + FT_Int x_offset, + FT_Int y_offset, + FT_Int width ) + { + ED* to_check; + FT_16D16 dist; + FT_16D16_Vec dist_vec; + + + to_check = current + ( y_offset * width ) + x_offset; + + /* + * While checking for the nearest point we first approximate the + * distance of `current` by adding the deviation (which is sqrt(2) at + * most). Only if the new value is less than the current value we + * calculate the actual distances using `FT_Vector_Length`. This last + * step can be omitted by using squared distances. + */ + + /* + * Approximate the distance. We subtract 1 to avoid precision errors, + * which could happen because the two directions can be opposite. + */ + dist = to_check->dist - ONE; + + if ( dist < current->dist ) + { + dist_vec = to_check->near; + + dist_vec.x += x_offset * ONE; + dist_vec.y += y_offset * ONE; + dist = VECTOR_LENGTH_16D16( dist_vec ); + + if ( dist < current->dist ) + { + current->dist = dist; + current->near = dist_vec; + } + } + } + + + /************************************************************************** + * + * @Function: + * first_pass + * + * @Description: + * First pass of the 8SED algorithm. Loop over the bitmap from top to + * bottom and scan each row left to right, updating the distances in + * `worker->distance_map`. + * + * @InOut: + * worker:: + * Contains all the relevant parameters. + * + */ + static void + first_pass( BSDF_Worker* worker ) + { + FT_Int i, j; /* iterators */ + FT_Int w, r; /* width, rows */ + ED* dm; /* distance map */ + + + dm = worker->distance_map; + w = worker->width; + r = worker->rows; + + /* Start scanning from top to bottom and sweep each */ + /* row back and forth comparing the distances of the */ + /* neighborhood. Leave the first row as it has no top */ + /* neighbor; it will be covered in the second scan of */ + /* the image (from bottom to top). */ + for ( j = 1; j < r; j++ ) + { + FT_Int index; + ED* current; + + + /* Forward pass of rows (left -> right). Leave the first */ + /* column, which gets covered in the backward pass. */ + for ( i = 1; i < w - 1; i++ ) + { + index = j * w + i; + current = dm + index; + + /* left-up */ + compare_neighbor( current, -1, -1, w ); + /* up */ + compare_neighbor( current, 0, -1, w ); + /* up-right */ + compare_neighbor( current, 1, -1, w ); + /* left */ + compare_neighbor( current, -1, 0, w ); + } + + /* Backward pass of rows (right -> left). Leave the last */ + /* column, which was already covered in the forward pass. */ + for ( i = w - 2; i >= 0; i-- ) + { + index = j * w + i; + current = dm + index; + + /* right */ + compare_neighbor( current, 1, 0, w ); + } + } + } + + + /************************************************************************** + * + * @Function: + * second_pass + * + * @Description: + * Second pass of the 8SED algorithm. Loop over the bitmap from bottom + * to top and scan each row left to right, updating the distances in + * `worker->distance_map`. + * + * @InOut: + * worker:: + * Contains all the relevant parameters. + * + */ + static void + second_pass( BSDF_Worker* worker ) + { + FT_Int i, j; /* iterators */ + FT_Int w, r; /* width, rows */ + ED* dm; /* distance map */ + + + dm = worker->distance_map; + w = worker->width; + r = worker->rows; + + /* Start scanning from bottom to top and sweep each */ + /* row back and forth comparing the distances of the */ + /* neighborhood. Leave the last row as it has no down */ + /* neighbor; it is already covered in the first scan */ + /* of the image (from top to bottom). */ + for ( j = r - 2; j >= 0; j-- ) + { + FT_Int index; + ED* current; + + + /* Forward pass of rows (left -> right). Leave the first */ + /* column, which gets covered in the backward pass. */ + for ( i = 1; i < w - 1; i++ ) + { + index = j * w + i; + current = dm + index; + + /* left-up */ + compare_neighbor( current, -1, 1, w ); + /* up */ + compare_neighbor( current, 0, 1, w ); + /* up-right */ + compare_neighbor( current, 1, 1, w ); + /* left */ + compare_neighbor( current, -1, 0, w ); + } + + /* Backward pass of rows (right -> left). Leave the last */ + /* column, which was already covered in the forward pass. */ + for ( i = w - 2; i >= 0; i-- ) + { + index = j * w + i; + current = dm + index; + + /* right */ + compare_neighbor( current, 1, 0, w ); + } + } + } + + + /************************************************************************** + * + * @Function: + * edt8 + * + * @Description: + * Compute the distance map of the a bitmap. Execute both first and + * second pass of the 8SED algorithm. + * + * @InOut: + * worker:: + * Contains all the relevant parameters. + * + * @Return: + * FreeType error, 0 means success. + * + */ + static FT_Error + edt8( BSDF_Worker* worker ) + { + FT_Error error = FT_Err_Ok; + + + if ( !worker || !worker->distance_map ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* first scan of the image */ + first_pass( worker ); + + /* second scan of the image */ + second_pass( worker ); + + Exit: + return error; + } + + + /************************************************************************** + * + * @Function: + * finalize_sdf + * + * @Description: + * Copy the SDF data from `worker->distance_map` to the `target` bitmap. + * Also transform the data to output format, (which is 6.10 fixed-point + * format at the moment). + * + * @Input: + * worker :: + * Contains source distance map and other SDF data. + * + * @Output: + * target :: + * Target bitmap to which the SDF data is copied to. + * + * @Return: + * FreeType error, 0 means success. + * + */ + static FT_Error + finalize_sdf( BSDF_Worker* worker, + const FT_Bitmap* target ) + { + FT_Error error = FT_Err_Ok; + + FT_Int w, r; + FT_Int i, j; + + FT_SDFFormat* t_buffer; + FT_16D16 spread; + + + if ( !worker || !target ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + w = (int)target->width; + r = (int)target->rows; + t_buffer = (FT_SDFFormat*)target->buffer; + + if ( w != worker->width || + r != worker->rows ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + +#if USE_SQUARED_DISTANCES + spread = FT_INT_16D16( worker->params.spread * + worker->params.spread ); +#else + spread = FT_INT_16D16( worker->params.spread ); +#endif + + for ( j = 0; j < r; j++ ) + { + for ( i = 0; i < w; i++ ) + { + FT_Int index; + FT_16D16 dist; + FT_SDFFormat final_dist; + FT_Char sign; + + + index = j * w + i; + dist = worker->distance_map[index].dist; + + if ( dist < 0 || dist > spread ) + dist = spread; + +#if USE_SQUARED_DISTANCES + dist = square_root( dist ); +#endif + + /* We assume that if the pixel is inside a contour */ + /* its coverage value must be > 127. */ + sign = worker->distance_map[index].alpha < 127 ? -1 : 1; + + /* flip the sign according to the property */ + if ( worker->params.flip_sign ) + sign = -sign; + + /* concatenate from 16.16 to appropriate format */ + final_dist = map_fixed_to_sdf( dist * sign, spread ); + + t_buffer[index] = final_dist; + } + } + + Exit: + return error; + } + + + /************************************************************************** + * + * interface functions + * + */ + + /* called when adding a new module through @FT_Add_Module */ + static FT_Error + bsdf_raster_new( FT_Memory memory, + BSDF_PRaster* araster ) + { + FT_Error error; + BSDF_PRaster raster = NULL; + + + if ( !FT_NEW( raster ) ) + raster->memory = memory; + + *araster = raster; + + return error; + } + + + /* unused */ + static void + bsdf_raster_reset( FT_Raster raster, + unsigned char* pool_base, + unsigned long pool_size ) + { + FT_UNUSED( raster ); + FT_UNUSED( pool_base ); + FT_UNUSED( pool_size ); + } + + + /* unused */ + static FT_Error + bsdf_raster_set_mode( FT_Raster raster, + unsigned long mode, + void* args ) + { + FT_UNUSED( raster ); + FT_UNUSED( mode ); + FT_UNUSED( args ); + + return FT_Err_Ok; + } + + + /* called while rendering through @FT_Render_Glyph */ + static FT_Error + bsdf_raster_render( FT_Raster raster, + const FT_Raster_Params* params ) + { + FT_Error error = FT_Err_Ok; + FT_Memory memory = NULL; + + const FT_Bitmap* source = NULL; + const FT_Bitmap* target = NULL; + + BSDF_TRaster* bsdf_raster = (BSDF_TRaster*)raster; + BSDF_Worker worker; + + const SDF_Raster_Params* sdf_params = (const SDF_Raster_Params*)params; + + + worker.distance_map = NULL; + + /* check for valid parameters */ + if ( !raster || !params ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* check whether the flag is set */ + if ( sdf_params->root.flags != FT_RASTER_FLAG_SDF ) + { + error = FT_THROW( Raster_Corrupted ); + goto Exit; + } + + source = (const FT_Bitmap*)sdf_params->root.source; + target = (const FT_Bitmap*)sdf_params->root.target; + + /* check source and target bitmap */ + if ( !source || !target ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + memory = bsdf_raster->memory; + if ( !memory ) + { + FT_TRACE0(( "bsdf_raster_render: Raster not set up properly,\n" )); + FT_TRACE0(( " unable to find memory handle.\n" )); + + error = FT_THROW( Invalid_Handle ); + goto Exit; + } + + /* check whether spread is set properly */ + if ( sdf_params->spread > MAX_SPREAD || + sdf_params->spread < MIN_SPREAD ) + { + FT_TRACE0(( "bsdf_raster_render:" + " The `spread' field of `SDF_Raster_Params'\n" )); + FT_TRACE0(( " " + " is invalid; the value of this field must be\n" )); + FT_TRACE0(( " " + " within [%d, %d].\n", + MIN_SPREAD, MAX_SPREAD )); + FT_TRACE0(( " " + " Also, you must pass `SDF_Raster_Params'\n" )); + FT_TRACE0(( " " + " instead of the default `FT_Raster_Params'\n" )); + FT_TRACE0(( " " + " while calling this function and set the fields\n" )); + FT_TRACE0(( " " + " accordingly.\n" )); + + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* set up the worker */ + + /* allocate the distance map */ + if ( FT_QALLOC_MULT( worker.distance_map, target->rows, + target->width * sizeof ( *worker.distance_map ) ) ) + goto Exit; + + worker.width = (int)target->width; + worker.rows = (int)target->rows; + worker.params = *sdf_params; + + FT_CALL( bsdf_init_distance_map( source, &worker ) ); + FT_CALL( bsdf_approximate_edge( &worker ) ); + FT_CALL( edt8( &worker ) ); + FT_CALL( finalize_sdf( &worker, target ) ); + + FT_TRACE0(( "bsdf_raster_render: Total memory used = %ld\n", + worker.width * worker.rows * + (long)sizeof ( *worker.distance_map ) )); + + Exit: + if ( worker.distance_map ) + FT_FREE( worker.distance_map ); + + return error; + } + + + /* called while deleting `FT_Library` only if the module is added */ + static void + bsdf_raster_done( FT_Raster raster ) + { + FT_Memory memory = (FT_Memory)((BSDF_TRaster*)raster)->memory; + + + FT_FREE( raster ); + } + + + FT_DEFINE_RASTER_FUNCS( + ft_bitmap_sdf_raster, + + FT_GLYPH_FORMAT_BITMAP, + + (FT_Raster_New_Func) bsdf_raster_new, /* raster_new */ + (FT_Raster_Reset_Func) bsdf_raster_reset, /* raster_reset */ + (FT_Raster_Set_Mode_Func)bsdf_raster_set_mode, /* raster_set_mode */ + (FT_Raster_Render_Func) bsdf_raster_render, /* raster_render */ + (FT_Raster_Done_Func) bsdf_raster_done /* raster_done */ + ) + + +/* END */ diff --git a/thirdparty/freetype/src/sdf/ftsdf.c b/thirdparty/freetype/src/sdf/ftsdf.c new file mode 100644 index 0000000000..f69cf49b47 --- /dev/null +++ b/thirdparty/freetype/src/sdf/ftsdf.c @@ -0,0 +1,3872 @@ +/**************************************************************************** + * + * ftsdf.c + * + * Signed Distance Field support for outline fonts (body). + * + * Copyright (C) 2020-2021 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Written by Anuj Verma. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#include <freetype/internal/ftobjs.h> +#include <freetype/internal/ftdebug.h> +#include <freetype/ftoutln.h> +#include <freetype/fttrigon.h> +#include <freetype/ftbitmap.h> +#include "ftsdf.h" + +#include "ftsdferrs.h" + + + /************************************************************************** + * + * A brief technical overview of how the SDF rasterizer works + * ---------------------------------------------------------- + * + * [Notes]: + * * SDF stands for Signed Distance Field everywhere. + * + * * This renderer generates SDF directly from outlines. There is + * another renderer called 'bsdf', which converts bitmaps to SDF; see + * file `ftbsdf.c` for more. + * + * * The basic idea of generating the SDF is taken from Viktor Chlumsky's + * research paper. The paper explains both single and multi-channel + * SDF, however, this implementation only generates single-channel SDF. + * + * Chlumsky, Viktor: Shape Decomposition for Multi-channel Distance + * Fields. Master's thesis. Czech Technical University in Prague, + * Faculty of InformationTechnology, 2015. + * + * For more information: https://github.com/Chlumsky/msdfgen + * + * ======================================================================== + * + * Generating SDF from outlines is pretty straightforward. + * + * (1) We have a set of contours that make the outline of a shape/glyph. + * Each contour comprises of several edges, with three types of edges. + * + * * line segments + * * conic Bezier curves + * * cubic Bezier curves + * + * (2) Apart from the outlines we also have a two-dimensional grid, namely + * the bitmap that is used to represent the final SDF data. + * + * (3) In order to generate SDF, our task is to find shortest signed + * distance from each grid point to the outline. The 'signed + * distance' means that if the grid point is filled by any contour + * then its sign is positive, otherwise it is negative. The pseudo + * code is as follows. + * + * ``` + * foreach grid_point (x, y): + * { + * int min_dist = INT_MAX; + * + * foreach contour in outline: + * { + * foreach edge in contour: + * { + * // get shortest distance from point (x, y) to the edge + * d = get_min_dist(x, y, edge); + * + * if (d < min_dist) + * min_dist = d; + * } + * + * bitmap[x, y] = min_dist; + * } + * } + * ``` + * + * (4) After running this algorithm the bitmap contains information about + * the shortest distance from each point to the outline of the shape. + * Of course, while this is the most straightforward way of generating + * SDF, we use various optimizations in our implementation. See the + * `sdf_generate_*' functions in this file for all details. + * + * The optimization currently used by default is subdivision; see + * function `sdf_generate_subdivision` for more. + * + * Also, to see how we compute the shortest distance from a point to + * each type of edge, check out the `get_min_distance_*' functions. + * + */ + + + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ +#undef FT_COMPONENT +#define FT_COMPONENT sdf + + + /************************************************************************** + * + * definitions + * + */ + + /* + * If set to 1, the rasterizer uses Newton-Raphson's method for finding + * the shortest distance from a point to a conic curve. + * + * If set to 0, an analytical method gets used instead, which computes the + * roots of a cubic polynomial to find the shortest distance. However, + * the analytical method can currently underflow; we thus use Newton's + * method by default. + */ +#ifndef USE_NEWTON_FOR_CONIC +#define USE_NEWTON_FOR_CONIC 1 +#endif + + /* + * The number of intervals a Bezier curve gets sampled and checked to find + * the shortest distance. + */ +#define MAX_NEWTON_DIVISIONS 4 + + /* + * The number of steps of Newton's iterations in each interval of the + * Bezier curve. Basically, we run Newton's approximation + * + * x -= Q(t) / Q'(t) + * + * for each division to get the shortest distance. + */ +#define MAX_NEWTON_STEPS 4 + + /* + * The epsilon distance (in 16.16 fractional units) used for corner + * resolving. If the difference of two distances is less than this value + * they will be checked for a corner if they are ambiguous. + */ +#define CORNER_CHECK_EPSILON 32 + +#if 0 + /* + * Coarse grid dimension. Will probably be removed in the future because + * coarse grid optimization is the slowest algorithm. + */ +#define CG_DIMEN 8 +#endif + + + /************************************************************************** + * + * macros + * + */ + +#define MUL_26D6( a, b ) ( ( ( a ) * ( b ) ) / 64 ) +#define VEC_26D6_DOT( p, q ) ( MUL_26D6( p.x, q.x ) + \ + MUL_26D6( p.y, q.y ) ) + + + /************************************************************************** + * + * structures and enums + * + */ + + /************************************************************************** + * + * @Struct: + * SDF_TRaster + * + * @Description: + * This struct is used in place of @FT_Raster and is stored within the + * internal FreeType renderer struct. While rasterizing it is passed to + * the @FT_Raster_RenderFunc function, which then can be used however we + * want. + * + * @Fields: + * memory :: + * Used internally to allocate intermediate memory while raterizing. + * + */ + typedef struct SDF_TRaster_ + { + FT_Memory memory; + + } SDF_TRaster, *SDF_PRaster; + + + /************************************************************************** + * + * @Enum: + * SDF_Edge_Type + * + * @Description: + * Enumeration of all curve types present in fonts. + * + * @Fields: + * SDF_EDGE_UNDEFINED :: + * Undefined edge, simply used to initialize and detect errors. + * + * SDF_EDGE_LINE :: + * Line segment with start and end point. + * + * SDF_EDGE_CONIC :: + * A conic/quadratic Bezier curve with start, end, and one control + * point. + * + * SDF_EDGE_CUBIC :: + * A cubic Bezier curve with start, end, and two control points. + * + */ + typedef enum SDF_Edge_Type_ + { + SDF_EDGE_UNDEFINED = 0, + SDF_EDGE_LINE = 1, + SDF_EDGE_CONIC = 2, + SDF_EDGE_CUBIC = 3 + + } SDF_Edge_Type; + + + /************************************************************************** + * + * @Enum: + * SDF_Contour_Orientation + * + * @Description: + * Enumeration of all orientation values of a contour. We determine the + * orientation by calculating the area covered by a contour. Contrary + * to values returned by @FT_Outline_Get_Orientation, + * `SDF_Contour_Orientation` is independent of the fill rule, which can + * be different for different font formats. + * + * @Fields: + * SDF_ORIENTATION_NONE :: + * Undefined orientation, used for initialization and error detection. + * + * SDF_ORIENTATION_CW :: + * Clockwise orientation (positive area covered). + * + * SDF_ORIENTATION_CCW :: + * Counter-clockwise orientation (negative area covered). + * + * @Note: + * See @FT_Outline_Get_Orientation for more details. + * + */ + typedef enum SDF_Contour_Orientation_ + { + SDF_ORIENTATION_NONE = 0, + SDF_ORIENTATION_CW = 1, + SDF_ORIENTATION_CCW = 2 + + } SDF_Contour_Orientation; + + + /************************************************************************** + * + * @Struct: + * SDF_Edge + * + * @Description: + * Represent an edge of a contour. + * + * @Fields: + * start_pos :: + * Start position of an edge. Valid for all types of edges. + * + * end_pos :: + * Etart position of an edge. Valid for all types of edges. + * + * control_a :: + * A control point of the edge. Valid only for `SDF_EDGE_CONIC` + * and `SDF_EDGE_CUBIC`. + * + * control_b :: + * Another control point of the edge. Valid only for + * `SDF_EDGE_CONIC`. + * + * edge_type :: + * Type of the edge, see @SDF_Edge_Type for all possible edge types. + * + * next :: + * Used to create a singly linked list, which can be interpreted + * as a contour. + * + */ + typedef struct SDF_Edge_ + { + FT_26D6_Vec start_pos; + FT_26D6_Vec end_pos; + FT_26D6_Vec control_a; + FT_26D6_Vec control_b; + + SDF_Edge_Type edge_type; + + struct SDF_Edge_* next; + + } SDF_Edge; + + + /************************************************************************** + * + * @Struct: + * SDF_Contour + * + * @Description: + * Represent a complete contour, which contains a list of edges. + * + * @Fields: + * last_pos :: + * Contains the value of `end_pos' of the last edge in the list of + * edges. Useful while decomposing the outline with + * @FT_Outline_Decompose. + * + * edges :: + * Linked list of all the edges that make the contour. + * + * next :: + * Used to create a singly linked list, which can be interpreted as a + * complete shape or @FT_Outline. + * + */ + typedef struct SDF_Contour_ + { + FT_26D6_Vec last_pos; + SDF_Edge* edges; + + struct SDF_Contour_* next; + + } SDF_Contour; + + + /************************************************************************** + * + * @Struct: + * SDF_Shape + * + * @Description: + * Represent a complete shape, which is the decomposition of + * @FT_Outline. + * + * @Fields: + * memory :: + * Used internally to allocate memory. + * + * contours :: + * Linked list of all the contours that make the shape. + * + */ + typedef struct SDF_Shape_ + { + FT_Memory memory; + SDF_Contour* contours; + + } SDF_Shape; + + + /************************************************************************** + * + * @Struct: + * SDF_Signed_Distance + * + * @Description: + * Represent signed distance of a point, i.e., the distance of the edge + * nearest to the point. + * + * @Fields: + * distance :: + * Distance of the point from the nearest edge. Can be squared or + * absolute depending on the `USE_SQUARED_DISTANCES` macro defined in + * file `ftsdfcommon.h`. + * + * cross :: + * Cross product of the shortest distance vector (i.e., the vector + * from the point to the nearest edge) and the direction of the edge + * at the nearest point. This is used to resolve ambiguities of + * `sign`. + * + * sign :: + * A value used to indicate whether the distance vector is outside or + * inside the contour corresponding to the edge. + * + * @Note: + * `sign` may or may not be correct, therefore it must be checked + * properly in case there is an ambiguity. + * + */ + typedef struct SDF_Signed_Distance_ + { + FT_16D16 distance; + FT_16D16 cross; + FT_Char sign; + + } SDF_Signed_Distance; + + + /************************************************************************** + * + * @Struct: + * SDF_Params + * + * @Description: + * Yet another internal parameters required by the rasterizer. + * + * @Fields: + * orientation :: + * This is not the @SDF_Contour_Orientation value but @FT_Orientation, + * which determines whether clockwise-oriented outlines are to be + * filled or counter-clockwise-oriented ones. + * + * flip_sign :: + * If set to true, flip the sign. By default the points filled by the + * outline are positive. + * + * flip_y :: + * If set to true the output bitmap is upside-down. Can be useful + * because OpenGL and DirectX use different coordinate systems for + * textures. + * + * overload_sign :: + * In the subdivision and bounding box optimization, the default + * outside sign is taken as -1. This parameter can be used to modify + * that behaviour. For example, while generating SDF for a single + * counter-clockwise contour, the outside sign should be 1. + * + */ + typedef struct SDF_Params_ + { + FT_Orientation orientation; + FT_Bool flip_sign; + FT_Bool flip_y; + + FT_Int overload_sign; + + } SDF_Params; + + + /************************************************************************** + * + * constants, initializer, and destructor + * + */ + + static + const FT_Vector zero_vector = { 0, 0 }; + + static + const SDF_Edge null_edge = { { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, + SDF_EDGE_UNDEFINED, NULL }; + + static + const SDF_Contour null_contour = { { 0, 0 }, NULL, NULL }; + + static + const SDF_Shape null_shape = { NULL, NULL }; + + static + const SDF_Signed_Distance max_sdf = { INT_MAX, 0, 0 }; + + + /* Create a new @SDF_Edge on the heap and assigns the `edge` */ + /* pointer to the newly allocated memory. */ + static FT_Error + sdf_edge_new( FT_Memory memory, + SDF_Edge** edge ) + { + FT_Error error = FT_Err_Ok; + SDF_Edge* ptr = NULL; + + + if ( !memory || !edge ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( !FT_QALLOC( ptr, sizeof ( *ptr ) ) ) + { + *ptr = null_edge; + *edge = ptr; + } + + Exit: + return error; + } + + + /* Free the allocated `edge` variable. */ + static void + sdf_edge_done( FT_Memory memory, + SDF_Edge** edge ) + { + if ( !memory || !edge || !*edge ) + return; + + FT_FREE( *edge ); + } + + + /* Create a new @SDF_Contour on the heap and assign */ + /* the `contour` pointer to the newly allocated memory. */ + static FT_Error + sdf_contour_new( FT_Memory memory, + SDF_Contour** contour ) + { + FT_Error error = FT_Err_Ok; + SDF_Contour* ptr = NULL; + + + if ( !memory || !contour ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( !FT_QALLOC( ptr, sizeof ( *ptr ) ) ) + { + *ptr = null_contour; + *contour = ptr; + } + + Exit: + return error; + } + + + /* Free the allocated `contour` variable. */ + /* Also free the list of edges. */ + static void + sdf_contour_done( FT_Memory memory, + SDF_Contour** contour ) + { + SDF_Edge* edges; + SDF_Edge* temp; + + + if ( !memory || !contour || !*contour ) + return; + + edges = (*contour)->edges; + + /* release all edges */ + while ( edges ) + { + temp = edges; + edges = edges->next; + + sdf_edge_done( memory, &temp ); + } + + FT_FREE( *contour ); + } + + + /* Create a new @SDF_Shape on the heap and assign */ + /* the `shape` pointer to the newly allocated memory. */ + static FT_Error + sdf_shape_new( FT_Memory memory, + SDF_Shape** shape ) + { + FT_Error error = FT_Err_Ok; + SDF_Shape* ptr = NULL; + + + if ( !memory || !shape ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( !FT_QALLOC( ptr, sizeof ( *ptr ) ) ) + { + *ptr = null_shape; + ptr->memory = memory; + *shape = ptr; + } + + Exit: + return error; + } + + + /* Free the allocated `shape` variable. */ + /* Also free the list of contours. */ + static void + sdf_shape_done( SDF_Shape** shape ) + { + FT_Memory memory; + SDF_Contour* contours; + SDF_Contour* temp; + + + if ( !shape || !*shape ) + return; + + memory = (*shape)->memory; + contours = (*shape)->contours; + + if ( !memory ) + return; + + /* release all contours */ + while ( contours ) + { + temp = contours; + contours = contours->next; + + sdf_contour_done( memory, &temp ); + } + + /* release the allocated shape struct */ + FT_FREE( *shape ); + } + + + /************************************************************************** + * + * shape decomposition functions + * + */ + + /* This function is called when starting a new contour at `to`, */ + /* which gets added to the shape's list. */ + static FT_Error + sdf_move_to( const FT_26D6_Vec* to, + void* user ) + { + SDF_Shape* shape = ( SDF_Shape* )user; + SDF_Contour* contour = NULL; + + FT_Error error = FT_Err_Ok; + FT_Memory memory = shape->memory; + + + if ( !to || !user ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + FT_CALL( sdf_contour_new( memory, &contour ) ); + + contour->last_pos = *to; + contour->next = shape->contours; + shape->contours = contour; + + Exit: + return error; + } + + + /* This function is called when there is a line in the */ + /* contour. The line starts at the previous edge point and */ + /* stops at `to`. */ + static FT_Error + sdf_line_to( const FT_26D6_Vec* to, + void* user ) + { + SDF_Shape* shape = ( SDF_Shape* )user; + SDF_Edge* edge = NULL; + SDF_Contour* contour = NULL; + + FT_Error error = FT_Err_Ok; + FT_Memory memory = shape->memory; + + + if ( !to || !user ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + contour = shape->contours; + + if ( contour->last_pos.x == to->x && + contour->last_pos.y == to->y ) + goto Exit; + + FT_CALL( sdf_edge_new( memory, &edge ) ); + + edge->edge_type = SDF_EDGE_LINE; + edge->start_pos = contour->last_pos; + edge->end_pos = *to; + + edge->next = contour->edges; + contour->edges = edge; + contour->last_pos = *to; + + Exit: + return error; + } + + + /* This function is called when there is a conic Bezier curve */ + /* in the contour. The curve starts at the previous edge point */ + /* and stops at `to`, with control point `control_1`. */ + static FT_Error + sdf_conic_to( const FT_26D6_Vec* control_1, + const FT_26D6_Vec* to, + void* user ) + { + SDF_Shape* shape = ( SDF_Shape* )user; + SDF_Edge* edge = NULL; + SDF_Contour* contour = NULL; + + FT_Error error = FT_Err_Ok; + FT_Memory memory = shape->memory; + + + if ( !control_1 || !to || !user ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + contour = shape->contours; + + FT_CALL( sdf_edge_new( memory, &edge ) ); + + edge->edge_type = SDF_EDGE_CONIC; + edge->start_pos = contour->last_pos; + edge->control_a = *control_1; + edge->end_pos = *to; + + edge->next = contour->edges; + contour->edges = edge; + contour->last_pos = *to; + + Exit: + return error; + } + + + /* This function is called when there is a cubic Bezier curve */ + /* in the contour. The curve starts at the previous edge point */ + /* and stops at `to`, with two control points `control_1` and */ + /* `control_2`. */ + static FT_Error + sdf_cubic_to( const FT_26D6_Vec* control_1, + const FT_26D6_Vec* control_2, + const FT_26D6_Vec* to, + void* user ) + { + SDF_Shape* shape = ( SDF_Shape* )user; + SDF_Edge* edge = NULL; + SDF_Contour* contour = NULL; + + FT_Error error = FT_Err_Ok; + FT_Memory memory = shape->memory; + + + if ( !control_2 || !control_1 || !to || !user ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + contour = shape->contours; + + FT_CALL( sdf_edge_new( memory, &edge ) ); + + edge->edge_type = SDF_EDGE_CUBIC; + edge->start_pos = contour->last_pos; + edge->control_a = *control_1; + edge->control_b = *control_2; + edge->end_pos = *to; + + edge->next = contour->edges; + contour->edges = edge; + contour->last_pos = *to; + + Exit: + return error; + } + + + /* Construct the structure to hold all four outline */ + /* decomposition functions. */ + FT_DEFINE_OUTLINE_FUNCS( + sdf_decompose_funcs, + + (FT_Outline_MoveTo_Func) sdf_move_to, /* move_to */ + (FT_Outline_LineTo_Func) sdf_line_to, /* line_to */ + (FT_Outline_ConicTo_Func)sdf_conic_to, /* conic_to */ + (FT_Outline_CubicTo_Func)sdf_cubic_to, /* cubic_to */ + + 0, /* shift */ + 0 /* delta */ + ) + + + /* Decompose `outline` and put it into the `shape` structure. */ + static FT_Error + sdf_outline_decompose( FT_Outline* outline, + SDF_Shape* shape ) + { + FT_Error error = FT_Err_Ok; + + + if ( !outline || !shape ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + error = FT_Outline_Decompose( outline, + &sdf_decompose_funcs, + (void*)shape ); + + Exit: + return error; + } + + + /************************************************************************** + * + * utility functions + * + */ + + /* Return the control box of an edge. The control box is a rectangle */ + /* in which all the control points can fit tightly. */ + static FT_CBox + get_control_box( SDF_Edge edge ) + { + FT_CBox cbox = { 0, 0, 0, 0 }; + FT_Bool is_set = 0; + + + switch ( edge.edge_type ) + { + case SDF_EDGE_CUBIC: + cbox.xMin = edge.control_b.x; + cbox.xMax = edge.control_b.x; + cbox.yMin = edge.control_b.y; + cbox.yMax = edge.control_b.y; + + is_set = 1; + /* fall through */ + + case SDF_EDGE_CONIC: + if ( is_set ) + { + cbox.xMin = edge.control_a.x < cbox.xMin + ? edge.control_a.x + : cbox.xMin; + cbox.xMax = edge.control_a.x > cbox.xMax + ? edge.control_a.x + : cbox.xMax; + + cbox.yMin = edge.control_a.y < cbox.yMin + ? edge.control_a.y + : cbox.yMin; + cbox.yMax = edge.control_a.y > cbox.yMax + ? edge.control_a.y + : cbox.yMax; + } + else + { + cbox.xMin = edge.control_a.x; + cbox.xMax = edge.control_a.x; + cbox.yMin = edge.control_a.y; + cbox.yMax = edge.control_a.y; + + is_set = 1; + } + /* fall through */ + + case SDF_EDGE_LINE: + if ( is_set ) + { + cbox.xMin = edge.start_pos.x < cbox.xMin + ? edge.start_pos.x + : cbox.xMin; + cbox.xMax = edge.start_pos.x > cbox.xMax + ? edge.start_pos.x + : cbox.xMax; + + cbox.yMin = edge.start_pos.y < cbox.yMin + ? edge.start_pos.y + : cbox.yMin; + cbox.yMax = edge.start_pos.y > cbox.yMax + ? edge.start_pos.y + : cbox.yMax; + } + else + { + cbox.xMin = edge.start_pos.x; + cbox.xMax = edge.start_pos.x; + cbox.yMin = edge.start_pos.y; + cbox.yMax = edge.start_pos.y; + } + + cbox.xMin = edge.end_pos.x < cbox.xMin + ? edge.end_pos.x + : cbox.xMin; + cbox.xMax = edge.end_pos.x > cbox.xMax + ? edge.end_pos.x + : cbox.xMax; + + cbox.yMin = edge.end_pos.y < cbox.yMin + ? edge.end_pos.y + : cbox.yMin; + cbox.yMax = edge.end_pos.y > cbox.yMax + ? edge.end_pos.y + : cbox.yMax; + + break; + + default: + break; + } + + return cbox; + } + + + /* Return orientation of a single contour. */ + /* Note that the orientation is independent of the fill rule! */ + /* So, for TTF a clockwise-oriented contour has to be filled */ + /* and the opposite for OTF fonts. */ + static SDF_Contour_Orientation + get_contour_orientation ( SDF_Contour* contour ) + { + SDF_Edge* head = NULL; + FT_26D6 area = 0; + + + /* return none if invalid parameters */ + if ( !contour || !contour->edges ) + return SDF_ORIENTATION_NONE; + + head = contour->edges; + + /* Calculate the area of the control box for all edges. */ + while ( head ) + { + switch ( head->edge_type ) + { + case SDF_EDGE_LINE: + area += MUL_26D6( ( head->end_pos.x - head->start_pos.x ), + ( head->end_pos.y + head->start_pos.y ) ); + break; + + case SDF_EDGE_CONIC: + area += MUL_26D6( head->control_a.x - head->start_pos.x, + head->control_a.y + head->start_pos.y ); + area += MUL_26D6( head->end_pos.x - head->control_a.x, + head->end_pos.y + head->control_a.y ); + break; + + case SDF_EDGE_CUBIC: + area += MUL_26D6( head->control_a.x - head->start_pos.x, + head->control_a.y + head->start_pos.y ); + area += MUL_26D6( head->control_b.x - head->control_a.x, + head->control_b.y + head->control_a.y ); + area += MUL_26D6( head->end_pos.x - head->control_b.x, + head->end_pos.y + head->control_b.y ); + break; + + default: + return SDF_ORIENTATION_NONE; + } + + head = head->next; + } + + /* Clockwise contours cover a positive area, and counter-clockwise */ + /* contours cover a negative area. */ + if ( area > 0 ) + return SDF_ORIENTATION_CW; + else + return SDF_ORIENTATION_CCW; + } + + + /* This function is exactly the same as the one */ + /* in the smooth renderer. It splits a conic */ + /* into two conics exactly half way at t = 0.5. */ + static void + split_conic( FT_26D6_Vec* base ) + { + FT_26D6 a, b; + + + base[4].x = base[2].x; + a = base[0].x + base[1].x; + b = base[1].x + base[2].x; + base[3].x = b / 2; + base[2].x = ( a + b ) / 4; + base[1].x = a / 2; + + base[4].y = base[2].y; + a = base[0].y + base[1].y; + b = base[1].y + base[2].y; + base[3].y = b / 2; + base[2].y = ( a + b ) / 4; + base[1].y = a / 2; + } + + + /* This function is exactly the same as the one */ + /* in the smooth renderer. It splits a cubic */ + /* into two cubics exactly half way at t = 0.5. */ + static void + split_cubic( FT_26D6_Vec* base ) + { + FT_26D6 a, b, c; + + + base[6].x = base[3].x; + a = base[0].x + base[1].x; + b = base[1].x + base[2].x; + c = base[2].x + base[3].x; + base[5].x = c / 2; + c += b; + base[4].x = c / 4; + base[1].x = a / 2; + a += b; + base[2].x = a / 4; + base[3].x = ( a + c ) / 8; + + base[6].y = base[3].y; + a = base[0].y + base[1].y; + b = base[1].y + base[2].y; + c = base[2].y + base[3].y; + base[5].y = c / 2; + c += b; + base[4].y = c / 4; + base[1].y = a / 2; + a += b; + base[2].y = a / 4; + base[3].y = ( a + c ) / 8; + } + + + /* Split a conic Bezier curve into a number of lines */ + /* and add them to `out'. */ + /* */ + /* This function uses recursion; we thus need */ + /* parameter `max_splits' for stopping. */ + static FT_Error + split_sdf_conic( FT_Memory memory, + FT_26D6_Vec* control_points, + FT_Int max_splits, + SDF_Edge** out ) + { + FT_Error error = FT_Err_Ok; + FT_26D6_Vec cpos[5]; + SDF_Edge* left,* right; + + + if ( !memory || !out ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* split conic outline */ + cpos[0] = control_points[0]; + cpos[1] = control_points[1]; + cpos[2] = control_points[2]; + + split_conic( cpos ); + + /* If max number of splits is done */ + /* then stop and add the lines to */ + /* the list. */ + if ( max_splits <= 2 ) + goto Append; + + /* Otherwise keep splitting. */ + FT_CALL( split_sdf_conic( memory, &cpos[0], max_splits / 2, out ) ); + FT_CALL( split_sdf_conic( memory, &cpos[2], max_splits / 2, out ) ); + + /* [NOTE]: This is not an efficient way of */ + /* splitting the curve. Check the deviation */ + /* instead and stop if the deviation is less */ + /* than a pixel. */ + + goto Exit; + + Append: + /* Do allocation and add the lines to the list. */ + + FT_CALL( sdf_edge_new( memory, &left ) ); + FT_CALL( sdf_edge_new( memory, &right ) ); + + left->start_pos = cpos[0]; + left->end_pos = cpos[2]; + left->edge_type = SDF_EDGE_LINE; + + right->start_pos = cpos[2]; + right->end_pos = cpos[4]; + right->edge_type = SDF_EDGE_LINE; + + left->next = right; + right->next = (*out); + *out = left; + + Exit: + return error; + } + + + /* Split a cubic Bezier curve into a number of lines */ + /* and add them to `out`. */ + /* */ + /* This function uses recursion; we thus need */ + /* parameter `max_splits' for stopping. */ + static FT_Error + split_sdf_cubic( FT_Memory memory, + FT_26D6_Vec* control_points, + FT_Int max_splits, + SDF_Edge** out ) + { + FT_Error error = FT_Err_Ok; + FT_26D6_Vec cpos[7]; + SDF_Edge* left,* right; + + + if ( !memory || !out ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* split the conic */ + cpos[0] = control_points[0]; + cpos[1] = control_points[1]; + cpos[2] = control_points[2]; + cpos[3] = control_points[3]; + + split_cubic( cpos ); + + /* If max number of splits is done */ + /* then stop and add the lines to */ + /* the list. */ + if ( max_splits <= 2 ) + goto Append; + + /* Otherwise keep splitting. */ + FT_CALL( split_sdf_cubic( memory, &cpos[0], max_splits / 2, out ) ); + FT_CALL( split_sdf_cubic( memory, &cpos[3], max_splits / 2, out ) ); + + /* [NOTE]: This is not an efficient way of */ + /* splitting the curve. Check the deviation */ + /* instead and stop if the deviation is less */ + /* than a pixel. */ + + goto Exit; + + Append: + /* Do allocation and add the lines to the list. */ + + FT_CALL( sdf_edge_new( memory, &left) ); + FT_CALL( sdf_edge_new( memory, &right) ); + + left->start_pos = cpos[0]; + left->end_pos = cpos[3]; + left->edge_type = SDF_EDGE_LINE; + + right->start_pos = cpos[3]; + right->end_pos = cpos[6]; + right->edge_type = SDF_EDGE_LINE; + + left->next = right; + right->next = (*out); + *out = left; + + Exit: + return error; + } + + + /* Subdivide an entire shape into line segments */ + /* such that it doesn't look visually different */ + /* from the original curve. */ + static FT_Error + split_sdf_shape( SDF_Shape* shape ) + { + FT_Error error = FT_Err_Ok; + FT_Memory memory; + + SDF_Contour* contours; + SDF_Contour* new_contours = NULL; + + + if ( !shape || !shape->memory ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + contours = shape->contours; + memory = shape->memory; + + /* for each contour */ + while ( contours ) + { + SDF_Edge* edges = contours->edges; + SDF_Edge* new_edges = NULL; + + SDF_Contour* tempc; + + + /* for each edge */ + while ( edges ) + { + SDF_Edge* edge = edges; + SDF_Edge* temp; + + switch ( edge->edge_type ) + { + case SDF_EDGE_LINE: + /* Just create a duplicate edge in case */ + /* it is a line. We can use the same edge. */ + FT_CALL( sdf_edge_new( memory, &temp ) ); + + ft_memcpy( temp, edge, sizeof ( *edge ) ); + + temp->next = new_edges; + new_edges = temp; + break; + + case SDF_EDGE_CONIC: + /* Subdivide the curve and add it to the list. */ + { + FT_26D6_Vec ctrls[3]; + + + ctrls[0] = edge->start_pos; + ctrls[1] = edge->control_a; + ctrls[2] = edge->end_pos; + + error = split_sdf_conic( memory, ctrls, 32, &new_edges ); + } + break; + + case SDF_EDGE_CUBIC: + /* Subdivide the curve and add it to the list. */ + { + FT_26D6_Vec ctrls[4]; + + + ctrls[0] = edge->start_pos; + ctrls[1] = edge->control_a; + ctrls[2] = edge->control_b; + ctrls[3] = edge->end_pos; + + error = split_sdf_cubic( memory, ctrls, 32, &new_edges ); + } + break; + + default: + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + edges = edges->next; + } + + /* add to the contours list */ + FT_CALL( sdf_contour_new( memory, &tempc ) ); + + tempc->next = new_contours; + tempc->edges = new_edges; + new_contours = tempc; + new_edges = NULL; + + /* deallocate the contour */ + tempc = contours; + contours = contours->next; + + sdf_contour_done( memory, &tempc ); + } + + shape->contours = new_contours; + + Exit: + return error; + } + + + /************************************************************************** + * + * for debugging + * + */ + +#ifdef FT_DEBUG_LEVEL_TRACE + + static void + sdf_shape_dump( SDF_Shape* shape ) + { + FT_UInt num_contours = 0; + + FT_UInt total_edges = 0; + FT_UInt total_lines = 0; + FT_UInt total_conic = 0; + FT_UInt total_cubic = 0; + + SDF_Contour* contour_list; + + + if ( !shape ) + { + FT_TRACE5(( "sdf_shape_dump: null shape\n" )); + return; + } + + contour_list = shape->contours; + + FT_TRACE5(( "sdf_shape_dump (values are in 26.6 format):\n" )); + + while ( contour_list ) + { + FT_UInt num_edges = 0; + SDF_Edge* edge_list; + SDF_Contour* contour = contour_list; + + + FT_TRACE5(( " Contour %d\n", num_contours )); + + edge_list = contour->edges; + + while ( edge_list ) + { + SDF_Edge* edge = edge_list; + + + FT_TRACE5(( " %3d: ", num_edges )); + + switch ( edge->edge_type ) + { + case SDF_EDGE_LINE: + FT_TRACE5(( "Line: (%ld, %ld) -- (%ld, %ld)\n", + edge->start_pos.x, edge->start_pos.y, + edge->end_pos.x, edge->end_pos.y )); + total_lines++; + break; + + case SDF_EDGE_CONIC: + FT_TRACE5(( "Conic: (%ld, %ld) .. (%ld, %ld) .. (%ld, %ld)\n", + edge->start_pos.x, edge->start_pos.y, + edge->control_a.x, edge->control_a.y, + edge->end_pos.x, edge->end_pos.y )); + total_conic++; + break; + + case SDF_EDGE_CUBIC: + FT_TRACE5(( "Cubic: (%ld, %ld) .. (%ld, %ld)" + " .. (%ld, %ld) .. (%ld %ld)\n", + edge->start_pos.x, edge->start_pos.y, + edge->control_a.x, edge->control_a.y, + edge->control_b.x, edge->control_b.y, + edge->end_pos.x, edge->end_pos.y )); + total_cubic++; + break; + + default: + break; + } + + num_edges++; + total_edges++; + edge_list = edge_list->next; + } + + num_contours++; + contour_list = contour_list->next; + } + + FT_TRACE5(( "\n" )); + FT_TRACE5(( " total number of contours = %d\n", num_contours )); + FT_TRACE5(( " total number of edges = %d\n", total_edges )); + FT_TRACE5(( " |__lines = %d\n", total_lines )); + FT_TRACE5(( " |__conic = %d\n", total_conic )); + FT_TRACE5(( " |__cubic = %d\n", total_cubic )); + } + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + + /************************************************************************** + * + * math functions + * + */ + +#if !USE_NEWTON_FOR_CONIC + + /* [NOTE]: All the functions below down until rasterizer */ + /* can be avoided if we decide to subdivide the */ + /* curve into lines. */ + + /* This function uses Newton's iteration to find */ + /* the cube root of a fixed-point integer. */ + static FT_16D16 + cube_root( FT_16D16 val ) + { + /* [IMPORTANT]: This function is not good as it may */ + /* not break, so use a lookup table instead. Or we */ + /* can use an algorithm similar to `square_root`. */ + + FT_Int v, g, c; + + + if ( val == 0 || + val == -FT_INT_16D16( 1 ) || + val == FT_INT_16D16( 1 ) ) + return val; + + v = val < 0 ? -val : val; + g = square_root( v ); + c = 0; + + while ( 1 ) + { + c = FT_MulFix( FT_MulFix( g, g ), g ) - v; + c = FT_DivFix( c, 3 * FT_MulFix( g, g ) ); + + g -= c; + + if ( ( c < 0 ? -c : c ) < 30 ) + break; + } + + return val < 0 ? -g : g; + } + + + /* Calculate the perpendicular by using '1 - base^2'. */ + /* Then use arctan to compute the angle. */ + static FT_16D16 + arc_cos( FT_16D16 val ) + { + FT_16D16 p; + FT_16D16 b = val; + FT_16D16 one = FT_INT_16D16( 1 ); + + + if ( b > one ) + b = one; + if ( b < -one ) + b = -one; + + p = one - FT_MulFix( b, b ); + p = square_root( p ); + + return FT_Atan2( b, p ); + } + + + /* Compute roots of a quadratic polynomial, assign them to `out`, */ + /* and return number of real roots. */ + /* */ + /* The procedure can be found at */ + /* */ + /* https://mathworld.wolfram.com/QuadraticFormula.html */ + static FT_UShort + solve_quadratic_equation( FT_26D6 a, + FT_26D6 b, + FT_26D6 c, + FT_16D16 out[2] ) + { + FT_16D16 discriminant = 0; + + + a = FT_26D6_16D16( a ); + b = FT_26D6_16D16( b ); + c = FT_26D6_16D16( c ); + + if ( a == 0 ) + { + if ( b == 0 ) + return 0; + else + { + out[0] = FT_DivFix( -c, b ); + + return 1; + } + } + + discriminant = FT_MulFix( b, b ) - 4 * FT_MulFix( a, c ); + + if ( discriminant < 0 ) + return 0; + else if ( discriminant == 0 ) + { + out[0] = FT_DivFix( -b, 2 * a ); + + return 1; + } + else + { + discriminant = square_root( discriminant ); + + out[0] = FT_DivFix( -b + discriminant, 2 * a ); + out[1] = FT_DivFix( -b - discriminant, 2 * a ); + + return 2; + } + } + + + /* Compute roots of a cubic polynomial, assign them to `out`, */ + /* and return number of real roots. */ + /* */ + /* The procedure can be found at */ + /* */ + /* https://mathworld.wolfram.com/CubicFormula.html */ + static FT_UShort + solve_cubic_equation( FT_26D6 a, + FT_26D6 b, + FT_26D6 c, + FT_26D6 d, + FT_16D16 out[3] ) + { + FT_16D16 q = 0; /* intermediate */ + FT_16D16 r = 0; /* intermediate */ + + FT_16D16 a2 = b; /* x^2 coefficients */ + FT_16D16 a1 = c; /* x coefficients */ + FT_16D16 a0 = d; /* constant */ + + FT_16D16 q3 = 0; + FT_16D16 r2 = 0; + FT_16D16 a23 = 0; + FT_16D16 a22 = 0; + FT_16D16 a1x2 = 0; + + + /* cutoff value for `a` to be a cubic, otherwise solve quadratic */ + if ( a == 0 || FT_ABS( a ) < 16 ) + return solve_quadratic_equation( b, c, d, out ); + + if ( d == 0 ) + { + out[0] = 0; + + return solve_quadratic_equation( a, b, c, out + 1 ) + 1; + } + + /* normalize the coefficients; this also makes them 16.16 */ + a2 = FT_DivFix( a2, a ); + a1 = FT_DivFix( a1, a ); + a0 = FT_DivFix( a0, a ); + + /* compute intermediates */ + a1x2 = FT_MulFix( a1, a2 ); + a22 = FT_MulFix( a2, a2 ); + a23 = FT_MulFix( a22, a2 ); + + q = ( 3 * a1 - a22 ) / 9; + r = ( 9 * a1x2 - 27 * a0 - 2 * a23 ) / 54; + + /* [BUG]: `q3` and `r2` still cause underflow. */ + + q3 = FT_MulFix( q, q ); + q3 = FT_MulFix( q3, q ); + + r2 = FT_MulFix( r, r ); + + if ( q3 < 0 && r2 < -q3 ) + { + FT_16D16 t = 0; + + + q3 = square_root( -q3 ); + t = FT_DivFix( r, q3 ); + + if ( t > ( 1 << 16 ) ) + t = ( 1 << 16 ); + if ( t < -( 1 << 16 ) ) + t = -( 1 << 16 ); + + t = arc_cos( t ); + a2 /= 3; + q = 2 * square_root( -q ); + + out[0] = FT_MulFix( q, FT_Cos( t / 3 ) ) - a2; + out[1] = FT_MulFix( q, FT_Cos( ( t + FT_ANGLE_PI * 2 ) / 3 ) ) - a2; + out[2] = FT_MulFix( q, FT_Cos( ( t + FT_ANGLE_PI * 4 ) / 3 ) ) - a2; + + return 3; + } + + else if ( r2 == -q3 ) + { + FT_16D16 s = 0; + + + s = cube_root( r ); + a2 /= -3; + + out[0] = a2 + ( 2 * s ); + out[1] = a2 - s; + + return 2; + } + + else + { + FT_16D16 s = 0; + FT_16D16 t = 0; + FT_16D16 dis = 0; + + + if ( q3 == 0 ) + dis = FT_ABS( r ); + else + dis = square_root( q3 + r2 ); + + s = cube_root( r + dis ); + t = cube_root( r - dis ); + a2 /= -3; + out[0] = ( a2 + ( s + t ) ); + + return 1; + } + } + +#endif /* !USE_NEWTON_FOR_CONIC */ + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** RASTERIZER **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + /************************************************************************** + * + * @Function: + * resolve_corner + * + * @Description: + * At some places on the grid two edges can give opposite directions; + * this happens when the closest point is on one of the endpoint. In + * that case we need to check the proper sign. + * + * This can be visualized by an example: + * + * ``` + * x + * + * o + * ^ \ + * / \ + * / \ + * (a) / \ (b) + * / \ + * / \ + * / v + * ``` + * + * Suppose `x` is the point whose shortest distance from an arbitrary + * contour we want to find out. It is clear that `o` is the nearest + * point on the contour. Now to determine the sign we do a cross + * product of the shortest distance vector and the edge direction, i.e., + * + * ``` + * => sign = cross(x - o, direction(a)) + * ``` + * + * Using the right hand thumb rule we can see that the sign will be + * positive. + * + * If we use `b', however, we have + * + * ``` + * => sign = cross(x - o, direction(b)) + * ``` + * + * In this case the sign will be negative. To determine the correct + * sign we thus divide the plane in two halves and check which plane the + * point lies in. + * + * ``` + * | + * x | + * | + * o + * ^|\ + * / | \ + * / | \ + * (a) / | \ (b) + * / | \ + * / \ + * / v + * ``` + * + * We can see that `x` lies in the plane of `a`, so we take the sign + * determined by `a`. This test can be easily done by calculating the + * orthogonality and taking the greater one. + * + * The orthogonality is simply the sinus of the two vectors (i.e., + * x - o) and the corresponding direction. We efficiently pre-compute + * the orthogonality with the corresponding `get_min_distance_*` + * functions. + * + * @Input: + * sdf1 :: + * First signed distance (can be any of `a` or `b`). + * + * sdf1 :: + * Second signed distance (can be any of `a` or `b`). + * + * @Return: + * The correct signed distance, which is computed by using the above + * algorithm. + * + * @Note: + * The function does not care about the actual distance, it simply + * returns the signed distance which has a larger cross product. As a + * consequence, this function should not be used if the two distances + * are fairly apart. In that case simply use the signed distance with + * a shorter absolute distance. + * + */ + static SDF_Signed_Distance + resolve_corner( SDF_Signed_Distance sdf1, + SDF_Signed_Distance sdf2 ) + { + return FT_ABS( sdf1.cross ) > FT_ABS( sdf2.cross ) ? sdf1 : sdf2; + } + + + /************************************************************************** + * + * @Function: + * get_min_distance_line + * + * @Description: + * Find the shortest distance from the `line` segment to a given `point` + * and assign it to `out`. Use it for line segments only. + * + * @Input: + * line :: + * The line segment to which the shortest distance is to be computed. + * + * point :: + * Point from which the shortest distance is to be computed. + * + * @Output: + * out :: + * Signed distance from `point` to `line`. + * + * @Return: + * FreeType error, 0 means success. + * + * @Note: + * The `line' parameter must have an edge type of `SDF_EDGE_LINE`. + * + */ + static FT_Error + get_min_distance_line( SDF_Edge* line, + FT_26D6_Vec point, + SDF_Signed_Distance* out ) + { + /* + * In order to calculate the shortest distance from a point to + * a line segment, we do the following. Let's assume that + * + * ``` + * a = start point of the line segment + * b = end point of the line segment + * p = point from which shortest distance is to be calculated + * ``` + * + * (1) Write the parametric equation of the line. + * + * ``` + * point_on_line = a + (b - a) * t (t is the factor) + * ``` + * + * (2) Find the projection of point `p` on the line. The projection + * will be perpendicular to the line, which allows us to get the + * solution by making the dot product zero. + * + * ``` + * (point_on_line - a) . (p - point_on_line) = 0 + * + * (point_on_line) + * (a) x-------o----------------x (b) + * |_| + * | + * | + * (p) + * ``` + * + * (3) Simplification of the above equation yields the factor of + * `point_on_line`: + * + * ``` + * t = ((p - a) . (b - a)) / |b - a|^2 + * ``` + * + * (4) We clamp factor `t` between [0.0f, 1.0f] because `point_on_line` + * can be outside of the line segment: + * + * ``` + * (point_on_line) + * (a) x------------------------x (b) -----o--- + * |_| + * | + * | + * (p) + * ``` + * + * (5) Finally, the distance we are interested in is + * + * ``` + * |point_on_line - p| + * ``` + */ + + FT_Error error = FT_Err_Ok; + + FT_Vector a; /* start position */ + FT_Vector b; /* end position */ + FT_Vector p; /* current point */ + + FT_26D6_Vec line_segment; /* `b` - `a` */ + FT_26D6_Vec p_sub_a; /* `p` - `a` */ + + FT_26D6 sq_line_length; /* squared length of `line_segment` */ + FT_16D16 factor; /* factor of the nearest point */ + FT_26D6 cross; /* used to determine sign */ + + FT_16D16_Vec nearest_point; /* `point_on_line` */ + FT_16D16_Vec nearest_vector; /* `p` - `nearest_point` */ + + + if ( !line || !out ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( line->edge_type != SDF_EDGE_LINE ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + a = line->start_pos; + b = line->end_pos; + p = point; + + line_segment.x = b.x - a.x; + line_segment.y = b.y - a.y; + + p_sub_a.x = p.x - a.x; + p_sub_a.y = p.y - a.y; + + sq_line_length = ( line_segment.x * line_segment.x ) / 64 + + ( line_segment.y * line_segment.y ) / 64; + + /* currently factor is 26.6 */ + factor = ( p_sub_a.x * line_segment.x ) / 64 + + ( p_sub_a.y * line_segment.y ) / 64; + + /* now factor is 16.16 */ + factor = FT_DivFix( factor, sq_line_length ); + + /* clamp the factor between 0.0 and 1.0 in fixed point */ + if ( factor > FT_INT_16D16( 1 ) ) + factor = FT_INT_16D16( 1 ); + if ( factor < 0 ) + factor = 0; + + nearest_point.x = FT_MulFix( FT_26D6_16D16( line_segment.x ), + factor ); + nearest_point.y = FT_MulFix( FT_26D6_16D16( line_segment.y ), + factor ); + + nearest_point.x = FT_26D6_16D16( a.x ) + nearest_point.x; + nearest_point.y = FT_26D6_16D16( a.y ) + nearest_point.y; + + nearest_vector.x = nearest_point.x - FT_26D6_16D16( p.x ); + nearest_vector.y = nearest_point.y - FT_26D6_16D16( p.y ); + + cross = FT_MulFix( nearest_vector.x, line_segment.y ) - + FT_MulFix( nearest_vector.y, line_segment.x ); + + /* assign the output */ + out->sign = cross < 0 ? 1 : -1; + out->distance = VECTOR_LENGTH_16D16( nearest_vector ); + + /* Instead of finding `cross` for checking corner we */ + /* directly set it here. This is more efficient */ + /* because if the distance is perpendicular we can */ + /* directly set it to 1. */ + if ( factor != 0 && factor != FT_INT_16D16( 1 ) ) + out->cross = FT_INT_16D16( 1 ); + else + { + /* [OPTIMIZATION]: Pre-compute this direction. */ + /* If not perpendicular then compute `cross`. */ + FT_Vector_NormLen( &line_segment ); + FT_Vector_NormLen( &nearest_vector ); + + out->cross = FT_MulFix( line_segment.x, nearest_vector.y ) - + FT_MulFix( line_segment.y, nearest_vector.x ); + } + + Exit: + return error; + } + + + /************************************************************************** + * + * @Function: + * get_min_distance_conic + * + * @Description: + * Find the shortest distance from the `conic` Bezier curve to a given + * `point` and assign it to `out`. Use it for conic/quadratic curves + * only. + * + * @Input: + * conic :: + * The conic Bezier curve to which the shortest distance is to be + * computed. + * + * point :: + * Point from which the shortest distance is to be computed. + * + * @Output: + * out :: + * Signed distance from `point` to `conic`. + * + * @Return: + * FreeType error, 0 means success. + * + * @Note: + * The `conic` parameter must have an edge type of `SDF_EDGE_CONIC`. + * + */ + +#if !USE_NEWTON_FOR_CONIC + + /* + * The function uses an analytical method to find the shortest distance + * which is faster than the Newton-Raphson method, but has underflows at + * the moment. Use Newton's method if you can see artifacts in the SDF. + */ + static FT_Error + get_min_distance_conic( SDF_Edge* conic, + FT_26D6_Vec point, + SDF_Signed_Distance* out ) + { + /* + * The procedure to find the shortest distance from a point to a + * quadratic Bezier curve is similar to the line segment algorithm. The + * shortest distance is perpendicular to the Bezier curve; the only + * difference from line is that there can be more than one + * perpendicular, and we also have to check the endpoints, because the + * perpendicular may not be the shortest. + * + * Let's assume that + * ``` + * p0 = first endpoint + * p1 = control point + * p2 = second endpoint + * p = point from which shortest distance is to be calculated + * ``` + * + * (1) The equation of a quadratic Bezier curve can be written as + * + * ``` + * B(t) = (1 - t)^2 * p0 + 2(1 - t)t * p1 + t^2 * p2 + * ``` + * + * with `t` a factor in the range [0.0f, 1.0f]. This equation can + * be rewritten as + * + * ``` + * B(t) = t^2 * (p0 - 2p1 + p2) + 2t * (p1 - p0) + p0 + * ``` + * + * With + * + * ``` + * A = p0 - 2p1 + p2 + * B = p1 - p0 + * ``` + * + * we have + * + * ``` + * B(t) = t^2 * A + 2t * B + p0 + * ``` + * + * (2) The derivative of the last equation above is + * + * ``` + * B'(t) = 2 *(tA + B) + * ``` + * + * (3) To find the shortest distance from `p` to `B(t)` we find the + * point on the curve at which the shortest distance vector (i.e., + * `B(t) - p`) and the direction (i.e., `B'(t)`) make 90 degrees. + * In other words, we make the dot product zero. + * + * ``` + * (B(t) - p) . (B'(t)) = 0 + * (t^2 * A + 2t * B + p0 - p) . (2 * (tA + B)) = 0 + * ``` + * + * After simplifying we get a cubic equation + * + * ``` + * at^3 + bt^2 + ct + d = 0 + * ``` + * + * with + * + * ``` + * a = A.A + * b = 3A.B + * c = 2B.B + A.p0 - A.p + * d = p0.B - p.B + * ``` + * + * (4) Now the roots of the equation can be computed using 'Cardano's + * Cubic formula'; we clamp the roots in the range [0.0f, 1.0f]. + * + * [note]: `B` and `B(t)` are different in the above equations. + */ + + FT_Error error = FT_Err_Ok; + + FT_26D6_Vec aA, bB; /* A, B in the above comment */ + FT_26D6_Vec nearest_point; /* point on curve nearest to `point` */ + FT_26D6_Vec direction; /* direction of curve at `nearest_point` */ + + FT_26D6_Vec p0, p1, p2; /* control points of a conic curve */ + FT_26D6_Vec p; /* `point` to which shortest distance */ + + FT_26D6 a, b, c, d; /* cubic coefficients */ + + FT_16D16 roots[3] = { 0, 0, 0 }; /* real roots of the cubic eq. */ + FT_16D16 min_factor; /* factor at `nearest_point` */ + FT_16D16 cross; /* to determine the sign */ + FT_16D16 min = FT_INT_MAX; /* shortest squared distance */ + + FT_UShort num_roots; /* number of real roots of cubic */ + FT_UShort i; + + + if ( !conic || !out ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( conic->edge_type != SDF_EDGE_CONIC ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + p0 = conic->start_pos; + p1 = conic->control_a; + p2 = conic->end_pos; + p = point; + + /* compute substitution coefficients */ + aA.x = p0.x - 2 * p1.x + p2.x; + aA.y = p0.y - 2 * p1.y + p2.y; + + bB.x = p1.x - p0.x; + bB.y = p1.y - p0.y; + + /* compute cubic coefficients */ + a = VEC_26D6_DOT( aA, aA ); + + b = 3 * VEC_26D6_DOT( aA, bB ); + + c = 2 * VEC_26D6_DOT( bB, bB ) + + VEC_26D6_DOT( aA, p0 ) - + VEC_26D6_DOT( aA, p ); + + d = VEC_26D6_DOT( p0, bB ) - + VEC_26D6_DOT( p, bB ); + + /* find the roots */ + num_roots = solve_cubic_equation( a, b, c, d, roots ); + + if ( num_roots == 0 ) + { + roots[0] = 0; + roots[1] = FT_INT_16D16( 1 ); + num_roots = 2; + } + + /* [OPTIMIZATION]: Check the roots, clamp them and discard */ + /* duplicate roots. */ + + /* convert these values to 16.16 for further computation */ + aA.x = FT_26D6_16D16( aA.x ); + aA.y = FT_26D6_16D16( aA.y ); + + bB.x = FT_26D6_16D16( bB.x ); + bB.y = FT_26D6_16D16( bB.y ); + + p0.x = FT_26D6_16D16( p0.x ); + p0.y = FT_26D6_16D16( p0.y ); + + p.x = FT_26D6_16D16( p.x ); + p.y = FT_26D6_16D16( p.y ); + + for ( i = 0; i < num_roots; i++ ) + { + FT_16D16 t = roots[i]; + FT_16D16 t2 = 0; + FT_16D16 dist = 0; + + FT_16D16_Vec curve_point; + FT_16D16_Vec dist_vector; + + /* + * Ideally we should discard the roots which are outside the range + * [0.0, 1.0] and check the endpoints of the Bezier curve, but Behdad + * Esfahbod proved the following lemma. + * + * Lemma: + * + * (1) If the closest point on the curve [0, 1] is to the endpoint at + * `t` = 1 and the cubic has no real roots at `t` = 1 then the + * cubic must have a real root at some `t` > 1. + * + * (2) Similarly, if the closest point on the curve [0, 1] is to the + * endpoint at `t` = 0 and the cubic has no real roots at `t` = 0 + * then the cubic must have a real root at some `t` < 0. + * + * Now because of this lemma we only need to clamp the roots and that + * will take care of the endpoints. + * + * For more details see + * + * https://lists.nongnu.org/archive/html/freetype-devel/2020-06/msg00147.html + */ + + if ( t < 0 ) + t = 0; + if ( t > FT_INT_16D16( 1 ) ) + t = FT_INT_16D16( 1 ); + + t2 = FT_MulFix( t, t ); + + /* B(t) = t^2 * A + 2t * B + p0 - p */ + curve_point.x = FT_MulFix( aA.x, t2 ) + + 2 * FT_MulFix( bB.x, t ) + p0.x; + curve_point.y = FT_MulFix( aA.y, t2 ) + + 2 * FT_MulFix( bB.y, t ) + p0.y; + + /* `curve_point` - `p` */ + dist_vector.x = curve_point.x - p.x; + dist_vector.y = curve_point.y - p.y; + + dist = VECTOR_LENGTH_16D16( dist_vector ); + + if ( dist < min ) + { + min = dist; + nearest_point = curve_point; + min_factor = t; + } + } + + /* B'(t) = 2 * (tA + B) */ + direction.x = 2 * FT_MulFix( aA.x, min_factor ) + 2 * bB.x; + direction.y = 2 * FT_MulFix( aA.y, min_factor ) + 2 * bB.y; + + /* determine the sign */ + cross = FT_MulFix( nearest_point.x - p.x, direction.y ) - + FT_MulFix( nearest_point.y - p.y, direction.x ); + + /* assign the values */ + out->distance = min; + out->sign = cross < 0 ? 1 : -1; + + if ( min_factor != 0 && min_factor != FT_INT_16D16( 1 ) ) + out->cross = FT_INT_16D16( 1 ); /* the two are perpendicular */ + else + { + /* convert to nearest vector */ + nearest_point.x -= FT_26D6_16D16( p.x ); + nearest_point.y -= FT_26D6_16D16( p.y ); + + /* compute `cross` if not perpendicular */ + FT_Vector_NormLen( &direction ); + FT_Vector_NormLen( &nearest_point ); + + out->cross = FT_MulFix( direction.x, nearest_point.y ) - + FT_MulFix( direction.y, nearest_point.x ); + } + + Exit: + return error; + } + +#else /* USE_NEWTON_FOR_CONIC */ + + /* + * The function uses Newton's approximation to find the shortest distance, + * which is a bit slower than the analytical method but doesn't cause + * underflow. + */ + static FT_Error + get_min_distance_conic( SDF_Edge* conic, + FT_26D6_Vec point, + SDF_Signed_Distance* out ) + { + /* + * This method uses Newton-Raphson's approximation to find the shortest + * distance from a point to a conic curve. It does not involve solving + * any cubic equation, that is why there is no risk of underflow. + * + * Let's assume that + * + * ``` + * p0 = first endpoint + * p1 = control point + * p3 = second endpoint + * p = point from which shortest distance is to be calculated + * ``` + * + * (1) The equation of a quadratic Bezier curve can be written as + * + * ``` + * B(t) = (1 - t)^2 * p0 + 2(1 - t)t * p1 + t^2 * p2 + * ``` + * + * with `t` the factor in the range [0.0f, 1.0f]. The above + * equation can be rewritten as + * + * ``` + * B(t) = t^2 * (p0 - 2p1 + p2) + 2t * (p1 - p0) + p0 + * ``` + * + * With + * + * ``` + * A = p0 - 2p1 + p2 + * B = 2 * (p1 - p0) + * ``` + * + * we have + * + * ``` + * B(t) = t^2 * A + t * B + p0 + * ``` + * + * (2) The derivative of the above equation is + * + * ``` + * B'(t) = 2t * A + B + * ``` + * + * (3) The second derivative of the above equation is + * + * ``` + * B''(t) = 2A + * ``` + * + * (4) The equation `P(t)` of the distance from point `p` to the curve + * can be written as + * + * ``` + * P(t) = t^2 * A + t^2 * B + p0 - p + * ``` + * + * With + * + * ``` + * C = p0 - p + * ``` + * + * we have + * + * ``` + * P(t) = t^2 * A + t * B + C + * ``` + * + * (5) Finally, the equation of the angle between `B(t)` and `P(t)` can + * be written as + * + * ``` + * Q(t) = P(t) . B'(t) + * ``` + * + * (6) Our task is to find a value of `t` such that the above equation + * `Q(t)` becomes zero, this is, the point-to-curve vector makes + * 90~degrees with the curve. We solve this with the Newton-Raphson + * method. + * + * (7) We first assume an arbitary value of factor `t`, which we then + * improve. + * + * ``` + * t := Q(t) / Q'(t) + * ``` + * + * Putting the value of `Q(t)` from the above equation gives + * + * ``` + * t := P(t) . B'(t) / derivative(P(t) . B'(t)) + * t := P(t) . B'(t) / + * (P'(t) . B'(t) + P(t) . B''(t)) + * ``` + * + * Note that `P'(t)` is the same as `B'(t)` because the constant is + * gone due to the derivative. + * + * (8) Finally we get the equation to improve the factor as + * + * ``` + * t := P(t) . B'(t) / + * (B'(t) . B'(t) + P(t) . B''(t)) + * ``` + * + * [note]: `B` and `B(t)` are different in the above equations. + */ + + FT_Error error = FT_Err_Ok; + + FT_26D6_Vec aA, bB, cC; /* A, B, C in the above comment */ + FT_26D6_Vec nearest_point; /* point on curve nearest to `point` */ + FT_26D6_Vec direction; /* direction of curve at `nearest_point` */ + + FT_26D6_Vec p0, p1, p2; /* control points of a conic curve */ + FT_26D6_Vec p; /* `point` to which shortest distance */ + + FT_16D16 min_factor = 0; /* factor at `nearest_point' */ + FT_16D16 cross; /* to determine the sign */ + FT_16D16 min = FT_INT_MAX; /* shortest squared distance */ + + FT_UShort iterations; + FT_UShort steps; + + + if ( !conic || !out ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( conic->edge_type != SDF_EDGE_CONIC ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + p0 = conic->start_pos; + p1 = conic->control_a; + p2 = conic->end_pos; + p = point; + + /* compute substitution coefficients */ + aA.x = p0.x - 2 * p1.x + p2.x; + aA.y = p0.y - 2 * p1.y + p2.y; + + bB.x = 2 * ( p1.x - p0.x ); + bB.y = 2 * ( p1.y - p0.y ); + + cC.x = p0.x; + cC.y = p0.y; + + /* do Newton's iterations */ + for ( iterations = 0; iterations <= MAX_NEWTON_DIVISIONS; iterations++ ) + { + FT_16D16 factor = FT_INT_16D16( iterations ) / MAX_NEWTON_DIVISIONS; + FT_16D16 factor2; + FT_16D16 length; + + FT_16D16_Vec curve_point; /* point on the curve */ + FT_16D16_Vec dist_vector; /* `curve_point` - `p` */ + + FT_26D6_Vec d1; /* first derivative */ + FT_26D6_Vec d2; /* second derivative */ + + FT_16D16 temp1; + FT_16D16 temp2; + + + for ( steps = 0; steps < MAX_NEWTON_STEPS; steps++ ) + { + factor2 = FT_MulFix( factor, factor ); + + /* B(t) = t^2 * A + t * B + p0 */ + curve_point.x = FT_MulFix( aA.x, factor2 ) + + FT_MulFix( bB.x, factor ) + cC.x; + curve_point.y = FT_MulFix( aA.y, factor2 ) + + FT_MulFix( bB.y, factor ) + cC.y; + + /* convert to 16.16 */ + curve_point.x = FT_26D6_16D16( curve_point.x ); + curve_point.y = FT_26D6_16D16( curve_point.y ); + + /* P(t) in the comment */ + dist_vector.x = curve_point.x - FT_26D6_16D16( p.x ); + dist_vector.y = curve_point.y - FT_26D6_16D16( p.y ); + + length = VECTOR_LENGTH_16D16( dist_vector ); + + if ( length < min ) + { + min = length; + min_factor = factor; + nearest_point = curve_point; + } + + /* This is Newton's approximation. */ + /* */ + /* t := P(t) . B'(t) / */ + /* (B'(t) . B'(t) + P(t) . B''(t)) */ + + /* B'(t) = 2tA + B */ + d1.x = FT_MulFix( aA.x, 2 * factor ) + bB.x; + d1.y = FT_MulFix( aA.y, 2 * factor ) + bB.y; + + /* B''(t) = 2A */ + d2.x = 2 * aA.x; + d2.y = 2 * aA.y; + + dist_vector.x /= 1024; + dist_vector.y /= 1024; + + /* temp1 = P(t) . B'(t) */ + temp1 = VEC_26D6_DOT( dist_vector, d1 ); + + /* temp2 = B'(t) . B'(t) + P(t) . B''(t) */ + temp2 = VEC_26D6_DOT( d1, d1 ) + + VEC_26D6_DOT( dist_vector, d2 ); + + factor -= FT_DivFix( temp1, temp2 ); + + if ( factor < 0 || factor > FT_INT_16D16( 1 ) ) + break; + } + } + + /* B'(t) = 2t * A + B */ + direction.x = 2 * FT_MulFix( aA.x, min_factor ) + bB.x; + direction.y = 2 * FT_MulFix( aA.y, min_factor ) + bB.y; + + /* determine the sign */ + cross = FT_MulFix( nearest_point.x - FT_26D6_16D16( p.x ), + direction.y ) - + FT_MulFix( nearest_point.y - FT_26D6_16D16( p.y ), + direction.x ); + + /* assign the values */ + out->distance = min; + out->sign = cross < 0 ? 1 : -1; + + if ( min_factor != 0 && min_factor != FT_INT_16D16( 1 ) ) + out->cross = FT_INT_16D16( 1 ); /* the two are perpendicular */ + else + { + /* convert to nearest vector */ + nearest_point.x -= FT_26D6_16D16( p.x ); + nearest_point.y -= FT_26D6_16D16( p.y ); + + /* compute `cross` if not perpendicular */ + FT_Vector_NormLen( &direction ); + FT_Vector_NormLen( &nearest_point ); + + out->cross = FT_MulFix( direction.x, nearest_point.y ) - + FT_MulFix( direction.y, nearest_point.x ); + } + + Exit: + return error; + } + + +#endif /* USE_NEWTON_FOR_CONIC */ + + + /************************************************************************** + * + * @Function: + * get_min_distance_cubic + * + * @Description: + * Find the shortest distance from the `cubic` Bezier curve to a given + * `point` and assigns it to `out`. Use it for cubic curves only. + * + * @Input: + * cubic :: + * The cubic Bezier curve to which the shortest distance is to be + * computed. + * + * point :: + * Point from which the shortest distance is to be computed. + * + * @Output: + * out :: + * Signed distance from `point` to `cubic`. + * + * @Return: + * FreeType error, 0 means success. + * + * @Note: + * The function uses Newton's approximation to find the shortest + * distance. Another way would be to divide the cubic into conic or + * subdivide the curve into lines, but that is not implemented. + * + * The `cubic` parameter must have an edge type of `SDF_EDGE_CUBIC`. + * + */ + static FT_Error + get_min_distance_cubic( SDF_Edge* cubic, + FT_26D6_Vec point, + SDF_Signed_Distance* out ) + { + /* + * The procedure to find the shortest distance from a point to a cubic + * Bezier curve is similar to quadratic curve algorithm. The only + * difference is that while calculating factor `t`, instead of a cubic + * polynomial equation we have to find the roots of a 5th degree + * polynomial equation. Solving this would require a significant amount + * of time, and still the results may not be accurate. We are thus + * going to directly approximate the value of `t` using the Newton-Raphson + * method. + * + * Let's assume that + * + * ``` + * p0 = first endpoint + * p1 = first control point + * p2 = second control point + * p3 = second endpoint + * p = point from which shortest distance is to be calculated + * ``` + * + * (1) The equation of a cubic Bezier curve can be written as + * + * ``` + * B(t) = (1 - t)^3 * p0 + 3(1 - t)^2 t * p1 + + * 3(1 - t)t^2 * p2 + t^3 * p3 + * ``` + * + * The equation can be expanded and written as + * + * ``` + * B(t) = t^3 * (-p0 + 3p1 - 3p2 + p3) + + * 3t^2 * (p0 - 2p1 + p2) + 3t * (-p0 + p1) + p0 + * ``` + * + * With + * + * ``` + * A = -p0 + 3p1 - 3p2 + p3 + * B = 3(p0 - 2p1 + p2) + * C = 3(-p0 + p1) + * ``` + * + * we have + * + * ``` + * B(t) = t^3 * A + t^2 * B + t * C + p0 + * ``` + * + * (2) The derivative of the above equation is + * + * ``` + * B'(t) = 3t^2 * A + 2t * B + C + * ``` + * + * (3) The second derivative of the above equation is + * + * ``` + * B''(t) = 6t * A + 2B + * ``` + * + * (4) The equation `P(t)` of the distance from point `p` to the curve + * can be written as + * + * ``` + * P(t) = t^3 * A + t^2 * B + t * C + p0 - p + * ``` + * + * With + * + * ``` + * D = p0 - p + * ``` + * + * we have + * + * ``` + * P(t) = t^3 * A + t^2 * B + t * C + D + * ``` + * + * (5) Finally the equation of the angle between `B(t)` and `P(t)` can + * be written as + * + * ``` + * Q(t) = P(t) . B'(t) + * ``` + * + * (6) Our task is to find a value of `t` such that the above equation + * `Q(t)` becomes zero, this is, the point-to-curve vector makes + * 90~degree with curve. We solve this with the Newton-Raphson + * method. + * + * (7) We first assume an arbitary value of factor `t`, which we then + * improve. + * + * ``` + * t := Q(t) / Q'(t) + * ``` + * + * Putting the value of `Q(t)` from the above equation gives + * + * ``` + * t := P(t) . B'(t) / derivative(P(t) . B'(t)) + * t := P(t) . B'(t) / + * (P'(t) . B'(t) + P(t) . B''(t)) + * ``` + * + * Note that `P'(t)` is the same as `B'(t)` because the constant is + * gone due to the derivative. + * + * (8) Finally we get the equation to improve the factor as + * + * ``` + * t := P(t) . B'(t) / + * (B'(t) . B'( t ) + P(t) . B''(t)) + * ``` + * + * [note]: `B` and `B(t)` are different in the above equations. + */ + + FT_Error error = FT_Err_Ok; + + FT_26D6_Vec aA, bB, cC, dD; /* A, B, C in the above comment */ + FT_16D16_Vec nearest_point; /* point on curve nearest to `point` */ + FT_16D16_Vec direction; /* direction of curve at `nearest_point` */ + + FT_26D6_Vec p0, p1, p2, p3; /* control points of a cubic curve */ + FT_26D6_Vec p; /* `point` to which shortest distance */ + + FT_16D16 min_factor = 0; /* factor at shortest distance */ + FT_16D16 min_factor_sq = 0; /* factor at shortest distance */ + FT_16D16 cross; /* to determine the sign */ + FT_16D16 min = FT_INT_MAX; /* shortest distance */ + + FT_UShort iterations; + FT_UShort steps; + + + if ( !cubic || !out ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( cubic->edge_type != SDF_EDGE_CUBIC ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + p0 = cubic->start_pos; + p1 = cubic->control_a; + p2 = cubic->control_b; + p3 = cubic->end_pos; + p = point; + + /* compute substitution coefficients */ + aA.x = -p0.x + 3 * ( p1.x - p2.x ) + p3.x; + aA.y = -p0.y + 3 * ( p1.y - p2.y ) + p3.y; + + bB.x = 3 * ( p0.x - 2 * p1.x + p2.x ); + bB.y = 3 * ( p0.y - 2 * p1.y + p2.y ); + + cC.x = 3 * ( p1.x - p0.x ); + cC.y = 3 * ( p1.y - p0.y ); + + dD.x = p0.x; + dD.y = p0.y; + + for ( iterations = 0; iterations <= MAX_NEWTON_DIVISIONS; iterations++ ) + { + FT_16D16 factor = FT_INT_16D16( iterations ) / MAX_NEWTON_DIVISIONS; + + FT_16D16 factor2; /* factor^2 */ + FT_16D16 factor3; /* factor^3 */ + FT_16D16 length; + + FT_16D16_Vec curve_point; /* point on the curve */ + FT_16D16_Vec dist_vector; /* `curve_point' - `p' */ + + FT_26D6_Vec d1; /* first derivative */ + FT_26D6_Vec d2; /* second derivative */ + + FT_16D16 temp1; + FT_16D16 temp2; + + + for ( steps = 0; steps < MAX_NEWTON_STEPS; steps++ ) + { + factor2 = FT_MulFix( factor, factor ); + factor3 = FT_MulFix( factor2, factor ); + + /* B(t) = t^3 * A + t^2 * B + t * C + D */ + curve_point.x = FT_MulFix( aA.x, factor3 ) + + FT_MulFix( bB.x, factor2 ) + + FT_MulFix( cC.x, factor ) + dD.x; + curve_point.y = FT_MulFix( aA.y, factor3 ) + + FT_MulFix( bB.y, factor2 ) + + FT_MulFix( cC.y, factor ) + dD.y; + + /* convert to 16.16 */ + curve_point.x = FT_26D6_16D16( curve_point.x ); + curve_point.y = FT_26D6_16D16( curve_point.y ); + + /* P(t) in the comment */ + dist_vector.x = curve_point.x - FT_26D6_16D16( p.x ); + dist_vector.y = curve_point.y - FT_26D6_16D16( p.y ); + + length = VECTOR_LENGTH_16D16( dist_vector ); + + if ( length < min ) + { + min = length; + min_factor = factor; + min_factor_sq = factor2; + nearest_point = curve_point; + } + + /* This the Newton's approximation. */ + /* */ + /* t := P(t) . B'(t) / */ + /* (B'(t) . B'(t) + P(t) . B''(t)) */ + + /* B'(t) = 3t^2 * A + 2t * B + C */ + d1.x = FT_MulFix( aA.x, 3 * factor2 ) + + FT_MulFix( bB.x, 2 * factor ) + cC.x; + d1.y = FT_MulFix( aA.y, 3 * factor2 ) + + FT_MulFix( bB.y, 2 * factor ) + cC.y; + + /* B''(t) = 6t * A + 2B */ + d2.x = FT_MulFix( aA.x, 6 * factor ) + 2 * bB.x; + d2.y = FT_MulFix( aA.y, 6 * factor ) + 2 * bB.y; + + dist_vector.x /= 1024; + dist_vector.y /= 1024; + + /* temp1 = P(t) . B'(t) */ + temp1 = VEC_26D6_DOT( dist_vector, d1 ); + + /* temp2 = B'(t) . B'(t) + P(t) . B''(t) */ + temp2 = VEC_26D6_DOT( d1, d1 ) + + VEC_26D6_DOT( dist_vector, d2 ); + + factor -= FT_DivFix( temp1, temp2 ); + + if ( factor < 0 || factor > FT_INT_16D16( 1 ) ) + break; + } + } + + /* B'(t) = 3t^2 * A + 2t * B + C */ + direction.x = FT_MulFix( aA.x, 3 * min_factor_sq ) + + FT_MulFix( bB.x, 2 * min_factor ) + cC.x; + direction.y = FT_MulFix( aA.y, 3 * min_factor_sq ) + + FT_MulFix( bB.y, 2 * min_factor ) + cC.y; + + /* determine the sign */ + cross = FT_MulFix( nearest_point.x - FT_26D6_16D16( p.x ), + direction.y ) - + FT_MulFix( nearest_point.y - FT_26D6_16D16( p.y ), + direction.x ); + + /* assign the values */ + out->distance = min; + out->sign = cross < 0 ? 1 : -1; + + if ( min_factor != 0 && min_factor != FT_INT_16D16( 1 ) ) + out->cross = FT_INT_16D16( 1 ); /* the two are perpendicular */ + else + { + /* convert to nearest vector */ + nearest_point.x -= FT_26D6_16D16( p.x ); + nearest_point.y -= FT_26D6_16D16( p.y ); + + /* compute `cross` if not perpendicular */ + FT_Vector_NormLen( &direction ); + FT_Vector_NormLen( &nearest_point ); + + out->cross = FT_MulFix( direction.x, nearest_point.y ) - + FT_MulFix( direction.y, nearest_point.x ); + } + + Exit: + return error; + } + + + /************************************************************************** + * + * @Function: + * sdf_edge_get_min_distance + * + * @Description: + * Find shortest distance from `point` to any type of `edge`. It checks + * the edge type and then calls the relevant `get_min_distance_*` + * function. + * + * @Input: + * edge :: + * An edge to which the shortest distance is to be computed. + * + * point :: + * Point from which the shortest distance is to be computed. + * + * @Output: + * out :: + * Signed distance from `point` to `edge`. + * + * @Return: + * FreeType error, 0 means success. + * + */ + static FT_Error + sdf_edge_get_min_distance( SDF_Edge* edge, + FT_26D6_Vec point, + SDF_Signed_Distance* out ) + { + FT_Error error = FT_Err_Ok; + + + if ( !edge || !out ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* edge-specific distance calculation */ + switch ( edge->edge_type ) + { + case SDF_EDGE_LINE: + get_min_distance_line( edge, point, out ); + break; + + case SDF_EDGE_CONIC: + get_min_distance_conic( edge, point, out ); + break; + + case SDF_EDGE_CUBIC: + get_min_distance_cubic( edge, point, out ); + break; + + default: + error = FT_THROW( Invalid_Argument ); + } + + Exit: + return error; + } + + + /* `sdf_generate' is not used at the moment */ +#if 0 + + #error "DO NOT USE THIS!" + #error "The function still outputs 16-bit data, which might cause memory" + #error "corruption. If required I will add this later." + + /************************************************************************** + * + * @Function: + * sdf_contour_get_min_distance + * + * @Description: + * Iterate over all edges that make up the contour, find the shortest + * distance from a point to this contour, and assigns result to `out`. + * + * @Input: + * contour :: + * A contour to which the shortest distance is to be computed. + * + * point :: + * Point from which the shortest distance is to be computed. + * + * @Output: + * out :: + * Signed distance from the `point' to the `contour'. + * + * @Return: + * FreeType error, 0 means success. + * + * @Note: + * The function does not return a signed distance for each edge which + * makes up the contour, it simply returns the shortest of all the + * edges. + * + */ + static FT_Error + sdf_contour_get_min_distance( SDF_Contour* contour, + FT_26D6_Vec point, + SDF_Signed_Distance* out ) + { + FT_Error error = FT_Err_Ok; + SDF_Signed_Distance min_dist = max_sdf; + SDF_Edge* edge_list; + + + if ( !contour || !out ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + edge_list = contour->edges; + + /* iterate over all the edges manually */ + while ( edge_list ) + { + SDF_Signed_Distance current_dist = max_sdf; + FT_16D16 diff; + + + FT_CALL( sdf_edge_get_min_distance( edge_list, + point, + ¤t_dist ) ); + + if ( current_dist.distance >= 0 ) + { + diff = current_dist.distance - min_dist.distance; + + + if ( FT_ABS(diff ) < CORNER_CHECK_EPSILON ) + min_dist = resolve_corner( min_dist, current_dist ); + else if ( diff < 0 ) + min_dist = current_dist; + } + else + FT_TRACE0(( "sdf_contour_get_min_distance: Overflow.\n" )); + + edge_list = edge_list->next; + } + + *out = min_dist; + + Exit: + return error; + } + + + /************************************************************************** + * + * @Function: + * sdf_generate + * + * @Description: + * This is the main function that is responsible for generating signed + * distance fields. The function does not align or compute the size of + * `bitmap`; therefore the calling application must set up `bitmap` + * properly and transform the `shape' appropriately in advance. + * + * Currently we check all pixels against all contours and all edges. + * + * @Input: + * internal_params :: + * Internal parameters and properties required by the rasterizer. See + * @SDF_Params for more. + * + * shape :: + * A complete shape which is used to generate SDF. + * + * spread :: + * Maximum distances to be allowed in the output bitmap. + * + * @Output: + * bitmap :: + * The output bitmap which will contain the SDF information. + * + * @Return: + * FreeType error, 0 means success. + * + */ + static FT_Error + sdf_generate( const SDF_Params internal_params, + const SDF_Shape* shape, + FT_UInt spread, + const FT_Bitmap* bitmap ) + { + FT_Error error = FT_Err_Ok; + + FT_UInt width = 0; + FT_UInt rows = 0; + FT_UInt x = 0; /* used to loop in x direction, i.e., width */ + FT_UInt y = 0; /* used to loop in y direction, i.e., rows */ + FT_UInt sp_sq = 0; /* `spread` [* `spread`] as a 16.16 fixed value */ + + FT_Short* buffer; + + + if ( !shape || !bitmap ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( spread < MIN_SPREAD || spread > MAX_SPREAD ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + width = bitmap->width; + rows = bitmap->rows; + buffer = (FT_Short*)bitmap->buffer; + + if ( USE_SQUARED_DISTANCES ) + sp_sq = FT_INT_16D16( spread * spread ); + else + sp_sq = FT_INT_16D16( spread ); + + if ( width == 0 || rows == 0 ) + { + FT_TRACE0(( "sdf_generate:" + " Cannot render glyph with width/height == 0\n" )); + FT_TRACE0(( " " + " (width, height provided [%d, %d])\n", + width, rows )); + + error = FT_THROW( Cannot_Render_Glyph ); + goto Exit; + } + + /* loop over all rows */ + for ( y = 0; y < rows; y++ ) + { + /* loop over all pixels of a row */ + for ( x = 0; x < width; x++ ) + { + /* `grid_point` is the current pixel position; */ + /* our task is to find the shortest distance */ + /* from this point to the entire shape. */ + FT_26D6_Vec grid_point = zero_vector; + SDF_Signed_Distance min_dist = max_sdf; + SDF_Contour* contour_list; + + FT_UInt index; + FT_Short value; + + + grid_point.x = FT_INT_26D6( x ); + grid_point.y = FT_INT_26D6( y ); + + /* This `grid_point' is at the corner, but we */ + /* use the center of the pixel. */ + grid_point.x += FT_INT_26D6( 1 ) / 2; + grid_point.y += FT_INT_26D6( 1 ) / 2; + + contour_list = shape->contours; + + /* iterate over all contours manually */ + while ( contour_list ) + { + SDF_Signed_Distance current_dist = max_sdf; + + + FT_CALL( sdf_contour_get_min_distance( contour_list, + grid_point, + ¤t_dist ) ); + + if ( current_dist.distance < min_dist.distance ) + min_dist = current_dist; + + contour_list = contour_list->next; + } + + /* [OPTIMIZATION]: if (min_dist > sp_sq) then simply clamp */ + /* the value to spread to avoid square_root */ + + /* clamp the values to spread */ + if ( min_dist.distance > sp_sq ) + min_dist.distance = sp_sq; + + /* square_root the values and fit in a 6.10 fixed point */ + if ( USE_SQUARED_DISTANCES ) + min_dist.distance = square_root( min_dist.distance ); + + if ( internal_params.orientation == FT_ORIENTATION_FILL_LEFT ) + min_dist.sign = -min_dist.sign; + if ( internal_params.flip_sign ) + min_dist.sign = -min_dist.sign; + + min_dist.distance /= 64; /* convert from 16.16 to 22.10 */ + + value = min_dist.distance & 0x0000FFFF; /* truncate to 6.10 */ + value *= min_dist.sign; + + if ( internal_params.flip_y ) + index = y * width + x; + else + index = ( rows - y - 1 ) * width + x; + + buffer[index] = value; + } + } + + Exit: + return error; + } + +#endif /* 0 */ + + + /************************************************************************** + * + * @Function: + * sdf_generate_bounding_box + * + * @Description: + * This function does basically the same thing as `sdf_generate` above + * but more efficiently. + * + * Instead of checking all pixels against all edges, we loop over all + * edges and only check pixels around the control box of the edge; the + * control box is increased by the spread in all directions. Anything + * outside of the control box that exceeds `spread` doesn't need to be + * computed. + * + * Lastly, to determine the sign of unchecked pixels, we do a single + * pass of all rows starting with a '+' sign and flipping when we come + * across a '-' sign and continue. This also eliminates the possibility + * of overflow because we only check the proximity of the curve. + * Therefore we can use squared distanced safely. + * + * @Input: + * internal_params :: + * Internal parameters and properties required by the rasterizer. + * See @SDF_Params for more. + * + * shape :: + * A complete shape which is used to generate SDF. + * + * spread :: + * Maximum distances to be allowed in the output bitmap. + * + * @Output: + * bitmap :: + * The output bitmap which will contain the SDF information. + * + * @Return: + * FreeType error, 0 means success. + * + */ + static FT_Error + sdf_generate_bounding_box( const SDF_Params internal_params, + const SDF_Shape* shape, + FT_UInt spread, + const FT_Bitmap* bitmap ) + { + FT_Error error = FT_Err_Ok; + FT_Memory memory = NULL; + + FT_Int width, rows, i, j; + FT_Int sp_sq; /* max value to check */ + + SDF_Contour* contours; /* list of all contours */ + FT_SDFFormat* buffer; /* the bitmap buffer */ + + /* This buffer has the same size in indices as the */ + /* bitmap buffer. When we check a pixel position for */ + /* a shortest distance we keep it in this buffer. */ + /* This way we can find out which pixel is set, */ + /* and also determine the signs properly. */ + SDF_Signed_Distance* dists = NULL; + + const FT_16D16 fixed_spread = FT_INT_16D16( spread ); + + + if ( !shape || !bitmap ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( spread < MIN_SPREAD || spread > MAX_SPREAD ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + memory = shape->memory; + if ( !memory ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( FT_ALLOC( dists, + bitmap->width * bitmap->rows * sizeof ( *dists ) ) ) + goto Exit; + + contours = shape->contours; + width = (FT_Int)bitmap->width; + rows = (FT_Int)bitmap->rows; + buffer = (FT_SDFFormat*)bitmap->buffer; + + if ( USE_SQUARED_DISTANCES ) + sp_sq = fixed_spread * fixed_spread; + else + sp_sq = fixed_spread; + + if ( width == 0 || rows == 0 ) + { + FT_TRACE0(( "sdf_generate:" + " Cannot render glyph with width/height == 0\n" )); + FT_TRACE0(( " " + " (width, height provided [%d, %d])", width, rows )); + + error = FT_THROW( Cannot_Render_Glyph ); + goto Exit; + } + + /* loop over all contours */ + while ( contours ) + { + SDF_Edge* edges = contours->edges; + + + /* loop over all edges */ + while ( edges ) + { + FT_CBox cbox; + FT_Int x, y; + + + /* get the control box and increase it by `spread' */ + cbox = get_control_box( *edges ); + + cbox.xMin = ( cbox.xMin - 63 ) / 64 - ( FT_Pos )spread; + cbox.xMax = ( cbox.xMax + 63 ) / 64 + ( FT_Pos )spread; + cbox.yMin = ( cbox.yMin - 63 ) / 64 - ( FT_Pos )spread; + cbox.yMax = ( cbox.yMax + 63 ) / 64 + ( FT_Pos )spread; + + /* now loop over the pixels in the control box. */ + for ( y = cbox.yMin; y < cbox.yMax; y++ ) + { + for ( x = cbox.xMin; x < cbox.xMax; x++ ) + { + FT_26D6_Vec grid_point = zero_vector; + SDF_Signed_Distance dist = max_sdf; + FT_UInt index = 0; + + + if ( x < 0 || x >= width ) + continue; + if ( y < 0 || y >= rows ) + continue; + + grid_point.x = FT_INT_26D6( x ); + grid_point.y = FT_INT_26D6( y ); + + /* This `grid_point` is at the corner, but we */ + /* use the center of the pixel. */ + grid_point.x += FT_INT_26D6( 1 ) / 2; + grid_point.y += FT_INT_26D6( 1 ) / 2; + + FT_CALL( sdf_edge_get_min_distance( edges, + grid_point, + &dist ) ); + + if ( internal_params.orientation == FT_ORIENTATION_FILL_LEFT ) + dist.sign = -dist.sign; + + /* ignore if the distance is greater than spread; */ + /* otherwise it creates artifacts due to the wrong sign */ + if ( dist.distance > sp_sq ) + continue; + + /* square_root the values and fit in a 6.10 fixed-point */ + if ( USE_SQUARED_DISTANCES ) + dist.distance = square_root( dist.distance ); + + if ( internal_params.flip_y ) + index = (FT_UInt)( y * width + x ); + else + index = (FT_UInt)( ( rows - y - 1 ) * width + x ); + + /* check whether the pixel is set or not */ + if ( dists[index].sign == 0 ) + dists[index] = dist; + else if ( dists[index].distance > dist.distance ) + dists[index] = dist; + else if ( FT_ABS( dists[index].distance - dist.distance ) + < CORNER_CHECK_EPSILON ) + dists[index] = resolve_corner( dists[index], dist ); + } + } + + edges = edges->next; + } + + contours = contours->next; + } + + /* final pass */ + for ( j = 0; j < rows; j++ ) + { + /* We assume the starting pixel of each row is outside. */ + FT_Char current_sign = -1; + FT_UInt index; + + + if ( internal_params.overload_sign != 0 ) + current_sign = internal_params.overload_sign < 0 ? -1 : 1; + + for ( i = 0; i < width; i++ ) + { + index = (FT_UInt)( j * width + i ); + + /* if the pixel is not set */ + /* its shortest distance is more than `spread` */ + if ( dists[index].sign == 0 ) + dists[index].distance = fixed_spread; + else + current_sign = dists[index].sign; + + /* clamp the values */ + if ( dists[index].distance > fixed_spread ) + dists[index].distance = fixed_spread; + + /* flip sign if required */ + dists[index].distance *= internal_params.flip_sign ? -current_sign + : current_sign; + + /* concatenate to appropriate format */ + buffer[index] = map_fixed_to_sdf( dists[index].distance, + fixed_spread ); + } + } + + Exit: + FT_FREE( dists ); + return error; + } + + + /************************************************************************** + * + * @Function: + * sdf_generate_subdivision + * + * @Description: + * Subdivide the shape into a number of straight lines, then use the + * above `sdf_generate_bounding_box` function to generate the SDF. + * + * Note: After calling this function `shape` no longer has the original + * edges, it only contains lines. + * + * @Input: + * internal_params :: + * Internal parameters and properties required by the rasterizer. + * See @SDF_Params for more. + * + * shape :: + * A complete shape which is used to generate SDF. + * + * spread :: + * Maximum distances to be allowed inthe output bitmap. + * + * @Output: + * bitmap :: + * The output bitmap which will contain the SDF information. + * + * @Return: + * FreeType error, 0 means success. + * + */ + static FT_Error + sdf_generate_subdivision( const SDF_Params internal_params, + SDF_Shape* shape, + FT_UInt spread, + const FT_Bitmap* bitmap ) + { + /* + * Thanks to Alexei for providing the idea of this optimization. + * + * We take advantage of two facts. + * + * (1) Computing the shortest distance from a point to a line segment is + * very fast. + * (2) We don't have to compute the shortest distance for the entire + * two-dimensional grid. + * + * Both ideas lead to the following optimization. + * + * (1) Split the outlines into a number of line segments. + * + * (2) For each line segment, only process its neighborhood. + * + * (3) Compute the closest distance to the line only for neighborhood + * grid points. + * + * This greatly reduces the number of grid points to check. + */ + + FT_Error error = FT_Err_Ok; + + + FT_CALL( split_sdf_shape( shape ) ); + FT_CALL( sdf_generate_bounding_box( internal_params, + shape, spread, bitmap ) ); + + Exit: + return error; + } + + + /************************************************************************** + * + * @Function: + * sdf_generate_with_overlaps + * + * @Description: + * This function can be used to generate SDF for glyphs with overlapping + * contours. The function generates SDF for contours separately on + * separate bitmaps (to generate SDF it uses + * `sdf_generate_subdivision`). At the end it simply combines all the + * SDF into the output bitmap; this fixes all the signs and removes + * overlaps. + * + * @Input: + * internal_params :: + * Internal parameters and properties required by the rasterizer. See + * @SDF_Params for more. + * + * shape :: + * A complete shape which is used to generate SDF. + * + * spread :: + * Maximum distances to be allowed in the output bitmap. + * + * @Output: + * bitmap :: + * The output bitmap which will contain the SDF information. + * + * @Return: + * FreeType error, 0 means success. + * + * @Note: + * The function cannot generate a proper SDF for glyphs with + * self-intersecting contours because we cannot separate them into two + * separate bitmaps. In case of self-intersecting contours it is + * necessary to remove the overlaps before generating the SDF. + * + */ + static FT_Error + sdf_generate_with_overlaps( SDF_Params internal_params, + SDF_Shape* shape, + FT_UInt spread, + const FT_Bitmap* bitmap ) + { + FT_Error error = FT_Err_Ok; + + FT_Int num_contours; /* total number of contours */ + FT_Int i, j; /* iterators */ + FT_Int width, rows; /* width and rows of the bitmap */ + FT_Bitmap* bitmaps; /* separate bitmaps for contours */ + + SDF_Contour* contour; /* temporary variable to iterate */ + SDF_Contour* temp_contour; /* temporary contour */ + SDF_Contour* head; /* head of the contour list */ + SDF_Shape temp_shape; /* temporary shape */ + + FT_Memory memory; /* to allocate memory */ + FT_SDFFormat* t; /* target bitmap buffer */ + FT_Bool flip_sign; /* flip sign? */ + + /* orientation of all the separate contours */ + SDF_Contour_Orientation* orientations; + + + bitmaps = NULL; + orientations = NULL; + head = NULL; + + if ( !shape || !bitmap || !shape->memory ) + return FT_THROW( Invalid_Argument ); + + /* Disable `flip_sign` to avoid extra complication */ + /* during the combination phase. */ + flip_sign = internal_params.flip_sign; + internal_params.flip_sign = 0; + + contour = shape->contours; + memory = shape->memory; + temp_shape.memory = memory; + width = (FT_Int)bitmap->width; + rows = (FT_Int)bitmap->rows; + num_contours = 0; + + /* find the number of contours in the shape */ + while ( contour ) + { + num_contours++; + contour = contour->next; + } + + /* allocate the bitmaps to generate SDF for separate contours */ + if ( FT_ALLOC( bitmaps, + (FT_UInt)num_contours * sizeof ( *bitmaps ) ) ) + goto Exit; + + /* allocate array to hold orientation for all contours */ + if ( FT_ALLOC( orientations, + (FT_UInt)num_contours * sizeof ( *orientations ) ) ) + goto Exit; + + contour = shape->contours; + + /* Iterate over all contours and generate SDF separately. */ + for ( i = 0; i < num_contours; i++ ) + { + /* initialize the corresponding bitmap */ + FT_Bitmap_Init( &bitmaps[i] ); + + bitmaps[i].width = bitmap->width; + bitmaps[i].rows = bitmap->rows; + bitmaps[i].pitch = bitmap->pitch; + bitmaps[i].num_grays = bitmap->num_grays; + bitmaps[i].pixel_mode = bitmap->pixel_mode; + + /* allocate memory for the buffer */ + if ( FT_ALLOC( bitmaps[i].buffer, + bitmap->rows * (FT_UInt)bitmap->pitch ) ) + goto Exit; + + /* determine the orientation */ + orientations[i] = get_contour_orientation( contour ); + + /* The `overload_sign` property is specific to */ + /* `sdf_generate_bounding_box`. This basically */ + /* overloads the default sign of the outside */ + /* pixels, which is necessary for */ + /* counter-clockwise contours. */ + if ( orientations[i] == SDF_ORIENTATION_CCW && + internal_params.orientation == FT_ORIENTATION_FILL_RIGHT ) + internal_params.overload_sign = 1; + else if ( orientations[i] == SDF_ORIENTATION_CW && + internal_params.orientation == FT_ORIENTATION_FILL_LEFT ) + internal_params.overload_sign = 1; + else + internal_params.overload_sign = 0; + + /* Make `contour->next` NULL so that there is */ + /* one contour in the list. Also hold the next */ + /* contour in a temporary variable so as to */ + /* restore the original value. */ + temp_contour = contour->next; + contour->next = NULL; + + /* Use `temp_shape` to hold the new contour. */ + /* Now, `temp_shape` has only one contour. */ + temp_shape.contours = contour; + + /* finally generate the SDF */ + FT_CALL( sdf_generate_subdivision( internal_params, + &temp_shape, + spread, + &bitmaps[i] ) ); + + /* Restore the original `next` variable. */ + contour->next = temp_contour; + + /* Since `split_sdf_shape` deallocated the original */ + /* contours list we need to assign the new value to */ + /* the shape's contour. */ + temp_shape.contours->next = head; + head = temp_shape.contours; + + /* Simply flip the orientation in case of post-script fonts */ + /* so as to avoid modificatons in the combining phase. */ + if ( internal_params.orientation == FT_ORIENTATION_FILL_LEFT ) + { + if ( orientations[i] == SDF_ORIENTATION_CW ) + orientations[i] = SDF_ORIENTATION_CCW; + else if ( orientations[i] == SDF_ORIENTATION_CCW ) + orientations[i] = SDF_ORIENTATION_CW; + } + + contour = contour->next; + } + + /* assign the new contour list to `shape->contours` */ + shape->contours = head; + + /* cast the output bitmap buffer */ + t = (FT_SDFFormat*)bitmap->buffer; + + /* Iterate over all pixels and combine all separate */ + /* contours. These are the rules for combining: */ + /* */ + /* (1) For all clockwise contours, compute the largest */ + /* value. Name this as `val_c`. */ + /* (2) For all counter-clockwise contours, compute the */ + /* smallest value. Name this as `val_ac`. */ + /* (3) Now, finally use the smaller value of `val_c' */ + /* and `val_ac'. */ + for ( j = 0; j < rows; j++ ) + { + for ( i = 0; i < width; i++ ) + { + FT_Int id = j * width + i; /* index of current pixel */ + FT_Int c; /* contour iterator */ + + FT_SDFFormat val_c = 0; /* max clockwise value */ + FT_SDFFormat val_ac = UCHAR_MAX; /* min counter-clockwise val */ + + + /* iterate through all the contours */ + for ( c = 0; c < num_contours; c++ ) + { + /* current contour value */ + FT_SDFFormat temp = ( (FT_SDFFormat*)bitmaps[c].buffer )[id]; + + + if ( orientations[c] == SDF_ORIENTATION_CW ) + val_c = FT_MAX( val_c, temp ); /* clockwise */ + else + val_ac = FT_MIN( val_ac, temp ); /* counter-clockwise */ + } + + /* Finally find the smaller of the two and assign to output. */ + /* Also apply `flip_sign` if set. */ + t[id] = FT_MIN( val_c, val_ac ); + + if ( flip_sign ) + t[id] = invert_sign( t[id] ); + } + } + + Exit: + /* deallocate orientations array */ + if ( orientations ) + FT_FREE( orientations ); + + /* deallocate temporary bitmaps */ + if ( bitmaps ) + { + if ( num_contours == 0 ) + error = FT_THROW( Raster_Corrupted ); + else + { + for ( i = 0; i < num_contours; i++ ) + FT_FREE( bitmaps[i].buffer ); + + FT_FREE( bitmaps ); + } + } + + /* restore the `flip_sign` property */ + internal_params.flip_sign = flip_sign; + + return error; + } + + + /************************************************************************** + * + * interface functions + * + */ + + static FT_Error + sdf_raster_new( FT_Memory memory, + SDF_PRaster* araster ) + { + FT_Error error; + SDF_PRaster raster = NULL; + + + if ( !FT_NEW( raster ) ) + raster->memory = memory; + + *araster = raster; + + return error; + } + + + static void + sdf_raster_reset( FT_Raster raster, + unsigned char* pool_base, + unsigned long pool_size ) + { + FT_UNUSED( raster ); + FT_UNUSED( pool_base ); + FT_UNUSED( pool_size ); + } + + + static FT_Error + sdf_raster_set_mode( FT_Raster raster, + unsigned long mode, + void* args ) + { + FT_UNUSED( raster ); + FT_UNUSED( mode ); + FT_UNUSED( args ); + + return FT_Err_Ok; + } + + + static FT_Error + sdf_raster_render( FT_Raster raster, + const FT_Raster_Params* params ) + { + FT_Error error = FT_Err_Ok; + SDF_TRaster* sdf_raster = (SDF_TRaster*)raster; + FT_Outline* outline = NULL; + const SDF_Raster_Params* sdf_params = (const SDF_Raster_Params*)params; + + FT_Memory memory = NULL; + SDF_Shape* shape = NULL; + SDF_Params internal_params; + + + /* check for valid arguments */ + if ( !sdf_raster || !sdf_params ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + outline = (FT_Outline*)sdf_params->root.source; + + /* check whether outline is valid */ + if ( !outline ) + { + error = FT_THROW( Invalid_Outline ); + goto Exit; + } + + /* if the outline is empty, return */ + if ( outline->n_points <= 0 || outline->n_contours <= 0 ) + goto Exit; + + /* check whether the outline has valid fields */ + if ( !outline->contours || !outline->points ) + { + error = FT_THROW( Invalid_Outline ); + goto Exit; + } + + /* check whether spread is set properly */ + if ( sdf_params->spread > MAX_SPREAD || + sdf_params->spread < MIN_SPREAD ) + { + FT_TRACE0(( "sdf_raster_render:" + " The `spread' field of `SDF_Raster_Params' is invalid,\n" )); + FT_TRACE0(( " " + " the value of this field must be within [%d, %d].\n", + MIN_SPREAD, MAX_SPREAD )); + FT_TRACE0(( " " + " Also, you must pass `SDF_Raster_Params' instead of\n" )); + FT_TRACE0(( " " + " the default `FT_Raster_Params' while calling\n" )); + FT_TRACE0(( " " + " this function and set the fields properly.\n" )); + + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + memory = sdf_raster->memory; + if ( !memory ) + { + FT_TRACE0(( "sdf_raster_render:" + " Raster not setup properly,\n" )); + FT_TRACE0(( " " + " unable to find memory handle.\n" )); + + error = FT_THROW( Invalid_Handle ); + goto Exit; + } + + /* set up the parameters */ + internal_params.orientation = FT_Outline_Get_Orientation( outline ); + internal_params.flip_sign = sdf_params->flip_sign; + internal_params.flip_y = sdf_params->flip_y; + internal_params.overload_sign = 0; + + FT_CALL( sdf_shape_new( memory, &shape ) ); + + FT_CALL( sdf_outline_decompose( outline, shape ) ); + + if ( sdf_params->overlaps ) + FT_CALL( sdf_generate_with_overlaps( internal_params, + shape, sdf_params->spread, + sdf_params->root.target ) ); + else + FT_CALL( sdf_generate_subdivision( internal_params, + shape, sdf_params->spread, + sdf_params->root.target ) ); + + if ( shape ) + sdf_shape_done( &shape ); + + Exit: + return error; + } + + + static void + sdf_raster_done( FT_Raster raster ) + { + FT_Memory memory = (FT_Memory)((SDF_TRaster*)raster)->memory; + + + FT_FREE( raster ); + } + + + FT_DEFINE_RASTER_FUNCS( + ft_sdf_raster, + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Raster_New_Func) sdf_raster_new, /* raster_new */ + (FT_Raster_Reset_Func) sdf_raster_reset, /* raster_reset */ + (FT_Raster_Set_Mode_Func)sdf_raster_set_mode, /* raster_set_mode */ + (FT_Raster_Render_Func) sdf_raster_render, /* raster_render */ + (FT_Raster_Done_Func) sdf_raster_done /* raster_done */ + ) + + +/* END */ diff --git a/thirdparty/freetype/src/sdf/ftsdf.h b/thirdparty/freetype/src/sdf/ftsdf.h new file mode 100644 index 0000000000..187b418af3 --- /dev/null +++ b/thirdparty/freetype/src/sdf/ftsdf.h @@ -0,0 +1,97 @@ +/**************************************************************************** + * + * ftsdf.h + * + * Signed Distance Field support (specification). + * + * Copyright (C) 2020-2021 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Written by Anuj Verma. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#ifndef FTSDF_H_ +#define FTSDF_H_ + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include <freetype/ftimage.h> + +/* common properties and function */ +#include "ftsdfcommon.h" + +FT_BEGIN_HEADER + + /************************************************************************** + * + * @struct: + * SDF_Raster_Params + * + * @description: + * This struct must be passed to the raster render function + * @FT_Raster_RenderFunc instead of @FT_Raster_Params because the + * rasterizer requires some additional information to render properly. + * + * @fields: + * root :: + * The native raster parameters structure. + * + * spread :: + * This is an essential parameter/property required by the renderer. + * `spread` defines the maximum unsigned value that is present in the + * final SDF output. For the default value check file + * `ftsdfcommon.h`. + * + * flip_sign :: + * By default positive values indicate positions inside of contours, + * i.e., filled by a contour. If this property is true then that + * output will be the opposite of the default, i.e., negative values + * indicate positions inside of contours. + * + * flip_y :: + * Setting this parameter to true maked the output image flipped + * along the y-axis. + * + * overlaps :: + * Set this to true to generate SDF for glyphs having overlapping + * contours. The overlapping support is limited to glyphs that do not + * have self-intersecting contours. Also, removing overlaps require a + * considerable amount of extra memory; additionally, it will not work + * if generating SDF from bitmap. + * + * @note: + * All properties are valid for both the 'sdf' and 'bsdf' renderers; the + * exception is `overlaps`, which gets ignored by the 'bsdf' renderer. + * + */ + typedef struct SDF_Raster_Params_ + { + FT_Raster_Params root; + FT_UInt spread; + FT_Bool flip_sign; + FT_Bool flip_y; + FT_Bool overlaps; + + } SDF_Raster_Params; + + + /* rasterizer to convert outline to SDF */ + FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_sdf_raster; + + /* rasterizer to convert bitmap to SDF */ + FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_bitmap_sdf_raster; + +FT_END_HEADER + +#endif /* FTSDF_H_ */ + + +/* END */ diff --git a/thirdparty/freetype/src/sdf/ftsdfcommon.c b/thirdparty/freetype/src/sdf/ftsdfcommon.c new file mode 100644 index 0000000000..91aa521bb3 --- /dev/null +++ b/thirdparty/freetype/src/sdf/ftsdfcommon.c @@ -0,0 +1,147 @@ +/**************************************************************************** + * + * ftsdfcommon.c + * + * Auxiliary data for Signed Distance Field support (body). + * + * Copyright (C) 2020-2021 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Written by Anuj Verma. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#include "ftsdf.h" +#include "ftsdfcommon.h" + + + /************************************************************************** + * + * common functions + * + */ + + /* + * Original algorithm: + * + * https://github.com/chmike/fpsqrt + * + * Use this to compute the square root of a 16.16 fixed point number. + */ + FT_LOCAL_DEF( FT_16D16 ) + square_root( FT_16D16 val ) + { + FT_ULong t, q, b, r; + + + r = (FT_ULong)val; + b = 0x40000000L; + q = 0; + + while ( b > 0x40L ) + { + t = q + b; + + if ( r >= t ) + { + r -= t; + q = t + b; + } + + r <<= 1; + b >>= 1; + } + + q >>= 8; + + return (FT_16D16)q; + } + + + /************************************************************************** + * + * format and sign manipulating functions + * + */ + + /* + * Convert 16.16 fixed point values to the desired output format. + * In this case we reduce 16.16 fixed point values to normalized + * 8-bit values. + * + * The `max_value` in the parameter is the maximum value in the + * distance field map and is equal to the spread. We normalize + * the distances using this value instead of computing the maximum + * value for the entire bitmap. + * + * You can use this function to map the 16.16 signed values to any + * format required. Do note that the output buffer is 8-bit, so only + * use an 8-bit format for `FT_SDFFormat`, or increase the buffer size in + * `ftsdfrend.c`. + */ + FT_LOCAL_DEF( FT_SDFFormat ) + map_fixed_to_sdf( FT_16D16 dist, + FT_16D16 max_value ) + { + FT_SDFFormat out; + FT_16D16 udist; + + + /* normalize the distance values */ + dist = FT_DivFix( dist, max_value ); + + udist = dist < 0 ? -dist : dist; + + /* Reduce the distance values to 8 bits. */ + /* */ + /* Since +1/-1 in 16.16 takes the 16th bit, we right-shift */ + /* the number by 9 to make it fit into the 7-bit range. */ + /* */ + /* One bit is reserved for the sign. */ + udist >>= 9; + + /* Since `char` can only store a maximum positive value */ + /* of 127 we need to make sure it does not wrap around and */ + /* give a negative value. */ + if ( dist > 0 && udist > 127 ) + udist = 127; + if ( dist < 0 && udist > 128 ) + udist = 128; + + /* Output the data; negative values are from [0, 127] and positive */ + /* from [128, 255]. One important thing is that negative values */ + /* are inverted here, that means [0, 128] maps to [-128, 0] linearly. */ + /* More on that in `freetype.h` near the documentation of */ + /* `FT_RENDER_MODE_SDF`. */ + out = dist < 0 ? 128 - (FT_SDFFormat)udist + : (FT_SDFFormat)udist + 128; + + return out; + } + + + /* + * Invert the signed distance packed into the corresponding format. + * So if the values are negative they will become positive in the + * chosen format. + * + * [Note]: This function should only be used after converting the + * 16.16 signed distance values to `FT_SDFFormat`. If that + * conversion has not been done, then simply invert the sign + * and use the above function to pack the values. + */ + FT_LOCAL_DEF( FT_SDFFormat ) + invert_sign( FT_SDFFormat dist ) + { + return 255 - dist; + } + + +/* END */ diff --git a/thirdparty/freetype/src/sdf/ftsdfcommon.h b/thirdparty/freetype/src/sdf/ftsdfcommon.h new file mode 100644 index 0000000000..44f6bba53f --- /dev/null +++ b/thirdparty/freetype/src/sdf/ftsdfcommon.h @@ -0,0 +1,139 @@ +/**************************************************************************** + * + * ftsdfcommon.h + * + * Auxiliary data for Signed Distance Field support (specification). + * + * Copyright (C) 2020-2021 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Written by Anuj Verma. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /**************************************************** + * + * This file contains common functions and properties + * for both the 'sdf' and 'bsdf' renderers. + * + */ + +#ifndef FTSDFCOMMON_H_ +#define FTSDFCOMMON_H_ + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include <freetype/internal/ftobjs.h> + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * default values (cannot be set individually for each renderer) + * + */ + + /* default spread value */ +#define DEFAULT_SPREAD 8 + /* minimum spread supported by the renderer */ +#define MIN_SPREAD 2 + /* maximum spread supported by the renderer */ +#define MAX_SPREAD 32 + + + /************************************************************************** + * + * common definitions (cannot be set individually for each renderer) + * + */ + + /* If this macro is set to 1 the rasterizer uses squared distances for */ + /* computation. It can greatly improve the performance but there is a */ + /* chance of overflow and artifacts. You can safely use it up to a */ + /* pixel size of 128. */ +#ifndef USE_SQUARED_DISTANCES +#define USE_SQUARED_DISTANCES 0 +#endif + + + /************************************************************************** + * + * common macros + * + */ + + /* convert int to 26.6 fixed-point */ +#define FT_INT_26D6( x ) ( x * 64 ) + /* convert int to 16.16 fixed-point */ +#define FT_INT_16D16( x ) ( x * 65536 ) + /* convert 26.6 to 16.16 fixed-point */ +#define FT_26D6_16D16( x ) ( x * 1024 ) + + + /* Convenience macro to call a function; it */ + /* jumps to label `Exit` if an error occurs. */ +#define FT_CALL( x ) do \ + { \ + error = ( x ); \ + if ( error != FT_Err_Ok ) \ + goto Exit; \ + } while ( 0 ) + + + /* + * The macro `VECTOR_LENGTH_16D16` computes either squared distances or + * actual distances, depending on the value of `USE_SQUARED_DISTANCES`. + * + * By using squared distances the performance can be greatly improved but + * there is a risk of overflow. + */ +#if USE_SQUARED_DISTANCES +#define VECTOR_LENGTH_16D16( v ) ( FT_MulFix( v.x, v.x ) + \ + FT_MulFix( v.y, v.y ) ) +#else +#define VECTOR_LENGTH_16D16( v ) FT_Vector_Length( &v ) +#endif + + + /************************************************************************** + * + * common typedefs + * + */ + + typedef FT_Vector FT_26D6_Vec; /* with 26.6 fixed-point components */ + typedef FT_Vector FT_16D16_Vec; /* with 16.16 fixed-point components */ + + typedef FT_Fixed FT_16D16; /* 16.16 fixed-point representation */ + typedef FT_Fixed FT_26D6; /* 26.6 fixed-point representation */ + typedef FT_Byte FT_SDFFormat; /* format to represent SDF data */ + + typedef FT_BBox FT_CBox; /* control box of a curve */ + + + FT_LOCAL( FT_16D16 ) + square_root( FT_16D16 val ); + + FT_LOCAL( FT_SDFFormat ) + map_fixed_to_sdf( FT_16D16 dist, + FT_16D16 max_value ); + + FT_LOCAL( FT_SDFFormat ) + invert_sign( FT_SDFFormat dist ); + + +FT_END_HEADER + +#endif /* FTSDFCOMMON_H_ */ + + +/* END */ diff --git a/thirdparty/freetype/src/sdf/ftsdferrs.h b/thirdparty/freetype/src/sdf/ftsdferrs.h new file mode 100644 index 0000000000..dbb113d537 --- /dev/null +++ b/thirdparty/freetype/src/sdf/ftsdferrs.h @@ -0,0 +1,37 @@ +/**************************************************************************** + * + * ftsdferrs.h + * + * Signed Distance Field error codes (specification only). + * + * Copyright (C) 2020-2021 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Written by Anuj Verma. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#ifndef FTSDFERRS_H_ +#define FTSDFERRS_H_ + +#include <freetype/ftmoderr.h> + +#undef FTERRORS_H_ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX Sdf_Err_ +#define FT_ERR_BASE FT_Mod_Err_Sdf + +#include <freetype/fterrors.h> + +#endif /* FTSDFERRS_H_ */ + + +/* END */ diff --git a/thirdparty/freetype/src/sdf/ftsdfrend.c b/thirdparty/freetype/src/sdf/ftsdfrend.c new file mode 100644 index 0000000000..30f2e62a4f --- /dev/null +++ b/thirdparty/freetype/src/sdf/ftsdfrend.c @@ -0,0 +1,614 @@ +/**************************************************************************** + * + * ftsdfrend.c + * + * Signed Distance Field renderer interface (body). + * + * Copyright (C) 2020-2021 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Written by Anuj Verma. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#include <freetype/internal/ftdebug.h> +#include <freetype/internal/ftobjs.h> +#include <freetype/internal/services/svprop.h> +#include <freetype/ftoutln.h> +#include <freetype/ftbitmap.h> +#include "ftsdfrend.h" +#include "ftsdf.h" + +#include "ftsdferrs.h" + + + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ +#undef FT_COMPONENT +#define FT_COMPONENT sdf + + + /************************************************************************** + * + * macros and default property values + * + */ +#define SDF_RENDERER( rend ) ( (SDF_Renderer)rend ) + + + /************************************************************************** + * + * for setting properties + * + */ + + /* property setter function */ + static FT_Error + sdf_property_set( FT_Module module, + const char* property_name, + const void* value, + FT_Bool value_is_string ) + { + FT_Error error = FT_Err_Ok; + SDF_Renderer render = SDF_RENDERER( FT_RENDERER( module ) ); + + FT_UNUSED( value_is_string ); + + + if ( ft_strcmp( property_name, "spread" ) == 0 ) + { + FT_Int val = *(const FT_Int*)value; + + + if ( val > MAX_SPREAD || val < MIN_SPREAD ) + { + FT_TRACE0(( "[sdf] sdf_property_set:" + " the `spread' property can have a value\n" )); + FT_TRACE0(( " " + " within range [%d, %d] (value provided: %d)\n", + MIN_SPREAD, MAX_SPREAD, val )); + + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + render->spread = (FT_UInt)val; + FT_TRACE7(( "[sdf] sdf_property_set:" + " updated property `spread' to %d\n", val )); + } + + else if ( ft_strcmp( property_name, "flip_sign" ) == 0 ) + { + FT_Int val = *(const FT_Int*)value; + + + render->flip_sign = val ? 1 : 0; + FT_TRACE7(( "[sdf] sdf_property_set:" + " updated property `flip_sign' to %d\n", val )); + } + + else if ( ft_strcmp( property_name, "flip_y" ) == 0 ) + { + FT_Int val = *(const FT_Int*)value; + + + render->flip_y = val ? 1 : 0; + FT_TRACE7(( "[sdf] sdf_property_set:" + " updated property `flip_y' to %d\n", val )); + } + + else if ( ft_strcmp( property_name, "overlaps" ) == 0 ) + { + FT_Bool val = *(const FT_Bool*)value; + + + render->overlaps = val; + FT_TRACE7(( "[sdf] sdf_property_set:" + " updated property `overlaps' to %d\n", val )); + } + + else + { + FT_TRACE0(( "[sdf] sdf_property_set:" + " missing property `%s'\n", property_name )); + error = FT_THROW( Missing_Property ); + } + + Exit: + return error; + } + + + /* property getter function */ + static FT_Error + sdf_property_get( FT_Module module, + const char* property_name, + void* value ) + { + FT_Error error = FT_Err_Ok; + SDF_Renderer render = SDF_RENDERER( FT_RENDERER( module ) ); + + + if ( ft_strcmp( property_name, "spread" ) == 0 ) + { + FT_UInt* val = (FT_UInt*)value; + + + *val = render->spread; + } + + else if ( ft_strcmp( property_name, "flip_sign" ) == 0 ) + { + FT_Int* val = (FT_Int*)value; + + + *val = render->flip_sign; + } + + else if ( ft_strcmp( property_name, "flip_y" ) == 0 ) + { + FT_Int* val = (FT_Int*)value; + + + *val = render->flip_y; + } + + else if ( ft_strcmp( property_name, "overlaps" ) == 0 ) + { + FT_Int* val = (FT_Int*)value; + + + *val = render->overlaps; + } + + else + { + FT_TRACE0(( "[sdf] sdf_property_get:" + " missing property `%s'\n", property_name )); + error = FT_THROW( Missing_Property ); + } + + return error; + } + + + FT_DEFINE_SERVICE_PROPERTIESREC( + sdf_service_properties, + + (FT_Properties_SetFunc)sdf_property_set, /* set_property */ + (FT_Properties_GetFunc)sdf_property_get ) /* get_property */ + + + FT_DEFINE_SERVICEDESCREC1( + sdf_services, + + FT_SERVICE_ID_PROPERTIES, &sdf_service_properties ) + + + static FT_Module_Interface + ft_sdf_requester( FT_Renderer render, + const char* module_interface ) + { + FT_UNUSED( render ); + + return ft_service_list_lookup( sdf_services, module_interface ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** OUTLINE TO SDF CONVERTER **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + /************************************************************************** + * + * interface functions + * + */ + + static FT_Error + ft_sdf_init( FT_Renderer render ) + { + SDF_Renderer sdf_render = SDF_RENDERER( render ); + + + sdf_render->spread = DEFAULT_SPREAD; + sdf_render->flip_sign = 0; + sdf_render->flip_y = 0; + sdf_render->overlaps = 0; + + return FT_Err_Ok; + } + + + static void + ft_sdf_done( FT_Renderer render ) + { + FT_UNUSED( render ); + } + + + /* generate signed distance field from a glyph's slot image */ + static FT_Error + ft_sdf_render( FT_Renderer module, + FT_GlyphSlot slot, + FT_Render_Mode mode, + const FT_Vector* origin ) + { + FT_Error error = FT_Err_Ok; + FT_Outline* outline = &slot->outline; + FT_Bitmap* bitmap = &slot->bitmap; + FT_Memory memory = NULL; + FT_Renderer render = NULL; + + FT_Pos x_shift = 0; + FT_Pos y_shift = 0; + + FT_Pos x_pad = 0; + FT_Pos y_pad = 0; + + SDF_Raster_Params params; + SDF_Renderer sdf_module = SDF_RENDERER( module ); + + + render = &sdf_module->root; + memory = render->root.memory; + + /* check whether slot format is correct before rendering */ + if ( slot->format != render->glyph_format ) + { + error = FT_THROW( Invalid_Glyph_Format ); + goto Exit; + } + + /* check whether render mode is correct */ + if ( mode != FT_RENDER_MODE_SDF ) + { + error = FT_THROW( Cannot_Render_Glyph ); + goto Exit; + } + + /* deallocate the previously allocated bitmap */ + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + { + FT_FREE( bitmap->buffer ); + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + + /* preset the bitmap using the glyph's outline; */ + /* the sdf bitmap is similar to an anti-aliased bitmap */ + /* with a slightly bigger size and different pixel mode */ + if ( ft_glyphslot_preset_bitmap( slot, FT_RENDER_MODE_NORMAL, origin ) ) + { + error = FT_THROW( Raster_Overflow ); + goto Exit; + } + + /* the rows and pitch must be valid after presetting the */ + /* bitmap using outline */ + if ( !bitmap->rows || !bitmap->pitch ) + { + FT_ERROR(( "ft_sdf_render: failed to preset bitmap\n" )); + + error = FT_THROW( Cannot_Render_Glyph ); + goto Exit; + } + + /* the padding will simply be equal to the `spread' */ + x_pad = sdf_module->spread; + y_pad = sdf_module->spread; + + /* apply the padding; will be in all the directions */ + bitmap->rows += y_pad * 2; + bitmap->width += x_pad * 2; + + /* ignore the pitch, pixel mode and set custom */ + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; + bitmap->pitch = (int)( bitmap->width ); + bitmap->num_grays = 255; + + /* allocate new buffer */ + if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) ) + goto Exit; + + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + + slot->bitmap_top += y_pad; + slot->bitmap_left -= x_pad; + + x_shift = 64 * -slot->bitmap_left; + y_shift = 64 * -slot->bitmap_top; + y_shift += 64 * (FT_Int)bitmap->rows; + + if ( origin ) + { + x_shift += origin->x; + y_shift += origin->y; + } + + /* translate outline to render it into the bitmap */ + if ( x_shift || y_shift ) + FT_Outline_Translate( outline, x_shift, y_shift ); + + /* set up parameters */ + params.root.target = bitmap; + params.root.source = outline; + params.root.flags = FT_RASTER_FLAG_SDF; + params.spread = sdf_module->spread; + params.flip_sign = sdf_module->flip_sign; + params.flip_y = sdf_module->flip_y; + params.overlaps = sdf_module->overlaps; + + /* render the outline */ + error = render->raster_render( render->raster, + (const FT_Raster_Params*)¶ms ); + + /* transform the outline back to the original state */ + if ( x_shift || y_shift ) + FT_Outline_Translate( outline, -x_shift, -y_shift ); + + Exit: + if ( !error ) + { + /* the glyph is successfully rendered to a bitmap */ + slot->format = FT_GLYPH_FORMAT_BITMAP; + } + else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + { + FT_FREE( bitmap->buffer ); + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + + return error; + } + + + /* transform the glyph using matrix and/or delta */ + static FT_Error + ft_sdf_transform( FT_Renderer render, + FT_GlyphSlot slot, + const FT_Matrix* matrix, + const FT_Vector* delta ) + { + FT_Error error = FT_Err_Ok; + + + if ( slot->format != render->glyph_format ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( matrix ) + FT_Outline_Transform( &slot->outline, matrix ); + + if ( delta ) + FT_Outline_Translate( &slot->outline, delta->x, delta->y ); + + Exit: + return error; + } + + + /* return the control box of a glyph's outline */ + static void + ft_sdf_get_cbox( FT_Renderer render, + FT_GlyphSlot slot, + FT_BBox* cbox ) + { + FT_ZERO( cbox ); + + if ( slot->format == render->glyph_format ) + FT_Outline_Get_CBox( &slot->outline, cbox ); + } + + + /* set render specific modes or attributes */ + static FT_Error + ft_sdf_set_mode( FT_Renderer render, + FT_ULong mode_tag, + FT_Pointer data ) + { + /* pass it to the rasterizer */ + return render->clazz->raster_class->raster_set_mode( render->raster, + mode_tag, + data ); + } + + + FT_DEFINE_RENDERER( + ft_sdf_renderer_class, + + FT_MODULE_RENDERER, + sizeof ( SDF_Renderer_Module ), + + "sdf", + 0x10000L, + 0x20000L, + + NULL, + + (FT_Module_Constructor)ft_sdf_init, + (FT_Module_Destructor) ft_sdf_done, + (FT_Module_Requester) ft_sdf_requester, + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Renderer_RenderFunc) ft_sdf_render, /* render_glyph */ + (FT_Renderer_TransformFunc)ft_sdf_transform, /* transform_glyph */ + (FT_Renderer_GetCBoxFunc) ft_sdf_get_cbox, /* get_glyph_cbox */ + (FT_Renderer_SetModeFunc) ft_sdf_set_mode, /* set_mode */ + + (FT_Raster_Funcs*)&ft_sdf_raster /* raster_class */ + ) + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** BITMAP TO SDF CONVERTER **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + /* generate signed distance field from glyph's bitmap */ + static FT_Error + ft_bsdf_render( FT_Renderer module, + FT_GlyphSlot slot, + FT_Render_Mode mode, + const FT_Vector* origin ) + { + FT_Error error = FT_Err_Ok; + FT_Memory memory = NULL; + + FT_Bitmap* bitmap = &slot->bitmap; + FT_Renderer render = NULL; + FT_Bitmap target; + + FT_Pos x_pad = 0; + FT_Pos y_pad = 0; + + SDF_Raster_Params params; + SDF_Renderer sdf_module = SDF_RENDERER( module ); + + + /* initialize the bitmap in case any error occurs */ + FT_Bitmap_Init( &target ); + + render = &sdf_module->root; + memory = render->root.memory; + + /* check whether slot format is correct before rendering */ + if ( slot->format != render->glyph_format ) + { + error = FT_THROW( Invalid_Glyph_Format ); + goto Exit; + } + + /* check whether render mode is correct */ + if ( mode != FT_RENDER_MODE_SDF ) + { + error = FT_THROW( Cannot_Render_Glyph ); + goto Exit; + } + + if ( origin ) + { + FT_ERROR(( "ft_bsdf_render: can't translate the bitmap\n" )); + + error = FT_THROW( Unimplemented_Feature ); + goto Exit; + } + + /* Do not generate SDF if the bitmap is not owned by the */ + /* glyph: it might be that the source buffer is already freed. */ + if ( !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) + { + FT_ERROR(( "ft_bsdf_render: can't generate SDF from" + " unowned source bitmap\n" )); + + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( !bitmap->rows || !bitmap->pitch ) + { + FT_ERROR(( "ft_bsdf_render: invalid bitmap size\n" )); + + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + FT_Bitmap_New( &target ); + + /* padding will simply be equal to `spread` */ + x_pad = sdf_module->spread; + y_pad = sdf_module->spread; + + /* apply padding, which extends to all directions */ + target.rows = bitmap->rows + y_pad * 2; + target.width = bitmap->width + x_pad * 2; + + /* set up the target bitmap */ + target.pixel_mode = FT_PIXEL_MODE_GRAY; + target.pitch = (int)( target.width ); + target.num_grays = 255; + + if ( FT_ALLOC_MULT( target.buffer, target.rows, target.pitch ) ) + goto Exit; + + /* set up parameters */ + params.root.target = ⌖ + params.root.source = bitmap; + params.root.flags = FT_RASTER_FLAG_SDF; + params.spread = sdf_module->spread; + params.flip_sign = sdf_module->flip_sign; + params.flip_y = sdf_module->flip_y; + + error = render->raster_render( render->raster, + (const FT_Raster_Params*)¶ms ); + + Exit: + if ( !error ) + { + /* the glyph is successfully converted to a SDF */ + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + { + FT_FREE( bitmap->buffer ); + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + + slot->bitmap = target; + slot->bitmap_top += y_pad; + slot->bitmap_left -= x_pad; + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + } + else if ( target.buffer ) + FT_FREE( target.buffer ); + + return error; + } + + + FT_DEFINE_RENDERER( + ft_bitmap_sdf_renderer_class, + + FT_MODULE_RENDERER, + sizeof ( SDF_Renderer_Module ), + + "bsdf", + 0x10000L, + 0x20000L, + + NULL, + + (FT_Module_Constructor)ft_sdf_init, + (FT_Module_Destructor) ft_sdf_done, + (FT_Module_Requester) ft_sdf_requester, + + FT_GLYPH_FORMAT_BITMAP, + + (FT_Renderer_RenderFunc) ft_bsdf_render, /* render_glyph */ + (FT_Renderer_TransformFunc)ft_sdf_transform, /* transform_glyph */ + (FT_Renderer_GetCBoxFunc) ft_sdf_get_cbox, /* get_glyph_cbox */ + (FT_Renderer_SetModeFunc) ft_sdf_set_mode, /* set_mode */ + + (FT_Raster_Funcs*)&ft_bitmap_sdf_raster /* raster_class */ + ) + + +/* END */ diff --git a/thirdparty/freetype/src/sdf/ftsdfrend.h b/thirdparty/freetype/src/sdf/ftsdfrend.h new file mode 100644 index 0000000000..bc88707ec2 --- /dev/null +++ b/thirdparty/freetype/src/sdf/ftsdfrend.h @@ -0,0 +1,118 @@ +/**************************************************************************** + * + * ftsdfrend.h + * + * Signed Distance Field renderer interface (specification). + * + * Copyright (C) 2020-2021 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Written by Anuj Verma. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#ifndef FTSDFREND_H_ +#define FTSDFREND_H_ + +#include <freetype/ftrender.h> +#include <freetype/ftmodapi.h> +#include <freetype/internal/ftobjs.h> + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @struct: + * SDF_Renderer_Module + * + * @description: + * This struct extends the native renderer struct `FT_RendererRec`. It + * is basically used to store various parameters required by the + * renderer and some additional parameters that can be used to tweak the + * output of the renderer. + * + * @fields: + * root :: + * The native rendere struct. + * + * spread :: + * This is an essential parameter/property required by the renderer. + * `spread` defines the maximum unsigned value that is present in the + * final SDF output. For the default value check file + * `ftsdfcommon.h`. + * + * flip_sign :: + * By default positive values indicate positions inside of contours, + * i.e., filled by a contour. If this property is true then that + * output will be the opposite of the default, i.e., negative values + * indicate positions inside of contours. + * + * flip_y :: + * Setting this parameter to true makes the output image flipped + * along the y-axis. + * + * overlaps :: + * Set this to true to generate SDF for glyphs having overlapping + * contours. The overlapping support is limited to glyphs that do not + * have self-intersecting contours. Also, removing overlaps require a + * considerable amount of extra memory; additionally, it will not work + * if generating SDF from bitmap. + * + * @note: + * All properties except `overlaps` are valid for both the 'sdf' and + * 'bsdf' renderers. + * + */ + typedef struct SDF_Renderer_Module_ + { + FT_RendererRec root; + FT_UInt spread; + FT_Bool flip_sign; + FT_Bool flip_y; + FT_Bool overlaps; + + } SDF_Renderer_Module, *SDF_Renderer; + + + /************************************************************************** + * + * @renderer: + * ft_sdf_renderer_class + * + * @description: + * Renderer to convert @FT_Outline to signed distance fields. + * + */ + FT_DECLARE_RENDERER( ft_sdf_renderer_class ) + + + /************************************************************************** + * + * @renderer: + * ft_bitmap_sdf_renderer_class + * + * @description: + * This is not exactly a renderer; it is just a converter that + * transforms bitmaps to signed distance fields. + * + * @note: + * This is not a separate module, it is part of the 'sdf' module. + * + */ + FT_DECLARE_RENDERER( ft_bitmap_sdf_renderer_class ) + + +FT_END_HEADER + +#endif /* FTSDFREND_H_ */ + + +/* END */ diff --git a/thirdparty/freetype/src/sdf/sdf.c b/thirdparty/freetype/src/sdf/sdf.c new file mode 100644 index 0000000000..1bc3fc385c --- /dev/null +++ b/thirdparty/freetype/src/sdf/sdf.c @@ -0,0 +1,29 @@ +/**************************************************************************** + * + * sdf.c + * + * FreeType Signed Distance Field renderer module component (body only). + * + * Copyright (C) 2020-2021 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Written by Anuj Verma. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include "ftsdfrend.c" +#include "ftsdfcommon.c" +#include "ftbsdf.c" +#include "ftsdf.c" + + +/* END */ diff --git a/thirdparty/freetype/src/sfnt/module.mk b/thirdparty/freetype/src/sfnt/module.mk deleted file mode 100644 index 0f459d8421..0000000000 --- a/thirdparty/freetype/src/sfnt/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 SFNT module definition -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += SFNT_MODULE - -define SFNT_MODULE -$(OPEN_DRIVER) FT_Module_Class, sfnt_module_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)sfnt $(ECHO_DRIVER_DESC)helper module for TrueType & OpenType formats$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/sfnt/pngshim.c b/thirdparty/freetype/src/sfnt/pngshim.c index f55016122c..02fe37440c 100644 --- a/thirdparty/freetype/src/sfnt/pngshim.c +++ b/thirdparty/freetype/src/sfnt/pngshim.c @@ -4,7 +4,7 @@ * * PNG Bitmap glyph support. * - * Copyright (C) 2013-2020 by + * Copyright (C) 2013-2021 by * Google, Inc. * Written by Stuart Gill and Behdad Esfahbod. * @@ -270,7 +270,10 @@ int bitdepth, color_type, interlace; FT_Int i; - png_byte* *rows = NULL; /* pacify compiler */ + + /* `rows` gets modified within a 'setjmp' scope; */ + /* we thus need the `volatile` keyword. */ + png_byte* *volatile rows = NULL; if ( x_offset < 0 || @@ -427,7 +430,7 @@ goto DestroyExit; } - if ( FT_NEW_ARRAY( rows, imgHeight ) ) + if ( FT_QNEW_ARRAY( rows, imgHeight ) ) { error = FT_THROW( Out_Of_Memory ); goto DestroyExit; @@ -438,11 +441,11 @@ png_read_image( png, rows ); - FT_FREE( rows ); - png_read_end( png, info ); DestroyExit: + /* even if reading fails with longjmp, rows must be freed */ + FT_FREE( rows ); png_destroy_read_struct( &png, &info, NULL ); FT_Stream_Close( &stream ); diff --git a/thirdparty/freetype/src/sfnt/pngshim.h b/thirdparty/freetype/src/sfnt/pngshim.h index 2d6e83d69b..89efd27545 100644 --- a/thirdparty/freetype/src/sfnt/pngshim.h +++ b/thirdparty/freetype/src/sfnt/pngshim.h @@ -4,7 +4,7 @@ * * PNG Bitmap glyph support. * - * Copyright (C) 2013-2020 by + * Copyright (C) 2013-2021 by * Google, Inc. * Written by Stuart Gill and Behdad Esfahbod. * diff --git a/thirdparty/freetype/src/sfnt/rules.mk b/thirdparty/freetype/src/sfnt/rules.mk deleted file mode 100644 index f56ef060ed..0000000000 --- a/thirdparty/freetype/src/sfnt/rules.mk +++ /dev/null @@ -1,85 +0,0 @@ -# -# FreeType 2 SFNT driver configuration rules -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# SFNT driver directory -# -SFNT_DIR := $(SRC_DIR)/sfnt - - -# compilation flags for the driver -# -SFNT_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(SFNT_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# SFNT driver sources (i.e., C files) -# -SFNT_DRV_SRC := $(SFNT_DIR)/pngshim.c \ - $(SFNT_DIR)/sfdriver.c \ - $(SFNT_DIR)/sfobjs.c \ - $(SFNT_DIR)/sfwoff.c \ - $(SFNT_DIR)/sfwoff2.c \ - $(SFNT_DIR)/ttbdf.c \ - $(SFNT_DIR)/ttcmap.c \ - $(SFNT_DIR)/ttcolr.c \ - $(SFNT_DIR)/ttcpal.c \ - $(SFNT_DIR)/ttkern.c \ - $(SFNT_DIR)/ttload.c \ - $(SFNT_DIR)/ttmtx.c \ - $(SFNT_DIR)/ttpost.c \ - $(SFNT_DIR)/ttsbit.c \ - $(SFNT_DIR)/woff2tags.c - -# SFNT driver headers -# -SFNT_DRV_H := $(SFNT_DRV_SRC:%c=%h) \ - $(SFNT_DIR)/sferrors.h - - -# SFNT driver object(s) -# -# SFNT_DRV_OBJ_M is used during `multi' builds. -# SFNT_DRV_OBJ_S is used during `single' builds. -# -SFNT_DRV_OBJ_M := $(SFNT_DRV_SRC:$(SFNT_DIR)/%.c=$(OBJ_DIR)/%.$O) -SFNT_DRV_OBJ_S := $(OBJ_DIR)/sfnt.$O - -# SFNT driver source file for single build -# -SFNT_DRV_SRC_S := $(SFNT_DIR)/sfnt.c - - -# SFNT driver - single object -# -$(SFNT_DRV_OBJ_S): $(SFNT_DRV_SRC_S) $(SFNT_DRV_SRC) \ - $(FREETYPE_H) $(SFNT_DRV_H) - $(SFNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(SFNT_DRV_SRC_S)) - - -# SFNT driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(SFNT_DIR)/%.c $(FREETYPE_H) $(SFNT_DRV_H) - $(SFNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(SFNT_DRV_OBJ_S) -DRV_OBJS_M += $(SFNT_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/sfnt/sfdriver.c b/thirdparty/freetype/src/sfnt/sfdriver.c index 0460339a74..d1d01c99e5 100644 --- a/thirdparty/freetype/src/sfnt/sfdriver.c +++ b/thirdparty/freetype/src/sfnt/sfdriver.c @@ -4,7 +4,7 @@ * * High-level SFNT driver interface (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -501,7 +501,7 @@ FT_UNUSED( error ); - if ( FT_ALLOC( result, entry->stringLength / 2 + 1 ) ) + if ( FT_QALLOC( result, entry->stringLength / 2 + 1 ) ) return NULL; if ( FT_STREAM_SEEK( entry->stringOffset ) || @@ -560,7 +560,7 @@ FT_UNUSED( error ); - if ( FT_ALLOC( result, entry->stringLength + 1 ) ) + if ( FT_QALLOC( result, entry->stringLength + 1 ) ) return NULL; if ( FT_STREAM_SEEK( entry->stringOffset ) || @@ -868,8 +868,8 @@ result[len] = '\0'; FT_TRACE0(( "sfnt_get_var_ps_name:" - " Shortening variation PS name prefix\n" - " " + " Shortening variation PS name prefix\n" )); + FT_TRACE0(( " " " to %d characters\n", len )); } @@ -920,16 +920,16 @@ if ( !subfamily_name ) { FT_TRACE1(( "sfnt_get_var_ps_name:" - " can't construct named instance PS name;\n" - " " + " can't construct named instance PS name;\n" )); + FT_TRACE1(( " " " trying to construct normal instance PS name\n" )); goto construct_instance_name; } /* after the prefix we have character `-' followed by the */ /* subfamily name (using only characters a-z, A-Z, and 0-9) */ - if ( FT_ALLOC( result, face->var_postscript_prefix_len + - 1 + ft_strlen( subfamily_name ) + 1 ) ) + if ( FT_QALLOC( result, face->var_postscript_prefix_len + + 1 + ft_strlen( subfamily_name ) + 1 ) ) return NULL; ft_strcpy( result, face->var_postscript_prefix ); @@ -957,9 +957,9 @@ construct_instance_name: axis = mm_var->axis; - if ( FT_ALLOC( result, - face->var_postscript_prefix_len + - num_coords * MAX_VALUE_DESCRIPTOR_LEN + 1 ) ) + if ( FT_QALLOC( result, + face->var_postscript_prefix_len + + num_coords * MAX_VALUE_DESCRIPTOR_LEN + 1 ) ) return NULL; p = result; @@ -993,6 +993,7 @@ if ( t != ' ' && ft_isalnum( t ) ) *p++ = t; } + *p++ = '\0'; } check_length: @@ -1213,6 +1214,8 @@ #define PUT_COLOR_LAYERS( a ) NULL #endif +#define PUT_COLOR_LAYERS_V1( a ) PUT_COLOR_LAYERS( a ) + #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES #define PUT_PS_NAMES( a ) a #else @@ -1271,9 +1274,9 @@ /* TT_Free_Table_Func free_eblc */ PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike ), - /* TT_Set_SBit_Strike_Func set_sbit_strike */ + /* TT_Set_SBit_Strike_Func set_sbit_strike */ PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ), - /* TT_Load_Strike_Metrics_Func load_strike_metrics */ + /* TT_Load_Strike_Metrics_Func load_strike_metrics */ PUT_COLOR_LAYERS( tt_face_load_cpal ), /* TT_Load_Table_Func load_cpal */ @@ -1287,6 +1290,18 @@ /* TT_Set_Palette_Func set_palette */ PUT_COLOR_LAYERS( tt_face_get_colr_layer ), /* TT_Get_Colr_Layer_Func get_colr_layer */ + + PUT_COLOR_LAYERS_V1( tt_face_get_colr_glyph_paint ), + /* TT_Get_Color_Glyph_Paint_Func get_colr_glyph_paint */ + PUT_COLOR_LAYERS_V1( tt_face_get_color_glyph_clipbox ), + /* TT_Get_Color_Glyph_ClipBox_Func get_clipbox */ + PUT_COLOR_LAYERS_V1( tt_face_get_paint_layers ), + /* TT_Get_Paint_Layers_Func get_paint_layers */ + PUT_COLOR_LAYERS_V1( tt_face_get_colorline_stops ), + /* TT_Get_Paint get_paint */ + PUT_COLOR_LAYERS_V1( tt_face_get_paint ), + /* TT_Get_Colorline_Stops_Func get_colorline_stops */ + PUT_COLOR_LAYERS( tt_face_colr_blend_layer ), /* TT_Blend_Colr_Func colr_blend */ diff --git a/thirdparty/freetype/src/sfnt/sfdriver.h b/thirdparty/freetype/src/sfnt/sfdriver.h index 1ac2706325..8d5b5ce367 100644 --- a/thirdparty/freetype/src/sfnt/sfdriver.h +++ b/thirdparty/freetype/src/sfnt/sfdriver.h @@ -4,7 +4,7 @@ * * High-level SFNT driver interface (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/sfnt/sferrors.h b/thirdparty/freetype/src/sfnt/sferrors.h index 55c3e76b66..78e6f03513 100644 --- a/thirdparty/freetype/src/sfnt/sferrors.h +++ b/thirdparty/freetype/src/sfnt/sferrors.h @@ -4,7 +4,7 @@ * * SFNT error codes (specification only). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/sfnt/sfnt.c b/thirdparty/freetype/src/sfnt/sfnt.c index 471239ff0b..97692cdfb0 100644 --- a/thirdparty/freetype/src/sfnt/sfnt.c +++ b/thirdparty/freetype/src/sfnt/sfnt.c @@ -4,7 +4,7 @@ * * Single object library component. * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/sfnt/sfobjs.c b/thirdparty/freetype/src/sfnt/sfobjs.c index 39460be2e6..7891024790 100644 --- a/thirdparty/freetype/src/sfnt/sfobjs.c +++ b/thirdparty/freetype/src/sfnt/sfobjs.c @@ -4,7 +4,7 @@ * * SFNT object management (base). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -65,7 +65,7 @@ len = (FT_UInt)entry->stringLength / 2; - if ( FT_NEW_ARRAY( string, len + 1 ) ) + if ( FT_QNEW_ARRAY( string, len + 1 ) ) return NULL; for ( n = 0; n < len; n++ ) @@ -100,7 +100,7 @@ len = (FT_UInt)entry->stringLength; - if ( FT_NEW_ARRAY( string, len + 1 ) ) + if ( FT_QNEW_ARRAY( string, len + 1 ) ) return NULL; for ( n = 0; n < len; n++ ) @@ -360,17 +360,27 @@ FT_FRAME_END }; +#ifndef FT_CONFIG_OPTION_USE_BROTLI + FT_UNUSED( face_instance_index ); + FT_UNUSED( woff2_num_faces ); +#endif + face->ttc_header.tag = 0; face->ttc_header.version = 0; face->ttc_header.count = 0; +#if defined( FT_CONFIG_OPTION_USE_ZLIB ) || \ + defined( FT_CONFIG_OPTION_USE_BROTLI ) retry: +#endif + offset = FT_STREAM_POS(); if ( FT_READ_ULONG( tag ) ) return error; +#ifdef FT_CONFIG_OPTION_USE_ZLIB if ( tag == TTAG_wOFF ) { FT_TRACE2(( "sfnt_open_font: file is a WOFF; synthesizing SFNT\n" )); @@ -386,7 +396,9 @@ stream = face->root.stream; goto retry; } +#endif +#ifdef FT_CONFIG_OPTION_USE_BROTLI if ( tag == TTAG_wOF2 ) { FT_TRACE2(( "sfnt_open_font: file is a WOFF2; synthesizing SFNT\n" )); @@ -405,6 +417,7 @@ stream = face->root.stream; goto retry; } +#endif if ( tag != 0x00010000UL && tag != TTAG_ttcf && @@ -446,7 +459,7 @@ return FT_THROW( Array_Too_Large ); /* now read the offsets of each font in the file */ - if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) ) + if ( FT_QNEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) ) return error; if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) ) @@ -464,7 +477,7 @@ face->ttc_header.version = 1 << 16; face->ttc_header.count = 1; - if ( FT_NEW( face->ttc_header.offsets ) ) + if ( FT_QNEW( face->ttc_header.offsets ) ) return error; face->ttc_header.offsets[0] = offset; @@ -643,8 +656,8 @@ */ if ( ( face->variation_support & TT_FACE_FLAG_VAR_FVAR ) && - !( FT_ALLOC( default_values, num_axes * 4 ) || - FT_ALLOC( instance_values, num_axes * 4 ) ) ) + !( FT_QALLOC( default_values, num_axes * 4 ) || + FT_QALLOC( instance_values, num_axes * 4 ) ) ) { /* the current stream position is 16 bytes after the table start */ FT_ULong array_start = FT_STREAM_POS() - 16 + offset; @@ -820,7 +833,8 @@ /* it doesn't contain outlines. */ /* */ - FT_TRACE2(( "sfnt_load_face: %p\n\n", (void *)face )); + FT_TRACE2(( "sfnt_load_face: %p\n", (void *)face )); + FT_TRACE2(( "\n" )); /* do we have outlines in there? */ #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -1149,9 +1163,10 @@ } /* synthesize Unicode charmap if one is missing */ - if ( !has_unicode ) + if ( !has_unicode && + root->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) { - FT_CharMapRec cmaprec; + FT_CharMapRec cmaprec; cmaprec.face = root; @@ -1207,7 +1222,7 @@ /* of `FT_Face', we map `available_sizes' indices to strike */ /* indices */ if ( FT_NEW_ARRAY( root->available_sizes, count ) || - FT_NEW_ARRAY( sbit_strike_map, count ) ) + FT_QNEW_ARRAY( sbit_strike_map, count ) ) goto Exit; bsize_idx = 0; @@ -1236,7 +1251,7 @@ } /* reduce array size to the actually used elements */ - (void)FT_RENEW_ARRAY( sbit_strike_map, count, bsize_idx ); + FT_MEM_QRENEW_ARRAY( sbit_strike_map, count, bsize_idx ); /* from now on, all strike indices are mapped */ /* using `sbit_strike_map' */ diff --git a/thirdparty/freetype/src/sfnt/sfobjs.h b/thirdparty/freetype/src/sfnt/sfobjs.h index e8e3042083..172c47ebb4 100644 --- a/thirdparty/freetype/src/sfnt/sfobjs.h +++ b/thirdparty/freetype/src/sfnt/sfobjs.h @@ -4,7 +4,7 @@ * * SFNT object management (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/sfnt/sfwoff.c b/thirdparty/freetype/src/sfnt/sfwoff.c index f0a32e1e06..422c816a21 100644 --- a/thirdparty/freetype/src/sfnt/sfwoff.c +++ b/thirdparty/freetype/src/sfnt/sfwoff.c @@ -4,7 +4,7 @@ * * WOFF format management (base). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -23,6 +23,9 @@ #include <freetype/ftgzip.h> +#ifdef FT_CONFIG_OPTION_USE_ZLIB + + /************************************************************************** * * The macro FT_COMPONENT is used in trace mode. It is an implicit @@ -66,7 +69,7 @@ } - FT_CALLBACK_DEF( int ) + FT_COMPARE_DEF( int ) compare_offsets( const void* a, const void* b ) { @@ -109,7 +112,7 @@ FT_ULong sfnt_offset; FT_Int nn; - FT_ULong old_tag = 0; + FT_Tag old_tag = 0; static const FT_Frame_Field woff_header_fields[] = { @@ -160,8 +163,8 @@ } /* Don't trust `totalSfntSize' before thorough checks. */ - if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) || - FT_NEW( sfnt_stream ) ) + if ( FT_QALLOC( sfnt, 12 + woff.num_tables * 16UL ) || + FT_NEW( sfnt_stream ) ) goto Exit; sfnt_header = sfnt; @@ -198,9 +201,9 @@ FT_NEW_ARRAY( indices, woff.num_tables ) ) goto Exit; - FT_TRACE2(( "\n" - " tag offset compLen origLen checksum\n" - " -------------------------------------------\n" )); + FT_TRACE2(( "\n" )); + FT_TRACE2(( " tag offset compLen origLen checksum\n" )); + FT_TRACE2(( " -------------------------------------------\n" )); if ( FT_FRAME_ENTER( 20L * woff.num_tables ) ) goto Exit; @@ -360,8 +363,6 @@ } else { -#ifdef FT_CONFIG_OPTION_USE_ZLIB - /* Uncompress with zlib. */ FT_ULong output_len = table->OrigLength; @@ -377,13 +378,6 @@ error = FT_THROW( Invalid_Table ); goto Exit1; } - -#else /* !FT_CONFIG_OPTION_USE_ZLIB */ - - error = FT_THROW( Unimplemented_Feature ); - goto Exit1; - -#endif /* !FT_CONFIG_OPTION_USE_ZLIB */ } FT_FRAME_EXIT(); @@ -433,5 +427,12 @@ #undef WRITE_USHORT #undef WRITE_ULONG +#else /* !FT_CONFIG_OPTION_USE_ZLIB */ + + /* ANSI C doesn't like empty source files */ + typedef int _sfwoff_dummy; + +#endif /* !FT_CONFIG_OPTION_USE_ZLIB */ + /* END */ diff --git a/thirdparty/freetype/src/sfnt/sfwoff.h b/thirdparty/freetype/src/sfnt/sfwoff.h index d177ab1160..3fbdac0fde 100644 --- a/thirdparty/freetype/src/sfnt/sfwoff.h +++ b/thirdparty/freetype/src/sfnt/sfwoff.h @@ -4,7 +4,7 @@ * * WOFFF format management (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -26,12 +26,15 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_USE_ZLIB FT_LOCAL( FT_Error ) woff_open_font( FT_Stream stream, TT_Face face ); +#endif + FT_END_HEADER #endif /* SFWOFF_H_ */ diff --git a/thirdparty/freetype/src/sfnt/sfwoff2.c b/thirdparty/freetype/src/sfnt/sfwoff2.c index 5c8202f823..5ee8dea28a 100644 --- a/thirdparty/freetype/src/sfnt/sfwoff2.c +++ b/thirdparty/freetype/src/sfnt/sfwoff2.c @@ -4,7 +4,7 @@ * * WOFF2 format management (base). * - * Copyright (C) 2019-2020 by + * Copyright (C) 2019-2021 by * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -26,8 +26,6 @@ #include <brotli/decode.h> -#endif - /************************************************************************** * @@ -101,15 +99,15 @@ } - FT_CALLBACK_DEF( int ) + FT_COMPARE_DEF( int ) compare_tags( const void* a, const void* b ) { WOFF2_Table table1 = *(WOFF2_Table*)a; WOFF2_Table table2 = *(WOFF2_Table*)b; - FT_ULong tag1 = table1->Tag; - FT_ULong tag2 = table2->Tag; + FT_Tag tag1 = table1->Tag; + FT_Tag tag2 = table2->Tag; if ( tag1 > tag2 ) @@ -316,8 +314,6 @@ const FT_Byte* src, FT_ULong src_size ) { -#ifdef FT_CONFIG_OPTION_USE_BROTLI - /* this cast is only of importance on 32bit systems; */ /* we don't validate it */ FT_Offset uncompressed_size = (FT_Offset)dst_size; @@ -338,20 +334,13 @@ FT_TRACE2(( "woff2_decompress: Brotli stream decompressed.\n" )); return FT_Err_Ok; - -#else /* !FT_CONFIG_OPTION_USE_BROTLI */ - - FT_ERROR(( "woff2_decompress: Brotli support not available.\n" )); - return FT_THROW( Unimplemented_Feature ); - -#endif /* !FT_CONFIG_OPTION_USE_BROTLI */ } static WOFF2_Table find_table( WOFF2_Table* tables, FT_UShort num_tables, - FT_ULong tag ) + FT_Tag tag ) { FT_Int i; @@ -790,7 +779,7 @@ goto Fail; loca_buf_size = loca_values_size * offset_size; - if ( FT_NEW_ARRAY( loca_buf, loca_buf_size ) ) + if ( FT_QNEW_ARRAY( loca_buf, loca_buf_size ) ) goto Fail; dst = loca_buf; @@ -1852,11 +1841,10 @@ FT_NEW_ARRAY( indices, woff2.num_tables ) ) goto Exit; - FT_TRACE2(( - "\n" - " tag flags transform origLen transformLen offset\n" - " -----------------------------------------------------------\n" )); - /* " XXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX" */ + FT_TRACE2(( "\n" )); + FT_TRACE2(( " tag flags transform origLen transformLen offset\n" )); + FT_TRACE2(( " -----------------------------------------------------------\n" )); + /* " XXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX" */ for ( nn = 0; nn < woff2.num_tables; nn++ ) { @@ -2119,8 +2107,8 @@ /* Create a temporary array. */ - if ( FT_NEW_ARRAY( temp_indices, - ttc_font->num_tables ) ) + if ( FT_QNEW_ARRAY( temp_indices, + ttc_font->num_tables ) ) goto Exit; FT_TRACE4(( "Storing tables for TTC face index %d.\n", face_index )); @@ -2128,9 +2116,9 @@ temp_indices[nn] = indices[ttc_font->table_indices[nn]]; /* Resize array to required size. */ - if ( FT_RENEW_ARRAY( indices, - woff2.num_tables, - ttc_font->num_tables ) ) + if ( FT_QRENEW_ARRAY( indices, + woff2.num_tables, + ttc_font->num_tables ) ) goto Exit; for ( nn = 0; nn < ttc_font->num_tables; nn++ ) @@ -2170,8 +2158,8 @@ } /* Write sfnt header. */ - if ( FT_ALLOC( sfnt, sfnt_size ) || - FT_NEW( sfnt_stream ) ) + if ( FT_QALLOC( sfnt, sfnt_size ) || + FT_NEW( sfnt_stream ) ) goto Exit; sfnt_header = sfnt; @@ -2209,6 +2197,25 @@ sizeof ( WOFF2_Table ), compare_tags ); + /* reject fonts that have multiple tables with the same tag */ + for ( nn = 1; nn < woff2.num_tables; nn++ ) + { + FT_Tag tag = indices[nn]->Tag; + + + if ( tag == indices[nn - 1]->Tag ) + { + FT_ERROR(( "woff2_open_font:" + " multiple tables with tag `%c%c%c%c'.\n", + (FT_Char)( tag >> 24 ), + (FT_Char)( tag >> 16 ), + (FT_Char)( tag >> 8 ), + (FT_Char)( tag ) )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + } + if ( woff2.uncompressed_size < 1 ) { error = FT_THROW( Invalid_Table ); @@ -2223,8 +2230,8 @@ } /* Allocate memory for uncompressed table data. */ - if ( FT_ALLOC( uncompressed_buf, woff2.uncompressed_size ) || - FT_FRAME_ENTER( woff2.totalCompressedSize ) ) + if ( FT_QALLOC( uncompressed_buf, woff2.uncompressed_size ) || + FT_FRAME_ENTER( woff2.totalCompressedSize ) ) goto Exit; /* Uncompress the stream. */ @@ -2333,5 +2340,12 @@ #undef BBOX_STREAM #undef INSTRUCTION_STREAM +#else /* !FT_CONFIG_OPTION_USE_BROTLI */ + + /* ANSI C doesn't like empty source files */ + typedef int _sfwoff2_dummy; + +#endif /* !FT_CONFIG_OPTION_USE_BROTLI */ + /* END */ diff --git a/thirdparty/freetype/src/sfnt/sfwoff2.h b/thirdparty/freetype/src/sfnt/sfwoff2.h index 798f66bd0a..fa78b02429 100644 --- a/thirdparty/freetype/src/sfnt/sfwoff2.h +++ b/thirdparty/freetype/src/sfnt/sfwoff2.h @@ -4,7 +4,7 @@ * * WOFFF2 format management (specification). * - * Copyright (C) 2019-2020 by + * Copyright (C) 2019-2021 by * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -26,6 +26,7 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_USE_BROTLI /* Leave the first byte open to store `flag_byte'. */ #define WOFF2_FLAGS_TRANSFORM 1 << 8 @@ -66,6 +67,7 @@ FT_BEGIN_HEADER FT_Int* face_index, FT_Long* num_faces ); +#endif /* FT_CONFIG_OPTION_USE_BROTLI */ FT_END_HEADER diff --git a/thirdparty/freetype/src/sfnt/ttbdf.c b/thirdparty/freetype/src/sfnt/ttbdf.c index a287d3afc4..b8d9473a63 100644 --- a/thirdparty/freetype/src/sfnt/ttbdf.c +++ b/thirdparty/freetype/src/sfnt/ttbdf.c @@ -4,7 +4,7 @@ * * TrueType and OpenType embedded BDF properties (body). * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/sfnt/ttbdf.h b/thirdparty/freetype/src/sfnt/ttbdf.h index e60c01cb8b..91271d916f 100644 --- a/thirdparty/freetype/src/sfnt/ttbdf.h +++ b/thirdparty/freetype/src/sfnt/ttbdf.h @@ -4,7 +4,7 @@ * * TrueType and OpenType embedded BDF properties (specification). * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/sfnt/ttcmap.c b/thirdparty/freetype/src/sfnt/ttcmap.c index 556a712199..b369d83788 100644 --- a/thirdparty/freetype/src/sfnt/ttcmap.c +++ b/thirdparty/freetype/src/sfnt/ttcmap.c @@ -4,7 +4,7 @@ * * TrueType character mapping table (cmap) support (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -916,6 +916,16 @@ length = (FT_UInt)( valid->limit - table ); } + /* it also happens that the `length' field is too small; */ + /* this is easy to correct */ + if ( length < (FT_UInt)( valid->limit - table ) ) + { + if ( valid->level >= FT_VALIDATE_PARANOID ) + FT_INVALID_DATA; + + length = (FT_UInt)( valid->limit - table ); + } + if ( length < 16 ) FT_INVALID_TOO_SHORT; diff --git a/thirdparty/freetype/src/sfnt/ttcmap.h b/thirdparty/freetype/src/sfnt/ttcmap.h index c7d7c21d2c..504fc951c4 100644 --- a/thirdparty/freetype/src/sfnt/ttcmap.h +++ b/thirdparty/freetype/src/sfnt/ttcmap.h @@ -4,7 +4,7 @@ * * TrueType character mapping table (cmap) support (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/sfnt/ttcmapc.h b/thirdparty/freetype/src/sfnt/ttcmapc.h index 2e4ce5075b..4e6cd46ba8 100644 --- a/thirdparty/freetype/src/sfnt/ttcmapc.h +++ b/thirdparty/freetype/src/sfnt/ttcmapc.h @@ -4,7 +4,7 @@ * * TT CMAP classes definitions (specification only). * - * Copyright (C) 2009-2020 by + * Copyright (C) 2009-2021 by * Oran Agra and Mickey Gabel. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/sfnt/ttcolr.c b/thirdparty/freetype/src/sfnt/ttcolr.c index 9025e356ce..8f5cc8bcd1 100644 --- a/thirdparty/freetype/src/sfnt/ttcolr.c +++ b/thirdparty/freetype/src/sfnt/ttcolr.c @@ -4,8 +4,8 @@ * * TrueType and OpenType colored glyph layer support (body). * - * Copyright (C) 2018-2020 by - * David Turner, Robert Wilhelm, and Werner Lemberg. + * Copyright (C) 2018-2021 by + * David Turner, Robert Wilhelm, Dominik Röttsches, and Werner Lemberg. * * Originally written by Shao Yu Zhang <shaozhang@fb.com>. * @@ -27,10 +27,12 @@ */ +#include <freetype/internal/ftcalc.h> #include <freetype/internal/ftdebug.h> #include <freetype/internal/ftstream.h> #include <freetype/tttags.h> #include <freetype/ftcolor.h> +#include <freetype/config/integer-types.h> #ifdef TT_CONFIG_OPTION_COLOR_LAYERS @@ -39,12 +41,27 @@ /* NOTE: These are the table sizes calculated through the specs. */ -#define BASE_GLYPH_SIZE 6U -#define LAYER_SIZE 4U -#define COLR_HEADER_SIZE 14U +#define BASE_GLYPH_SIZE 6U +#define BASE_GLYPH_PAINT_RECORD_SIZE 6U +#define LAYER_V1_LIST_PAINT_OFFSET_SIZE 4U +#define LAYER_V1_LIST_NUM_LAYERS_SIZE 4U +#define COLOR_STOP_SIZE 6U +#define LAYER_SIZE 4U +#define COLR_HEADER_SIZE 14U - typedef struct BaseGlyphRecord_ + typedef enum FT_PaintFormat_Internal_ + { + FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER = 18, + FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM = 20, + FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER = 22, + FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER = 26, + FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER = 30 + + } FT_PaintFormat_Internal; + + + typedef struct BaseGlyphRecord_ { FT_UShort gid; FT_UShort first_layer_index; @@ -53,7 +70,16 @@ } BaseGlyphRecord; - typedef struct Colr_ + typedef struct BaseGlyphV1Record_ + { + FT_UShort gid; + /* Offset from start of BaseGlyphV1List, i.e., from base_glyphs_v1. */ + FT_ULong paint_offset; + + } BaseGlyphV1Record; + + + typedef struct Colr_ { FT_UShort version; FT_UShort num_base_glyphs; @@ -62,7 +88,23 @@ FT_Byte* base_glyphs; FT_Byte* layers; - /* The memory which backs up the `COLR' table. */ + FT_ULong num_base_glyphs_v1; + /* Points at beginning of BaseGlyphV1List. */ + FT_Byte* base_glyphs_v1; + + FT_ULong num_layers_v1; + FT_Byte* layers_v1; + + FT_Byte* clip_list; + + /* + * Paint tables start at the minimum of the end of the LayerList and the + * end of the BaseGlyphList. Record this location in a field here for + * safety checks when accessing paint tables. + */ + FT_Byte* paints_start_v1; + + /* The memory that backs up the `COLR' table. */ void* table; FT_ULong table_size; @@ -88,10 +130,14 @@ FT_Byte* table = NULL; FT_Byte* p = NULL; + /* Needed for reading array lengths in referenced tables. */ + FT_Byte* p1 = NULL; Colr* colr = NULL; FT_ULong base_glyph_offset, layer_offset; + FT_ULong base_glyphs_offset_v1, num_base_glyphs_v1; + FT_ULong layer_offset_v1, num_layers_v1, clip_list_offset; FT_ULong table_size; @@ -115,7 +161,7 @@ goto NoColr; colr->version = FT_NEXT_USHORT( p ); - if ( colr->version != 0 ) + if ( colr->version != 0 && colr->version != 1 ) goto InvalidTable; colr->num_base_glyphs = FT_NEXT_USHORT( p ); @@ -135,6 +181,66 @@ if ( colr->num_layers * LAYER_SIZE > table_size - layer_offset ) goto InvalidTable; + if ( colr->version == 1 ) + { + base_glyphs_offset_v1 = FT_NEXT_ULONG( p ); + + if ( base_glyphs_offset_v1 >= table_size ) + goto InvalidTable; + + p1 = (FT_Byte*)( table + base_glyphs_offset_v1 ); + num_base_glyphs_v1 = FT_PEEK_ULONG( p1 ); + + if ( num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE > + table_size - base_glyphs_offset_v1 ) + goto InvalidTable; + + colr->num_base_glyphs_v1 = num_base_glyphs_v1; + colr->base_glyphs_v1 = p1; + + layer_offset_v1 = FT_NEXT_ULONG( p ); + + if ( layer_offset_v1 >= table_size ) + goto InvalidTable; + + if ( layer_offset_v1 ) + { + p1 = (FT_Byte*)( table + layer_offset_v1 ); + num_layers_v1 = FT_PEEK_ULONG( p1 ); + + if ( num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE > + table_size - layer_offset_v1 ) + goto InvalidTable; + + colr->num_layers_v1 = num_layers_v1; + colr->layers_v1 = p1; + + colr->paints_start_v1 = + FT_MIN( colr->base_glyphs_v1 + + colr->num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE, + colr->layers_v1 + + colr->num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE ); + } + else + { + colr->num_layers_v1 = 0; + colr->layers_v1 = 0; + colr->paints_start_v1 = + colr->base_glyphs_v1 + + colr->num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE; + } + + clip_list_offset = FT_NEXT_ULONG( p ); + + if ( clip_list_offset >= table_size ) + goto InvalidTable; + + if ( clip_list_offset ) + colr->clip_list = (FT_Byte*)( table + clip_list_offset ); + else + colr->clip_list = 0; + } + colr->base_glyphs = (FT_Byte*)( table + base_glyph_offset ); colr->layers = (FT_Byte*)( table + layer_offset ); colr->table = table; @@ -174,17 +280,17 @@ static FT_Bool find_base_glyph_record( FT_Byte* base_glyph_begin, - FT_Int num_base_glyph, + FT_UInt num_base_glyph, FT_UInt glyph_id, BaseGlyphRecord* record ) { - FT_Int min = 0; - FT_Int max = num_base_glyph - 1; + FT_UInt min = 0; + FT_UInt max = num_base_glyph; - while ( min <= max ) + while ( min < max ) { - FT_Int mid = min + ( max - min ) / 2; + FT_UInt mid = min + ( max - min ) / 2; FT_Byte* p = base_glyph_begin + mid * BASE_GLYPH_SIZE; FT_UShort gid = FT_NEXT_USHORT( p ); @@ -193,7 +299,7 @@ if ( gid < glyph_id ) min = mid + 1; else if (gid > glyph_id ) - max = mid - 1; + max = mid; else { record->gid = gid; @@ -265,6 +371,747 @@ } + static FT_Bool + read_color_line( FT_Byte* color_line_p, + FT_ColorLine *colorline ) + { + FT_Byte* p = color_line_p; + FT_PaintExtend paint_extend; + + + paint_extend = (FT_PaintExtend)FT_NEXT_BYTE( p ); + if ( paint_extend > FT_COLR_PAINT_EXTEND_REFLECT ) + return 0; + + colorline->extend = paint_extend; + + colorline->color_stop_iterator.num_color_stops = FT_NEXT_USHORT( p ); + colorline->color_stop_iterator.p = p; + colorline->color_stop_iterator.current_color_stop = 0; + + return 1; + } + + + /* + * Read a paint offset for `FT_Paint*` objects that have them and check + * whether it is within reasonable limits within the font and the COLR + * table. + * + * Return 1 on success, 0 on failure. + */ + static FT_Bool + get_child_table_pointer ( Colr* colr, + FT_Byte* paint_base, + FT_Byte** p, + FT_Byte** child_table_pointer ) + { + FT_UInt32 paint_offset; + FT_Byte* child_table_p; + + + if ( !child_table_pointer ) + return 0; + + paint_offset = FT_NEXT_UOFF3( *p ); + if ( !paint_offset ) + return 0; + + child_table_p = (FT_Byte*)( paint_base + paint_offset ); + + if ( child_table_p < colr->paints_start_v1 || + child_table_p >= ( (FT_Byte*)colr->table + colr->table_size ) ) + return 0; + + *child_table_pointer = child_table_p; + return 1; + } + + + static FT_Bool + read_paint( Colr* colr, + FT_Byte* p, + FT_COLR_Paint* apaint ) + { + FT_Byte* paint_base = p; + FT_Byte* child_table_p = NULL; + + + if ( !p || !colr || !colr->table ) + return 0; + + if ( p < colr->paints_start_v1 || + p >= ( (FT_Byte*)colr->table + colr->table_size ) ) + return 0; + + apaint->format = (FT_PaintFormat)FT_NEXT_BYTE( p ); + + if ( apaint->format >= FT_COLR_PAINT_FORMAT_MAX ) + return 0; + + if ( apaint->format == FT_COLR_PAINTFORMAT_COLR_LAYERS ) + { + /* Initialize layer iterator/ */ + FT_Byte num_layers; + FT_UInt32 first_layer_index; + + + num_layers = FT_NEXT_BYTE( p ); + if ( num_layers > colr->num_layers_v1 ) + return 0; + + first_layer_index = FT_NEXT_ULONG( p ); + if ( first_layer_index + num_layers > colr->num_layers_v1 ) + return 0; + + apaint->u.colr_layers.layer_iterator.num_layers = num_layers; + apaint->u.colr_layers.layer_iterator.layer = 0; + /* TODO: Check whether pointer is outside colr? */ + apaint->u.colr_layers.layer_iterator.p = + colr->layers_v1 + + LAYER_V1_LIST_NUM_LAYERS_SIZE + + LAYER_V1_LIST_PAINT_OFFSET_SIZE * first_layer_index; + + return 1; + } + + else if ( apaint->format == FT_COLR_PAINTFORMAT_SOLID ) + { + apaint->u.solid.color.palette_index = FT_NEXT_USHORT( p ); + apaint->u.solid.color.alpha = FT_NEXT_SHORT( p ); + + return 1; + } + + else if ( apaint->format == FT_COLR_PAINTFORMAT_COLR_GLYPH ) + { + apaint->u.colr_glyph.glyphID = FT_NEXT_USHORT( p ); + + return 1; + } + + /* + * Grouped below here are all paint formats that have an offset to a + * child paint table as the first entry (for example, a color line or a + * child paint table). Retrieve that and determine whether that paint + * offset is valid first. + */ + + if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) ) + return 0; + + if ( apaint->format == FT_COLR_PAINTFORMAT_LINEAR_GRADIENT ) + { + if ( !read_color_line( child_table_p, + &apaint->u.linear_gradient.colorline ) ) + return 0; + + /* + * In order to support variations expose these as FT_Fixed 16.16 values so + * that we can support fractional values after interpolation. + */ + apaint->u.linear_gradient.p0.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + apaint->u.linear_gradient.p0.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + apaint->u.linear_gradient.p1.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + apaint->u.linear_gradient.p1.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + apaint->u.linear_gradient.p2.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + apaint->u.linear_gradient.p2.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + + return 1; + } + + else if ( apaint->format == FT_COLR_PAINTFORMAT_RADIAL_GRADIENT ) + { + if ( !read_color_line( child_table_p, + &apaint->u.radial_gradient.colorline ) ) + return 0; + + apaint->u.radial_gradient.c0.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + apaint->u.radial_gradient.c0.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + + apaint->u.radial_gradient.r0 = FT_NEXT_USHORT( p ) << 16; + + apaint->u.radial_gradient.c1.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + apaint->u.radial_gradient.c1.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + + apaint->u.radial_gradient.r1 = FT_NEXT_USHORT( p ) << 16; + + return 1; + } + + else if ( apaint->format == FT_COLR_PAINTFORMAT_SWEEP_GRADIENT ) + { + if ( !read_color_line( child_table_p, + &apaint->u.sweep_gradient.colorline ) ) + return 0; + + apaint->u.sweep_gradient.center.x = + INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + apaint->u.sweep_gradient.center.y = + INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + + apaint->u.sweep_gradient.start_angle = + F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); + apaint->u.sweep_gradient.end_angle = + F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); + + return 1; + } + + if ( apaint->format == FT_COLR_PAINTFORMAT_GLYPH ) + { + apaint->u.glyph.paint.p = child_table_p; + apaint->u.glyph.paint.insert_root_transform = 0; + apaint->u.glyph.glyphID = FT_NEXT_USHORT( p ); + + return 1; + } + + else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSFORM ) + { + apaint->u.transform.paint.p = child_table_p; + apaint->u.transform.paint.insert_root_transform = 0; + + if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) ) + return 0; + + p = child_table_p; + + /* + * The following matrix coefficients are encoded as + * OpenType 16.16 fixed-point values. + */ + apaint->u.transform.affine.xx = FT_NEXT_LONG( p ); + apaint->u.transform.affine.yx = FT_NEXT_LONG( p ); + apaint->u.transform.affine.xy = FT_NEXT_LONG( p ); + apaint->u.transform.affine.yy = FT_NEXT_LONG( p ); + apaint->u.transform.affine.dx = FT_NEXT_LONG( p ); + apaint->u.transform.affine.dy = FT_NEXT_LONG( p ); + + return 1; + } + + else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSLATE ) + { + apaint->u.translate.paint.p = child_table_p; + apaint->u.translate.paint.insert_root_transform = 0; + + apaint->u.translate.dx = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + apaint->u.translate.dy = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + + return 1; + } + + else if ( apaint->format == + FT_COLR_PAINTFORMAT_SCALE || + (FT_PaintFormat_Internal)apaint->format == + FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER || + (FT_PaintFormat_Internal)apaint->format == + FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM || + (FT_PaintFormat_Internal)apaint->format == + FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER ) + { + apaint->u.scale.paint.p = child_table_p; + apaint->u.scale.paint.insert_root_transform = 0; + + /* All scale paints get at least one scale value. */ + apaint->u.scale.scale_x = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); + + /* Non-uniform ones read an extra y value. */ + if ( apaint->format == + FT_COLR_PAINTFORMAT_SCALE || + (FT_PaintFormat_Internal)apaint->format == + FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER ) + apaint->u.scale.scale_y = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); + else + apaint->u.scale.scale_y = apaint->u.scale.scale_x; + + /* Scale paints that have a center read center coordinates, */ + /* otherwise the center is (0,0). */ + if ( (FT_PaintFormat_Internal)apaint->format == + FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER || + (FT_PaintFormat_Internal)apaint->format == + FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER ) + { + apaint->u.scale.center_x = INT_TO_FIXED( FT_NEXT_SHORT ( p ) ); + apaint->u.scale.center_y = INT_TO_FIXED( FT_NEXT_SHORT ( p ) ); + } + else + { + apaint->u.scale.center_x = 0; + apaint->u.scale.center_y = 0; + } + + /* FT 'COLR' v1 API output format always returns fully defined */ + /* structs; we thus set the format to the public API value. */ + apaint->format = FT_COLR_PAINTFORMAT_SCALE; + + return 1; + } + + else if ( apaint->format == FT_COLR_PAINTFORMAT_ROTATE || + (FT_PaintFormat_Internal)apaint->format == + FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER ) + { + apaint->u.rotate.paint.p = child_table_p; + apaint->u.rotate.paint.insert_root_transform = 0; + + apaint->u.rotate.angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); + + if ( (FT_PaintFormat_Internal)apaint->format == + FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER ) + { + apaint->u.rotate.center_x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + apaint->u.rotate.center_y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + } + else + { + apaint->u.rotate.center_x = 0; + apaint->u.rotate.center_y = 0; + } + + apaint->format = FT_COLR_PAINTFORMAT_ROTATE; + + return 1; + } + + else if ( apaint->format == FT_COLR_PAINTFORMAT_SKEW || + (FT_PaintFormat_Internal)apaint->format == + FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER ) + { + apaint->u.skew.paint.p = child_table_p; + apaint->u.skew.paint.insert_root_transform = 0; + + apaint->u.skew.x_skew_angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); + apaint->u.skew.y_skew_angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); + + if ( (FT_PaintFormat_Internal)apaint->format == + FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER ) + { + apaint->u.skew.center_x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + apaint->u.skew.center_y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); + } + else + { + apaint->u.skew.center_x = 0; + apaint->u.skew.center_y = 0; + } + + apaint->format = FT_COLR_PAINTFORMAT_SKEW; + + return 1; + } + + else if ( apaint->format == FT_COLR_PAINTFORMAT_COMPOSITE ) + { + FT_UInt composite_mode; + + + apaint->u.composite.source_paint.p = child_table_p; + apaint->u.composite.source_paint.insert_root_transform = 0; + + composite_mode = FT_NEXT_BYTE( p ); + if ( composite_mode >= FT_COLR_COMPOSITE_MAX ) + return 0; + + apaint->u.composite.composite_mode = (FT_Composite_Mode)composite_mode; + + if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) ) + return 0; + + apaint->u.composite.backdrop_paint.p = + child_table_p; + apaint->u.composite.backdrop_paint.insert_root_transform = + 0; + + return 1; + } + + return 0; + } + + + static FT_Bool + find_base_glyph_v1_record( FT_Byte * base_glyph_begin, + FT_UInt num_base_glyph, + FT_UInt glyph_id, + BaseGlyphV1Record *record ) + { + FT_UInt min = 0; + FT_UInt max = num_base_glyph; + + + while ( min < max ) + { + FT_UInt mid = min + ( max - min ) / 2; + + /* + * `base_glyph_begin` is the beginning of `BaseGlyphV1List`; + * skip `numBaseGlyphV1Records` by adding 4 to start binary search + * in the array of `BaseGlyphV1Record`. + */ + FT_Byte *p = base_glyph_begin + 4 + mid * BASE_GLYPH_PAINT_RECORD_SIZE; + + FT_UShort gid = FT_NEXT_USHORT( p ); + + + if ( gid < glyph_id ) + min = mid + 1; + else if (gid > glyph_id ) + max = mid; + else + { + record->gid = gid; + record->paint_offset = FT_NEXT_ULONG ( p ); + return 1; + } + } + + return 0; + } + + + FT_LOCAL_DEF( FT_Bool ) + tt_face_get_colr_glyph_paint( TT_Face face, + FT_UInt base_glyph, + FT_Color_Root_Transform root_transform, + FT_OpaquePaint* opaque_paint ) + { + Colr* colr = (Colr*)face->colr; + BaseGlyphV1Record base_glyph_v1_record; + FT_Byte* p; + + if ( !colr || !colr->table ) + return 0; + + if ( colr->version < 1 || !colr->num_base_glyphs_v1 || + !colr->base_glyphs_v1 ) + return 0; + + if ( opaque_paint->p ) + return 0; + + if ( !find_base_glyph_v1_record( colr->base_glyphs_v1, + colr->num_base_glyphs_v1, + base_glyph, + &base_glyph_v1_record ) ) + return 0; + + if ( !base_glyph_v1_record.paint_offset || + base_glyph_v1_record.paint_offset > colr->table_size ) + return 0; + + p = (FT_Byte*)( colr->base_glyphs_v1 + + base_glyph_v1_record.paint_offset ); + if ( p >= ( (FT_Byte*)colr->table + colr->table_size ) ) + return 0; + + opaque_paint->p = p; + + if ( root_transform == FT_COLOR_INCLUDE_ROOT_TRANSFORM ) + opaque_paint->insert_root_transform = 1; + else + opaque_paint->insert_root_transform = 0; + + return 1; + } + + + FT_LOCAL_DEF( FT_Bool ) + tt_face_get_color_glyph_clipbox( TT_Face face, + FT_UInt base_glyph, + FT_ClipBox* clip_box ) + { + Colr* colr; + + FT_Byte *p, *p1, *clip_base; + + FT_Byte clip_list_format; + FT_ULong num_clip_boxes, i; + FT_UShort gid_start, gid_end; + FT_UInt32 clip_box_offset; + FT_Byte format; + + const FT_Byte num_corners = 4; + FT_Vector corners[4]; + FT_Byte j; + FT_BBox font_clip_box; + + + colr = (Colr*)face->colr; + if ( !colr ) + return 0; + + if ( !colr->clip_list ) + return 0; + + p = colr->clip_list; + + clip_base = p; + clip_list_format = FT_NEXT_BYTE ( p ); + + /* Format byte used here to be able to upgrade ClipList for >16bit */ + /* glyph ids; for now we can expect it to be 0. */ + if ( !( clip_list_format == 1 ) ) + return 0; + + num_clip_boxes = FT_NEXT_ULONG( p ); + + for ( i = 0; i < num_clip_boxes; ++i ) + { + gid_start = FT_NEXT_USHORT( p ); + gid_end = FT_NEXT_USHORT( p ); + clip_box_offset = FT_NEXT_UOFF3( p ); + + if ( base_glyph >= gid_start && base_glyph <= gid_end ) + { + p1 = (FT_Byte*)( clip_base + clip_box_offset ); + + if ( p1 >= ( (FT_Byte*)colr->table + colr->table_size ) ) + return 0; + + format = FT_NEXT_BYTE( p1 ); + + if ( format > 1 ) + return 0; + + /* `face->root.size->metrics.x_scale` and `y_scale` are factors */ + /* that scale a font unit value in integers to a 26.6 fixed value */ + /* according to the requested size, see for example */ + /* `ft_recompute_scaled_metrics`. */ + font_clip_box.xMin = FT_MulFix( FT_NEXT_SHORT( p1 ), + face->root.size->metrics.x_scale ); + font_clip_box.yMin = FT_MulFix( FT_NEXT_SHORT( p1 ), + face->root.size->metrics.x_scale ); + font_clip_box.xMax = FT_MulFix( FT_NEXT_SHORT( p1 ), + face->root.size->metrics.x_scale ); + font_clip_box.yMax = FT_MulFix( FT_NEXT_SHORT( p1 ), + face->root.size->metrics.x_scale ); + + /* Make 4 corner points (xMin, yMin), (xMax, yMax) and transform */ + /* them. If we we would only transform two corner points and */ + /* span a rectangle based on those, the rectangle may become too */ + /* small to cover the glyph. */ + corners[0].x = font_clip_box.xMin; + corners[1].x = font_clip_box.xMin; + corners[2].x = font_clip_box.xMax; + corners[3].x = font_clip_box.xMax; + + corners[0].y = font_clip_box.yMin; + corners[1].y = font_clip_box.yMax; + corners[2].y = font_clip_box.yMax; + corners[3].y = font_clip_box.yMin; + + for ( j = 0; j < num_corners; ++j ) + { + if ( face->root.internal->transform_flags & 1 ) + FT_Vector_Transform( &corners[j], + &face->root.internal->transform_matrix ); + + if ( face->root.internal->transform_flags & 2 ) + { + corners[j].x += face->root.internal->transform_delta.x; + corners[j].y += face->root.internal->transform_delta.y; + } + } + + clip_box->bottom_left = corners[0]; + clip_box->top_left = corners[1]; + clip_box->top_right = corners[2]; + clip_box->bottom_right = corners[3]; + + return 1; + } + } + + return 0; + } + + + FT_LOCAL_DEF( FT_Bool ) + tt_face_get_paint_layers( TT_Face face, + FT_LayerIterator* iterator, + FT_OpaquePaint* opaque_paint ) + { + FT_Byte* p = NULL; + FT_Byte* p_first_layer = NULL; + FT_Byte* p_paint = NULL; + FT_UInt32 paint_offset; + + Colr* colr; + + + if ( iterator->layer == iterator->num_layers ) + return 0; + + colr = (Colr*)face->colr; + if ( !colr ) + return 0; + + /* + * We have an iterator pointing at a paint offset as part of the + * `paintOffset` array in `LayerV1List`. + */ + p = iterator->p; + + /* + * First ensure that p is within COLRv1. + */ + if ( p < colr->layers_v1 || + p >= ( (FT_Byte*)colr->table + colr->table_size ) ) + return 0; + + /* + * Do a cursor sanity check of the iterator. Counting backwards from + * where it stands, we need to end up at a position after the beginning + * of the `LayerV1List` table and not after the end of the + * `LayerV1List`. + */ + p_first_layer = p - + iterator->layer * LAYER_V1_LIST_PAINT_OFFSET_SIZE - + LAYER_V1_LIST_NUM_LAYERS_SIZE; + if ( p_first_layer < (FT_Byte*)colr->layers_v1 ) + return 0; + if ( p_first_layer >= (FT_Byte*)( + colr->layers_v1 + LAYER_V1_LIST_NUM_LAYERS_SIZE + + colr->num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE ) ) + return 0; + + paint_offset = + FT_NEXT_ULONG( p ); + opaque_paint->insert_root_transform = + 0; + + p_paint = (FT_Byte*)( colr->layers_v1 + paint_offset ); + + if ( p_paint < colr->paints_start_v1 || + p_paint >= ( (FT_Byte*)colr->table + colr->table_size ) ) + return 0; + + opaque_paint->p = p_paint; + + iterator->p = p; + + iterator->layer++; + + return 1; + } + + + FT_LOCAL_DEF( FT_Bool ) + tt_face_get_colorline_stops( TT_Face face, + FT_ColorStop* color_stop, + FT_ColorStopIterator *iterator ) + { + Colr* colr = (Colr*)face->colr; + + FT_Byte* p; + + + if ( !colr || !colr->table ) + return 0; + + if ( iterator->current_color_stop >= iterator->num_color_stops ) + return 0; + + if ( iterator->p + + ( ( iterator->num_color_stops - iterator->current_color_stop ) * + COLOR_STOP_SIZE ) > + ( (FT_Byte *)colr->table + colr->table_size ) ) + return 0; + + /* Iterator points at first `ColorStop` of `ColorLine`. */ + p = iterator->p; + + color_stop->stop_offset = FT_NEXT_SHORT( p ); + + color_stop->color.palette_index = FT_NEXT_USHORT( p ); + + color_stop->color.alpha = FT_NEXT_SHORT( p ); + + iterator->p = p; + iterator->current_color_stop++; + + return 1; + } + + + FT_LOCAL_DEF( FT_Bool ) + tt_face_get_paint( TT_Face face, + FT_OpaquePaint opaque_paint, + FT_COLR_Paint* paint ) + { + Colr* colr = (Colr*)face->colr; + FT_OpaquePaint next_paint; + FT_Matrix ft_root_scale; + + if ( !colr || !colr->base_glyphs_v1 || !colr->table ) + return 0; + + if ( opaque_paint.insert_root_transform ) + { + /* 'COLR' v1 glyph information is returned in unscaled coordinates, + * i.e., `FT_Size` is not applied or multiplied into the values. When + * client applications draw color glyphs, they can request to include + * a top-level transform, which includes the active `x_scale` and + * `y_scale` information for scaling the glyph, as well the additional + * transform and translate configured through `FT_Set_Transform`. + * This allows client applications to apply this top-level transform + * to the graphics context first and only once, then have gradient and + * contour scaling applied correctly when performing the additional + * drawing operations for subsequenct paints. Prepare this initial + * transform here. + */ + paint->format = FT_COLR_PAINTFORMAT_TRANSFORM; + + next_paint.p = opaque_paint.p; + next_paint.insert_root_transform = 0; + paint->u.transform.paint = next_paint; + + /* `x_scale` and `y_scale` are in 26.6 format, representing the scale + * factor to get from font units to requested size. However, expected + * return values are in 16.16, so we shift accordingly with rounding. + */ + ft_root_scale.xx = ( face->root.size->metrics.x_scale + 32 ) >> 6; + ft_root_scale.xy = 0; + ft_root_scale.yx = 0; + ft_root_scale.yy = ( face->root.size->metrics.y_scale + 32 ) >> 6; + + if ( face->root.internal->transform_flags & 1 ) + FT_Matrix_Multiply( &face->root.internal->transform_matrix, + &ft_root_scale ); + + paint->u.transform.affine.xx = ft_root_scale.xx; + paint->u.transform.affine.xy = ft_root_scale.xy; + paint->u.transform.affine.yx = ft_root_scale.yx; + paint->u.transform.affine.yy = ft_root_scale.yy; + + /* The translation is specified in 26.6 format and, according to the + * documentation of `FT_Set_Translate`, is performed on the character + * size given in the last call to `FT_Set_Char_Size`. The + * 'PaintTransform' paint table's `FT_Affine23` format expects + * values in 16.16 format, thus we need to shift by 10 bits. + */ + if ( face->root.internal->transform_flags & 2 ) + { + paint->u.transform.affine.dx = + face->root.internal->transform_delta.x * ( 1 << 10 ); + paint->u.transform.affine.dy = + face->root.internal->transform_delta.y * ( 1 << 10 ); + } + else + { + paint->u.transform.affine.dx = 0; + paint->u.transform.affine.dy = 0; + } + + return 1; + } + + return read_paint( colr, opaque_paint.p, paint ); + } + + FT_LOCAL_DEF( FT_Error ) tt_face_colr_blend_layer( TT_Face face, FT_UInt color_index, diff --git a/thirdparty/freetype/src/sfnt/ttcolr.h b/thirdparty/freetype/src/sfnt/ttcolr.h index 6412162669..b81e4cb958 100644 --- a/thirdparty/freetype/src/sfnt/ttcolr.h +++ b/thirdparty/freetype/src/sfnt/ttcolr.h @@ -4,7 +4,7 @@ * * TrueType and OpenType colored glyph layer support (specification). * - * Copyright (C) 2018-2020 by + * Copyright (C) 2018-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * Originally written by Shao Yu Zhang <shaozhang@fb.com>. @@ -42,6 +42,32 @@ FT_BEGIN_HEADER FT_UInt *acolor_index, FT_LayerIterator* iterator ); + FT_LOCAL( FT_Bool ) + tt_face_get_colr_glyph_paint( TT_Face face, + FT_UInt base_glyph, + FT_Color_Root_Transform root_transform, + FT_OpaquePaint* paint ); + + FT_LOCAL( FT_Bool ) + tt_face_get_color_glyph_clipbox( TT_Face face, + FT_UInt base_glyph, + FT_ClipBox* clip_box ); + + FT_LOCAL( FT_Bool ) + tt_face_get_paint_layers( TT_Face face, + FT_LayerIterator* iterator, + FT_OpaquePaint* paint ); + + FT_LOCAL( FT_Bool ) + tt_face_get_colorline_stops( TT_Face face, + FT_ColorStop* color_stop, + FT_ColorStopIterator* iterator ); + + FT_LOCAL( FT_Bool ) + tt_face_get_paint( TT_Face face, + FT_OpaquePaint opaque_paint, + FT_COLR_Paint* paint ); + FT_LOCAL( FT_Error ) tt_face_colr_blend_layer( TT_Face face, FT_UInt color_index, diff --git a/thirdparty/freetype/src/sfnt/ttcpal.c b/thirdparty/freetype/src/sfnt/ttcpal.c index 9c514bafe5..a0d84bca3a 100644 --- a/thirdparty/freetype/src/sfnt/ttcpal.c +++ b/thirdparty/freetype/src/sfnt/ttcpal.c @@ -4,7 +4,7 @@ * * TrueType and OpenType color palette support (body). * - * Copyright (C) 2018-2020 by + * Copyright (C) 2018-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * Originally written by Shao Yu Zhang <shaozhang@fb.com>. diff --git a/thirdparty/freetype/src/sfnt/ttcpal.h b/thirdparty/freetype/src/sfnt/ttcpal.h index b544be696a..1c5586855b 100644 --- a/thirdparty/freetype/src/sfnt/ttcpal.h +++ b/thirdparty/freetype/src/sfnt/ttcpal.h @@ -4,7 +4,7 @@ * * TrueType and OpenType color palette support (specification). * - * Copyright (C) 2018-2020 by + * Copyright (C) 2018-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * Originally written by Shao Yu Zhang <shaozhang@fb.com>. diff --git a/thirdparty/freetype/src/sfnt/ttkern.c b/thirdparty/freetype/src/sfnt/ttkern.c index d4a70c7855..bb1922caf9 100644 --- a/thirdparty/freetype/src/sfnt/ttkern.c +++ b/thirdparty/freetype/src/sfnt/ttkern.c @@ -5,7 +5,7 @@ * Load the basic TrueType kerning table. This doesn't handle * kerning data within the GPOS table at the moment. * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/sfnt/ttkern.h b/thirdparty/freetype/src/sfnt/ttkern.h index f44b5bdeb0..3d8f1e8347 100644 --- a/thirdparty/freetype/src/sfnt/ttkern.h +++ b/thirdparty/freetype/src/sfnt/ttkern.h @@ -5,7 +5,7 @@ * Load the basic TrueType kerning table. This doesn't handle * kerning data within the GPOS table at the moment. * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/sfnt/ttload.c b/thirdparty/freetype/src/sfnt/ttload.c index 4b46f41357..51416d80b4 100644 --- a/thirdparty/freetype/src/sfnt/ttload.c +++ b/thirdparty/freetype/src/sfnt/ttload.c @@ -5,7 +5,7 @@ * Load the basic TrueType tables, i.e., tables that can be either in * TTF or OTF fonts (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -416,9 +416,9 @@ FT_FRAME_ENTER( sfnt.num_tables * 16L ) ) goto Exit; - FT_TRACE2(( "\n" - " tag offset length checksum\n" - " ----------------------------------\n" )); + FT_TRACE2(( "\n" )); + FT_TRACE2(( " tag offset length checksum\n" )); + FT_TRACE2(( " ----------------------------------\n" )); valid_entries = 0; for ( nn = 0; nn < sfnt.num_tables; nn++ ) @@ -505,7 +505,8 @@ FT_FRAME_EXIT(); - FT_TRACE2(( "table directory loaded\n\n" )); + FT_TRACE2(( "table directory loaded\n" )); + FT_TRACE2(( "\n" )); Exit: return error; @@ -794,8 +795,8 @@ if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) ) { FT_TRACE0(( "tt_face_load_maxp:" - " too much twilight points in `maxp' table;\n" - " " + " too much twilight points in `maxp' table;\n" )); + FT_TRACE0(( " " " some glyphs might be rendered incorrectly\n" )); maxProfile->maxTwilightPoints = 0xFFFFU - 4; @@ -836,6 +837,8 @@ FT_ULong table_pos, table_len; FT_ULong storage_start, storage_limit; TT_NameTable table; + TT_Name names = NULL; + TT_LangTag langTags = NULL; static const FT_Frame_Field name_table_fields[] = { @@ -916,13 +919,13 @@ storage_start += 2 + 4 * table->numLangTagRecords; /* allocate language tag records array */ - if ( FT_NEW_ARRAY( table->langTags, table->numLangTagRecords ) || - FT_FRAME_ENTER( table->numLangTagRecords * 4 ) ) + if ( FT_QNEW_ARRAY( langTags, table->numLangTagRecords ) || + FT_FRAME_ENTER( table->numLangTagRecords * 4 ) ) goto Exit; /* load language tags */ { - TT_LangTag entry = table->langTags; + TT_LangTag entry = langTags; TT_LangTag limit = FT_OFFSET( entry, table->numLangTagRecords ); @@ -938,7 +941,13 @@ /* invalid entry; ignore it */ entry->stringLength = 0; } + + /* mark the string as not yet loaded */ + entry->string = NULL; } + + table->langTags = langTags; + langTags = NULL; } FT_FRAME_EXIT(); @@ -947,14 +956,15 @@ } /* allocate name records array */ - if ( FT_NEW_ARRAY( table->names, table->numNameRecords ) || - FT_FRAME_ENTER( table->numNameRecords * 12 ) ) + if ( FT_QNEW_ARRAY( names, table->numNameRecords ) || + FT_FRAME_ENTER( table->numNameRecords * 12 ) ) goto Exit; /* load name records */ { - TT_Name entry = table->names; + TT_Name entry = names; FT_UInt count = table->numNameRecords; + FT_UInt valid = 0; for ( ; count > 0; count-- ) @@ -987,15 +997,20 @@ } } + /* mark the string as not yet converted */ + entry->string = NULL; + + valid++; entry++; } /* reduce array size to the actually used elements */ - count = (FT_UInt)( entry - table->names ); - (void)FT_RENEW_ARRAY( table->names, - table->numNameRecords, - count ); - table->numNameRecords = count; + FT_MEM_QRENEW_ARRAY( names, + table->numNameRecords, + valid ); + table->names = names; + names = NULL; + table->numNameRecords = valid; } FT_FRAME_EXIT(); @@ -1004,6 +1019,8 @@ face->num_names = (FT_UShort)table->numNameRecords; Exit: + FT_FREE( names ); + FT_FREE( langTags ); return error; } @@ -1311,6 +1328,12 @@ if ( FT_STREAM_READ_FIELDS( post_fields, post ) ) return error; + if ( post->FormatType != 0x00030000L && + post->FormatType != 0x00025000L && + post->FormatType != 0x00020000L && + post->FormatType != 0x00010000L ) + return FT_THROW( Invalid_Post_Table_Format ); + /* we don't load the glyph names, we do that in another */ /* module (ttpost). */ @@ -1410,8 +1433,8 @@ FT_Error error; FT_Memory memory = stream->memory; - FT_UInt j,num_ranges; - TT_GaspRange gaspranges = NULL; + FT_UShort j, num_ranges; + TT_GaspRange gasp_ranges = NULL; /* the gasp table is optional */ @@ -1422,8 +1445,8 @@ if ( FT_FRAME_ENTER( 4L ) ) goto Exit; - face->gasp.version = FT_GET_USHORT(); - face->gasp.numRanges = FT_GET_USHORT(); + face->gasp.version = FT_GET_USHORT(); + num_ranges = FT_GET_USHORT(); FT_FRAME_EXIT(); @@ -1435,29 +1458,31 @@ goto Exit; } - num_ranges = face->gasp.numRanges; - FT_TRACE3(( "numRanges: %u\n", num_ranges )); + FT_TRACE3(( "numRanges: %hu\n", num_ranges )); - if ( FT_QNEW_ARRAY( face->gasp.gaspRanges, num_ranges ) || - FT_FRAME_ENTER( num_ranges * 4L ) ) + if ( FT_QNEW_ARRAY( gasp_ranges, num_ranges ) || + FT_FRAME_ENTER( num_ranges * 4L ) ) goto Exit; - gaspranges = face->gasp.gaspRanges; - for ( j = 0; j < num_ranges; j++ ) { - gaspranges[j].maxPPEM = FT_GET_USHORT(); - gaspranges[j].gaspFlag = FT_GET_USHORT(); + gasp_ranges[j].maxPPEM = FT_GET_USHORT(); + gasp_ranges[j].gaspFlag = FT_GET_USHORT(); FT_TRACE3(( "gaspRange %d: rangeMaxPPEM %5d, rangeGaspBehavior 0x%x\n", j, - gaspranges[j].maxPPEM, - gaspranges[j].gaspFlag )); + gasp_ranges[j].maxPPEM, + gasp_ranges[j].gaspFlag )); } + face->gasp.gaspRanges = gasp_ranges; + gasp_ranges = NULL; + face->gasp.numRanges = num_ranges; + FT_FRAME_EXIT(); Exit: + FT_FREE( gasp_ranges ); return error; } diff --git a/thirdparty/freetype/src/sfnt/ttload.h b/thirdparty/freetype/src/sfnt/ttload.h index 4e53d8b782..cab15cd238 100644 --- a/thirdparty/freetype/src/sfnt/ttload.h +++ b/thirdparty/freetype/src/sfnt/ttload.h @@ -5,7 +5,7 @@ * Load the basic TrueType tables, i.e., tables that can be either in * TTF or OTF fonts (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/sfnt/ttmtx.c b/thirdparty/freetype/src/sfnt/ttmtx.c index 021123336e..7aece36fb0 100644 --- a/thirdparty/freetype/src/sfnt/ttmtx.c +++ b/thirdparty/freetype/src/sfnt/ttmtx.c @@ -4,7 +4,7 @@ * * Load the metrics tables common to TTF and OTF fonts (body). * - * Copyright (C) 2006-2020 by + * Copyright (C) 2006-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/sfnt/ttmtx.h b/thirdparty/freetype/src/sfnt/ttmtx.h index dba65ca9ba..270170d478 100644 --- a/thirdparty/freetype/src/sfnt/ttmtx.h +++ b/thirdparty/freetype/src/sfnt/ttmtx.h @@ -4,7 +4,7 @@ * * Load the metrics tables common to TTF and OTF fonts (specification). * - * Copyright (C) 2006-2020 by + * Copyright (C) 2006-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/sfnt/ttpost.c b/thirdparty/freetype/src/sfnt/ttpost.c index e93a4bf1b1..b92ca5db14 100644 --- a/thirdparty/freetype/src/sfnt/ttpost.c +++ b/thirdparty/freetype/src/sfnt/ttpost.c @@ -5,7 +5,7 @@ * PostScript name table processing for TrueType and OpenType fonts * (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -158,7 +158,7 @@ static FT_Error load_format_20( TT_Face face, FT_Stream stream, - FT_ULong post_limit ) + FT_ULong post_len ) { FT_Memory memory = stream->memory; FT_Error error; @@ -168,6 +168,7 @@ FT_UShort* glyph_indices = NULL; FT_Char** name_strings = NULL; + FT_Byte* strings = NULL; if ( FT_READ_USHORT( num_glyphs ) ) @@ -179,7 +180,8 @@ /* There already exist fonts which have more than 32768 glyph names */ /* in this table, so the test for this threshold has been dropped. */ - if ( num_glyphs > face->max_profile.numGlyphs ) + if ( num_glyphs > face->max_profile.numGlyphs || + (FT_ULong)num_glyphs * 2UL > post_len - 2 ) { error = FT_THROW( Invalid_File_Format ); goto Exit; @@ -190,7 +192,7 @@ FT_Int n; - if ( FT_NEW_ARRAY ( glyph_indices, num_glyphs ) || + if ( FT_QNEW_ARRAY( glyph_indices, num_glyphs ) || FT_FRAME_ENTER( num_glyphs * 2L ) ) goto Fail; @@ -223,60 +225,56 @@ } /* now load the name strings */ + if ( num_names ) { FT_UShort n; + FT_ULong p; - if ( FT_NEW_ARRAY( name_strings, num_names ) ) + post_len -= (FT_ULong)num_glyphs * 2UL + 2; + + if ( FT_QALLOC( strings, post_len + 1 ) || + FT_STREAM_READ( strings, post_len ) || + FT_QNEW_ARRAY( name_strings, num_names ) ) goto Fail; - for ( n = 0; n < num_names; n++ ) + /* convert from Pascal- to C-strings and set pointers */ + for ( p = 0, n = 0; p < post_len && n < num_names; n++ ) { - FT_UInt len; + FT_UInt len = strings[p]; - if ( FT_STREAM_POS() >= post_limit ) - break; - else + if ( len > 63U ) { - FT_TRACE6(( "load_format_20: %ld byte left in post table\n", - post_limit - FT_STREAM_POS() )); - - if ( FT_READ_BYTE( len ) ) - goto Fail1; - } - - if ( len > post_limit || - FT_STREAM_POS() > post_limit - len ) - { - FT_Int d = (FT_Int)post_limit - (FT_Int)FT_STREAM_POS(); - - - FT_ERROR(( "load_format_20:" - " exceeding string length (%d)," - " truncating at end of post table (%d byte left)\n", - len, d )); - len = (FT_UInt)FT_MAX( 0, d ); + error = FT_THROW( Invalid_File_Format ); + goto Fail; } - if ( FT_NEW_ARRAY( name_strings[n], len + 1 ) || - FT_STREAM_READ( name_strings[n], len ) ) - goto Fail1; - - name_strings[n][len] = '\0'; + strings[p] = 0; + name_strings[n] = (FT_Char*)strings + p + 1; + p += len + 1; } + strings[post_len] = 0; + /* deal with missing or insufficient string data */ if ( n < num_names ) { + if ( post_len == 0 ) + { + /* fake empty string */ + if ( FT_QREALLOC( strings, 1, 2 ) ) + goto Fail; + + post_len = 1; + strings[post_len] = 0; + } + FT_ERROR(( "load_format_20:" " all entries in post table are already parsed," " using NULL names for gid %d - %d\n", n, num_names - 1 )); for ( ; n < num_names; n++ ) - if ( FT_NEW_ARRAY( name_strings[n], 1 ) ) - goto Fail1; - else - name_strings[n][0] = '\0'; + name_strings[n] = (FT_Char*)strings + post_len; } } @@ -292,17 +290,9 @@ } return FT_Err_Ok; - Fail1: - { - FT_UShort n; - - - for ( n = 0; n < num_names; n++ ) - FT_FREE( name_strings[n] ); - } - Fail: FT_FREE( name_strings ); + FT_FREE( strings ); FT_FREE( glyph_indices ); Exit: @@ -313,7 +303,7 @@ static FT_Error load_format_25( TT_Face face, FT_Stream stream, - FT_ULong post_limit ) + FT_ULong post_len ) { FT_Memory memory = stream->memory; FT_Error error; @@ -321,7 +311,7 @@ FT_Int num_glyphs; FT_Char* offset_table = NULL; - FT_UNUSED( post_limit ); + FT_UNUSED( post_len ); if ( FT_READ_USHORT( num_glyphs ) ) @@ -336,7 +326,7 @@ goto Exit; } - if ( FT_NEW_ARRAY( offset_table, num_glyphs ) || + if ( FT_QNEW_ARRAY( offset_table, num_glyphs ) || FT_STREAM_READ( offset_table, num_glyphs ) ) goto Fail; @@ -384,7 +374,6 @@ FT_Error error; FT_Fixed format; FT_ULong post_len; - FT_ULong post_limit; /* get a stream for the face's resource */ @@ -395,8 +384,6 @@ if ( error ) goto Exit; - post_limit = FT_STREAM_POS() + post_len; - format = face->postscript.FormatType; /* go to beginning of subtable */ @@ -404,10 +391,10 @@ goto Exit; /* now read postscript table */ - if ( format == 0x00020000L ) - error = load_format_20( face, stream, post_limit ); - else if ( format == 0x00025000L ) - error = load_format_25( face, stream, post_limit ); + if ( format == 0x00020000L && post_len >= 34 ) + error = load_format_20( face, stream, post_len - 32 ); + else if ( format == 0x00025000L && post_len >= 34 ) + error = load_format_25( face, stream, post_len - 32 ); else error = FT_THROW( Invalid_File_Format ); @@ -433,17 +420,19 @@ if ( format == 0x00020000L ) { TT_Post_20 table = &names->names.format_20; - FT_UShort n; FT_FREE( table->glyph_indices ); table->num_glyphs = 0; - for ( n = 0; n < table->num_names; n++ ) - FT_FREE( table->glyph_names[n] ); + if ( table->num_names ) + { + table->glyph_names[0]--; + FT_FREE( table->glyph_names[0] ); - FT_FREE( table->glyph_names ); - table->num_names = 0; + FT_FREE( table->glyph_names ); + table->num_names = 0; + } } else if ( format == 0x00025000L ) { diff --git a/thirdparty/freetype/src/sfnt/ttpost.h b/thirdparty/freetype/src/sfnt/ttpost.h index 94c7d16800..6d65b5766c 100644 --- a/thirdparty/freetype/src/sfnt/ttpost.h +++ b/thirdparty/freetype/src/sfnt/ttpost.h @@ -5,7 +5,7 @@ * PostScript name table processing for TrueType and OpenType fonts * (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/sfnt/ttsbit.c b/thirdparty/freetype/src/sfnt/ttsbit.c index 9dd4419710..e9ba697dba 100644 --- a/thirdparty/freetype/src/sfnt/ttsbit.c +++ b/thirdparty/freetype/src/sfnt/ttsbit.c @@ -4,7 +4,7 @@ * * TrueType and OpenType embedded bitmap support (body). * - * Copyright (C) 2005-2020 by + * Copyright (C) 2005-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * Copyright 2013 by Google, Inc. @@ -172,13 +172,17 @@ goto Exit; } +#ifdef FT_DEBUG_LEVEL_TRACE /* we currently don't support bit 1; however, it is better to */ /* draw at least something... */ if ( flags == 3 ) + { FT_TRACE1(( "tt_face_load_sbit_strikes:" - " sbix overlay not supported yet\n" - " " + " sbix overlay not supported yet\n" )); + FT_TRACE1(( " " " expect bad rendering results\n" )); + } +#endif /* * Count the number of strikes available in the table. We are a bit @@ -240,8 +244,8 @@ if ( !face->ebdt_size ) { FT_TRACE2(( "tt_face_load_sbit_strikes:" - " no embedded bitmap data table found;\n" - " " + " no embedded bitmap data table found;\n" )); + FT_TRACE2(( " " " resetting number of strikes to zero\n" )); face->sbit_num_strikes = 0; } @@ -345,8 +349,8 @@ if ( metrics->ascender == 0 ) { FT_TRACE2(( "tt_face_load_strike_metrics:" - " sanitizing invalid ascender and descender\n" - " " + " sanitizing invalid ascender and descender\n" )); + FT_TRACE2(( " " " values for strike %ld (%dppem, %dppem)\n", strike_index, metrics->x_ppem, metrics->y_ppem )); @@ -374,8 +378,8 @@ if ( metrics->height == 0 ) { FT_TRACE2(( "tt_face_load_strike_metrics:" - " sanitizing invalid height value\n" - " " + " sanitizing invalid height value\n" )); + FT_TRACE2(( " " " for strike (%d, %d)\n", metrics->x_ppem, metrics->y_ppem )); metrics->height = metrics->y_ppem * 64; diff --git a/thirdparty/freetype/src/sfnt/ttsbit.h b/thirdparty/freetype/src/sfnt/ttsbit.h index b867e43a61..7a0ed92e92 100644 --- a/thirdparty/freetype/src/sfnt/ttsbit.h +++ b/thirdparty/freetype/src/sfnt/ttsbit.h @@ -4,7 +4,7 @@ * * TrueType and OpenType embedded bitmap support (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/sfnt/woff2tags.c b/thirdparty/freetype/src/sfnt/woff2tags.c index fd9f2e6c5d..fe8f5cf76f 100644 --- a/thirdparty/freetype/src/sfnt/woff2tags.c +++ b/thirdparty/freetype/src/sfnt/woff2tags.c @@ -4,7 +4,7 @@ * * WOFF2 Font table tags (base). * - * Copyright (C) 2019-2020 by + * Copyright (C) 2019-2021 by * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -17,6 +17,9 @@ #include <freetype/tttags.h> + +#ifdef FT_CONFIG_OPTION_USE_BROTLI + #include "woff2tags.h" /* @@ -28,10 +31,10 @@ * * for details. */ - FT_LOCAL_DEF( FT_ULong ) + FT_LOCAL_DEF( FT_Tag ) woff2_known_tags( FT_Byte index ) { - const FT_ULong known_tags[63] = + static const FT_Tag known_tags[63] = { FT_MAKE_TAG('c', 'm', 'a', 'p'), /* 0 */ FT_MAKE_TAG('h', 'e', 'a', 'd'), /* 1 */ @@ -105,5 +108,12 @@ return known_tags[index]; } +#else /* !FT_CONFIG_OPTION_USE_BROTLI */ + + /* ANSI C doesn't like empty source files */ + typedef int _woff2tags_dummy; + +#endif /* !FT_CONFIG_OPTION_USE_BROTLI */ + /* END */ diff --git a/thirdparty/freetype/src/sfnt/woff2tags.h b/thirdparty/freetype/src/sfnt/woff2tags.h index c437c77aa1..4ef0a651c3 100644 --- a/thirdparty/freetype/src/sfnt/woff2tags.h +++ b/thirdparty/freetype/src/sfnt/woff2tags.h @@ -2,9 +2,9 @@ * * woff2tags.h * - * WOFFF2 Font table tags (specification). + * WOFF2 Font table tags (specification). * - * Copyright (C) 2019-2020 by + * Copyright (C) 2019-2021 by * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -26,10 +26,12 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_USE_BROTLI - FT_LOCAL( FT_ULong ) + FT_LOCAL( FT_Tag ) woff2_known_tags( FT_Byte index ); +#endif FT_END_HEADER diff --git a/thirdparty/freetype/src/smooth/ftgrays.c b/thirdparty/freetype/src/smooth/ftgrays.c index 681900fd40..d982c2820b 100644 --- a/thirdparty/freetype/src/smooth/ftgrays.c +++ b/thirdparty/freetype/src/smooth/ftgrays.c @@ -4,7 +4,7 @@ * * A new `perfect' anti-aliasing renderer (body). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -149,14 +149,10 @@ #define FT_INT_MAX INT_MAX #define FT_ULONG_MAX ULONG_MAX -#define ADD_LONG( a, b ) \ - (long)( (unsigned long)(a) + (unsigned long)(b) ) -#define SUB_LONG( a, b ) \ - (long)( (unsigned long)(a) - (unsigned long)(b) ) -#define MUL_LONG( a, b ) \ - (long)( (unsigned long)(a) * (unsigned long)(b) ) -#define NEG_LONG( a ) \ - (long)( -(unsigned long)(a) ) +#define ADD_INT( a, b ) \ + (int)( (unsigned int)(a) + (unsigned int)(b) ) + +#define FT_STATIC_BYTE_CAST( type, var ) (type)(unsigned char)(var) #define ft_memset memset @@ -168,10 +164,11 @@ typedef ptrdiff_t FT_PtrDist; -#define ErrRaster_Invalid_Mode -2 -#define ErrRaster_Invalid_Outline -1 -#define ErrRaster_Invalid_Argument -3 -#define ErrRaster_Memory_Overflow -4 +#define Smooth_Err_Ok 0 +#define Smooth_Err_Invalid_Outline -1 +#define Smooth_Err_Cannot_Render_Glyph -2 +#define Smooth_Err_Invalid_Argument -3 +#define Smooth_Err_Raster_Overflow -4 #define FT_BEGIN_HEADER #define FT_END_HEADER @@ -229,23 +226,26 @@ typedef ptrdiff_t FT_PtrDist; #define FT_ERROR( varformat ) FT_Message varformat #endif -#define FT_THROW( e ) \ - ( FT_Throw( FT_ERR_CAT( ErrRaster_, e ), \ - __LINE__, \ - __FILE__ ) | \ - FT_ERR_CAT( ErrRaster_, e ) ) +#define FT_THROW( e ) \ + ( FT_Throw( FT_ERR_CAT( Smooth_Err_, e ), \ + __LINE__, \ + __FILE__ ) | \ + FT_ERR_CAT( Smooth_Err_, e ) ) #else /* !FT_DEBUG_LEVEL_TRACE */ #define FT_TRACE5( x ) do { } while ( 0 ) /* nothing */ #define FT_TRACE7( x ) do { } while ( 0 ) /* nothing */ #define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ -#define FT_THROW( e ) FT_ERR_CAT( ErrRaster_, e ) - +#define FT_THROW( e ) FT_ERR_CAT( Smooth_Err_, e ) #endif /* !FT_DEBUG_LEVEL_TRACE */ +#define FT_Trace_Enable() do { } while ( 0 ) /* nothing */ +#define FT_Trace_Disable() do { } while ( 0 ) /* nothing */ + + #define FT_DEFINE_OUTLINE_FUNCS( class_, \ move_to_, line_to_, \ conic_to_, cubic_to_, \ @@ -278,6 +278,8 @@ typedef ptrdiff_t FT_PtrDist; #else /* !STANDALONE_ */ +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H #include "ftgrays.h" #include <freetype/internal/ftobjs.h> #include <freetype/internal/ftdebug.h> @@ -286,10 +288,6 @@ typedef ptrdiff_t FT_PtrDist; #include "ftsmerrs.h" -#define Smooth_Err_Invalid_Mode Smooth_Err_Cannot_Render_Glyph -#define Smooth_Err_Memory_Overflow Smooth_Err_Out_Of_Memory -#define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory - #endif /* !STANDALONE_ */ @@ -362,7 +360,7 @@ typedef ptrdiff_t FT_PtrDist; } \ FT_END_STMNT -#ifdef __arm__ +#if defined( __GNUC__ ) && __GNUC__ < 7 && defined( __arm__ ) /* Work around a bug specific to GCC which make the compiler fail to */ /* optimize a division and modulo operation on the same parameters */ /* into a single call to `__aeabi_idivmod'. See */ @@ -382,14 +380,58 @@ typedef ptrdiff_t FT_PtrDist; #endif /* __arm__ */ - /* These macros speed up repetitive divisions by replacing them */ - /* with multiplications and right shifts. */ -#define FT_UDIVPREP( c, b ) \ - long b ## _r = c ? (long)( FT_ULONG_MAX >> PIXEL_BITS ) / ( b ) \ - : 0 -#define FT_UDIV( a, b ) \ - (TCoord)( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >> \ - ( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) ) + /* Calculating coverages for a slanted line requires a division each */ + /* time the line crosses from cell to cell. These macros speed up */ + /* the repetitive divisions by replacing them with multiplications */ + /* and right shifts so that at most two divisions are performed for */ + /* each slanted line. Nevertheless, these divisions are noticeable */ + /* in the overall performance because flattened curves produce a */ + /* very large number of slanted lines. */ + /* */ + /* The division results here are always within ONE_PIXEL. Therefore */ + /* the shift magnitude should be at least PIXEL_BITS wider than the */ + /* divisors to provide sufficient accuracy of the multiply-shift. */ + /* It should not exceed (64 - PIXEL_BITS) to prevent overflowing and */ + /* leave enough room for 64-bit unsigned multiplication however. */ +#define FT_UDIVPREP( c, b ) \ + FT_Int64 b ## _r = c ? (FT_Int64)0xFFFFFFFF / ( b ) : 0 +#define FT_UDIV( a, b ) \ + (TCoord)( ( (FT_UInt64)( a ) * (FT_UInt64)( b ## _r ) ) >> 32 ) + + + /* Scale area and apply fill rule to calculate the coverage byte. */ + /* The top fill bit is used for the non-zero rule. The eighth */ + /* fill bit is used for the even-odd rule. The higher coverage */ + /* bytes are either clamped for the non-zero-rule or discarded */ + /* later for the even-odd rule. */ +#define FT_FILL_RULE( coverage, area, fill ) \ + FT_BEGIN_STMNT \ + coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) ); \ + if ( coverage & fill ) \ + coverage = ~coverage; \ + if ( coverage > 255 && fill & INT_MIN ) \ + coverage = 255; \ + FT_END_STMNT + + + /* It is faster to write small spans byte-by-byte than calling */ + /* `memset'. This is mainly due to the cost of the function call. */ +#define FT_GRAY_SET( d, s, count ) \ + FT_BEGIN_STMNT \ + unsigned char* q = d; \ + switch ( count ) \ + { \ + case 7: *q++ = (unsigned char)s; /* fall through */ \ + case 6: *q++ = (unsigned char)s; /* fall through */ \ + case 5: *q++ = (unsigned char)s; /* fall through */ \ + case 4: *q++ = (unsigned char)s; /* fall through */ \ + case 3: *q++ = (unsigned char)s; /* fall through */ \ + case 2: *q++ = (unsigned char)s; /* fall through */ \ + case 1: *q = (unsigned char)s; /* fall through */ \ + case 0: break; \ + default: FT_MEM_SET( d, s, count ); \ + } \ + FT_END_STMNT /************************************************************************** @@ -432,7 +474,7 @@ typedef ptrdiff_t FT_PtrDist; #endif /* FT_Span buffer size for direct rendering only */ -#define FT_MAX_GRAY_SPANS 10 +#define FT_MAX_GRAY_SPANS 16 #if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ @@ -447,28 +489,24 @@ typedef ptrdiff_t FT_PtrDist; { ft_jmp_buf jump_buffer; - TCoord ex, ey; - TCoord min_ex, max_ex; + TCoord min_ex, max_ex; /* min and max integer pixel coordinates */ TCoord min_ey, max_ey; + TCoord count_ey; /* same as (max_ey - min_ey) */ - TArea area; - TCoord cover; - int invalid; + PCell cell; /* current cell */ + PCell cell_free; /* call allocation next free slot */ + PCell cell_null; /* last cell, used as dumpster and limit */ - PCell* ycells; - PCell cells; - FT_PtrDist max_cells; - FT_PtrDist num_cells; + PCell* ycells; /* array of cell linked-lists; one per */ + /* vertical coordinate in the current band */ - TPos x, y; + TPos x, y; /* last point position */ - FT_Outline outline; - TPixmap target; + FT_Outline outline; /* input outline */ + TPixmap target; /* target pixmap */ FT_Raster_Span_Func render_span; void* render_span_data; - FT_Span spans[FT_MAX_GRAY_SPANS]; - int num_spans; } gray_TWorker, *gray_PWorker; @@ -476,17 +514,25 @@ typedef ptrdiff_t FT_PtrDist; #pragma warning( pop ) #endif - #ifndef FT_STATIC_RASTER #define ras (*worker) #else static gray_TWorker ras; #endif + /* The |x| value of the null cell. Must be the largest possible */ + /* integer value stored in a `TCell.x` field. */ +#define CELL_MAX_X_VALUE INT_MAX + + +#define FT_INTEGRATE( ras, a, b ) \ + ras.cell->cover = ADD_INT( ras.cell->cover, a ), \ + ras.cell->area = ADD_INT( ras.cell->area, (a) * (TArea)(b) ) + typedef struct gray_TRaster_ { - void* memory; + void* memory; } gray_TRaster, *gray_PRaster; @@ -508,7 +554,7 @@ typedef ptrdiff_t FT_PtrDist; printf( "%3d:", y ); - for ( ; cell != NULL; cell = cell->next ) + for ( ; cell != ras.cell_null; cell = cell->next ) printf( " (%3d, c:%4d, a:%6d)", cell->x, cell->cover, cell->area ); printf( "\n" ); @@ -520,81 +566,67 @@ typedef ptrdiff_t FT_PtrDist; /************************************************************************** * - * Record the current cell in the linked list. + * Set the current cell to a new position. */ static void - gray_record_cell( RAS_ARG ) + gray_set_cell( RAS_ARG_ TCoord ex, + TCoord ey ) { - PCell *pcell, cell; - TCoord x = ras.ex; - + /* Move the cell pointer to a new position in the linked list. We use */ + /* a dumpster null cell for everything outside of the clipping region */ + /* during the render phase. This means that: */ + /* */ + /* . the new vertical position must be within min_ey..max_ey-1. */ + /* . the new horizontal position must be strictly less than max_ex */ + /* */ + /* Note that if a cell is to the left of the clipping region, it is */ + /* actually set to the (min_ex-1) horizontal position. */ - pcell = &ras.ycells[ras.ey - ras.min_ey]; - while ( ( cell = *pcell ) ) - { - if ( cell->x > x ) - break; + TCoord ey_index = ey - ras.min_ey; - if ( cell->x == x ) - goto Found; - pcell = &cell->next; - } + if ( ey_index < 0 || ey_index >= ras.count_ey || ex >= ras.max_ex ) + ras.cell = ras.cell_null; + else + { + PCell* pcell = ras.ycells + ey_index; + PCell cell; - if ( ras.num_cells >= ras.max_cells ) - ft_longjmp( ras.jump_buffer, 1 ); - /* insert new cell */ - cell = ras.cells + ras.num_cells++; - cell->x = x; - cell->area = ras.area; - cell->cover = ras.cover; + ex = FT_MAX( ex, ras.min_ex - 1 ); - cell->next = *pcell; - *pcell = cell; + while ( 1 ) + { + cell = *pcell; - return; + if ( cell->x > ex ) + break; - Found: - /* update old cell */ - cell->area += ras.area; - cell->cover += ras.cover; - } + if ( cell->x == ex ) + goto Found; + pcell = &cell->next; + } - /************************************************************************** - * - * Set the current cell to a new position. - */ - static void - gray_set_cell( RAS_ARG_ TCoord ex, - TCoord ey ) - { - /* Move the cell pointer to a new position. We set the `invalid' */ - /* flag to indicate that the cell isn't part of those we're interested */ - /* in during the render phase. This means that: */ - /* */ - /* . the new vertical position must be within min_ey..max_ey-1. */ - /* . the new horizontal position must be strictly less than max_ex */ - /* */ - /* Note that if a cell is to the left of the clipping region, it is */ - /* actually set to the (min_ex-1) horizontal position. */ + /* insert new cell */ + cell = ras.cell_free++; + if ( cell >= ras.cell_null ) + ft_longjmp( ras.jump_buffer, 1 ); - /* record the current one if it is valid and substantial */ - if ( !ras.invalid && ( ras.area || ras.cover ) ) - gray_record_cell( RAS_VAR ); + cell->x = ex; + cell->area = 0; + cell->cover = 0; - ras.area = 0; - ras.cover = 0; - ras.ex = FT_MAX( ex, ras.min_ex - 1 ); - ras.ey = ey; + cell->next = *pcell; + *pcell = cell; - ras.invalid = ( ey >= ras.max_ey || ey < ras.min_ey || - ex >= ras.max_ex ); + Found: + ras.cell = cell; + } } -#ifndef FT_LONG64 +#ifndef FT_INT64 /************************************************************************** * @@ -622,8 +654,8 @@ typedef ptrdiff_t FT_PtrDist; return; } - fx1 = FRACT( x1 ); - fx2 = FRACT( x2 ); + fx1 = FRACT( x1 ); + fx2 = FRACT( x2 ); /* everything is located in a single cell. That is easy! */ /* */ @@ -655,10 +687,9 @@ typedef ptrdiff_t FT_PtrDist; /* XXX: y-delta and x-delta below should be related. */ FT_DIV_MOD( TCoord, p, dx, delta, mod ); - ras.area += (TArea)( ( fx1 + first ) * delta ); - ras.cover += delta; - y1 += delta; - ex1 += incr; + FT_INTEGRATE( ras, delta, fx1 + first ); + y1 += delta; + ex1 += incr; gray_set_cell( RAS_VAR_ ex1, ey ); if ( ex1 != ex2 ) @@ -679,10 +710,9 @@ typedef ptrdiff_t FT_PtrDist; delta++; } - ras.area += (TArea)( ONE_PIXEL * delta ); - ras.cover += delta; - y1 += delta; - ex1 += incr; + FT_INTEGRATE( ras, delta, ONE_PIXEL ); + y1 += delta; + ex1 += incr; gray_set_cell( RAS_VAR_ ex1, ey ); } while ( ex1 != ex2 ); } @@ -690,10 +720,7 @@ typedef ptrdiff_t FT_PtrDist; fx1 = ONE_PIXEL - first; End: - dy = y2 - y1; - - ras.area += (TArea)( ( fx1 + fx2 ) * dy ); - ras.cover += dy; + FT_INTEGRATE( ras, y2 - y1, fx1 + fx2 ); } @@ -736,7 +763,6 @@ typedef ptrdiff_t FT_PtrDist; { TCoord ex = TRUNC( ras.x ); TCoord two_fx = FRACT( ras.x ) << 1; - TArea area; if ( dy > 0) @@ -750,27 +776,23 @@ typedef ptrdiff_t FT_PtrDist; incr = -1; } - delta = first - fy1; - ras.area += (TArea)two_fx * delta; - ras.cover += delta; - ey1 += incr; + delta = first - fy1; + FT_INTEGRATE( ras, delta, two_fx); + ey1 += incr; gray_set_cell( RAS_VAR_ ex, ey1 ); delta = first + first - ONE_PIXEL; - area = (TArea)two_fx * delta; while ( ey1 != ey2 ) { - ras.area += area; - ras.cover += delta; - ey1 += incr; + FT_INTEGRATE( ras, delta, two_fx); + ey1 += incr; gray_set_cell( RAS_VAR_ ex, ey1 ); } - delta = fy2 - ONE_PIXEL + first; - ras.area += (TArea)two_fx * delta; - ras.cover += delta; + delta = fy2 - ONE_PIXEL + first; + FT_INTEGRATE( ras, delta, two_fx); goto End; } @@ -883,8 +905,7 @@ typedef ptrdiff_t FT_PtrDist; do { fy2 = ONE_PIXEL; - ras.cover += ( fy2 - fy1 ); - ras.area += ( fy2 - fy1 ) * fx1 * 2; + FT_INTEGRATE( ras, fy2 - fy1, fx1 * 2 ); fy1 = 0; ey1++; gray_set_cell( RAS_VAR_ ex1, ey1 ); @@ -893,8 +914,7 @@ typedef ptrdiff_t FT_PtrDist; do { fy2 = 0; - ras.cover += ( fy2 - fy1 ); - ras.area += ( fy2 - fy1 ) * fx1 * 2; + FT_INTEGRATE( ras, fy2 - fy1, fx1 * 2 ); fy1 = ONE_PIXEL; ey1--; gray_set_cell( RAS_VAR_ ex1, ey1 ); @@ -902,7 +922,7 @@ typedef ptrdiff_t FT_PtrDist; } else /* any other line */ { - TPos prod = dx * (TPos)fy1 - dy * (TPos)fx1; + FT_Int64 prod = dx * (FT_Int64)fy1 - dy * (FT_Int64)fx1; FT_UDIVPREP( ex1 != ex2, dx ); FT_UDIVPREP( ey1 != ey2, dy ); @@ -912,72 +932,308 @@ typedef ptrdiff_t FT_PtrDist; /* also easily updated when moving from one cell to the next. */ do { - if ( prod <= 0 && - prod - dx * ONE_PIXEL > 0 ) /* left */ + if ( prod - dx * ONE_PIXEL > 0 && + prod <= 0 ) /* left */ { fx2 = 0; fy2 = FT_UDIV( -prod, -dx ); prod -= dy * ONE_PIXEL; - ras.cover += ( fy2 - fy1 ); - ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + FT_INTEGRATE( ras, fy2 - fy1, fx1 + fx2 ); fx1 = ONE_PIXEL; fy1 = fy2; ex1--; } - else if ( prod - dx * ONE_PIXEL <= 0 && - prod - dx * ONE_PIXEL + dy * ONE_PIXEL > 0 ) /* up */ + else if ( prod - dx * ONE_PIXEL + dy * ONE_PIXEL > 0 && + prod - dx * ONE_PIXEL <= 0 ) /* up */ { prod -= dx * ONE_PIXEL; fx2 = FT_UDIV( -prod, dy ); fy2 = ONE_PIXEL; - ras.cover += ( fy2 - fy1 ); - ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + FT_INTEGRATE( ras, fy2 - fy1, fx1 + fx2 ); fx1 = fx2; fy1 = 0; ey1++; } - else if ( prod - dx * ONE_PIXEL + dy * ONE_PIXEL <= 0 && - prod + dy * ONE_PIXEL >= 0 ) /* right */ + else if ( prod + dy * ONE_PIXEL >= 0 && + prod - dx * ONE_PIXEL + dy * ONE_PIXEL <= 0 ) /* right */ { prod += dy * ONE_PIXEL; fx2 = ONE_PIXEL; fy2 = FT_UDIV( prod, dx ); - ras.cover += ( fy2 - fy1 ); - ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + FT_INTEGRATE( ras, fy2 - fy1, fx1 + fx2 ); fx1 = 0; fy1 = fy2; ex1++; } - else /* ( prod + dy * ONE_PIXEL < 0 && - prod > 0 ) down */ + else /* ( prod > 0 && + prod + dy * ONE_PIXEL < 0 ) down */ { fx2 = FT_UDIV( prod, -dy ); fy2 = 0; prod += dx * ONE_PIXEL; - ras.cover += ( fy2 - fy1 ); - ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + FT_INTEGRATE( ras, fy2 - fy1, fx1 + fx2 ); fx1 = fx2; fy1 = ONE_PIXEL; ey1--; } gray_set_cell( RAS_VAR_ ex1, ey1 ); + } while ( ex1 != ex2 || ey1 != ey2 ); } fx2 = FRACT( to_x ); fy2 = FRACT( to_y ); - ras.cover += ( fy2 - fy1 ); - ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + FT_INTEGRATE( ras, fy2 - fy1, fx1 + fx2 ); End: - ras.x = to_x; - ras.y = to_y; + ras.x = to_x; + ras.y = to_y; } #endif + /* + * Benchmarking shows that using DDA to flatten the quadratic Bézier arcs + * is slightly faster in the following cases: + * + * - When the host CPU is 64-bit. + * - When SSE2 SIMD registers and instructions are available (even on + * x86). + * + * For other cases, using binary splits is actually slightly faster. + */ +#if defined( __SSE2__ ) || \ + defined( __x86_64__ ) || \ + defined( _M_AMD64 ) || \ + ( defined( _M_IX86_FP ) && _M_IX86_FP >= 2 ) +# define FT_SSE2 1 +#else +# define FT_SSE2 0 +#endif + +#if FT_SSE2 || \ + defined( __aarch64__ ) || \ + defined( _M_ARM64 ) +# define BEZIER_USE_DDA 1 +#else +# define BEZIER_USE_DDA 0 +#endif + + /* + * For now, the code that depends on `BEZIER_USE_DDA` requires `FT_Int64` + * to be defined. If `FT_INT64` is not defined, meaning there is no + * 64-bit type available, disable it to avoid compilation errors. See for + * example https://gitlab.freedesktop.org/freetype/freetype/-/issues/1071. + */ +#if !defined( FT_INT64 ) +# undef BEZIER_USE_DDA +# define BEZIER_USE_DDA 0 +#endif + +#if BEZIER_USE_DDA + +#if FT_SSE2 +# include <emmintrin.h> +#endif + +#define LEFT_SHIFT( a, b ) (FT_Int64)( (FT_UInt64)(a) << (b) ) + + + static void + gray_render_conic( RAS_ARG_ const FT_Vector* control, + const FT_Vector* to ) + { + FT_Vector p0, p1, p2; + TPos ax, ay, bx, by, dx, dy; + int shift; + + FT_Int64 rx, ry; + FT_Int64 qx, qy; + FT_Int64 px, py; + + FT_UInt count; + + + p0.x = ras.x; + p0.y = ras.y; + p1.x = UPSCALE( control->x ); + p1.y = UPSCALE( control->y ); + p2.x = UPSCALE( to->x ); + p2.y = UPSCALE( to->y ); + + /* short-cut the arc that crosses the current band */ + if ( ( TRUNC( p0.y ) >= ras.max_ey && + TRUNC( p1.y ) >= ras.max_ey && + TRUNC( p2.y ) >= ras.max_ey ) || + ( TRUNC( p0.y ) < ras.min_ey && + TRUNC( p1.y ) < ras.min_ey && + TRUNC( p2.y ) < ras.min_ey ) ) + { + ras.x = p2.x; + ras.y = p2.y; + return; + } + + bx = p1.x - p0.x; + by = p1.y - p0.y; + ax = p2.x - p1.x - bx; /* p0.x + p2.x - 2 * p1.x */ + ay = p2.y - p1.y - by; /* p0.y + p2.y - 2 * p1.y */ + + dx = FT_ABS( ax ); + dy = FT_ABS( ay ); + if ( dx < dy ) + dx = dy; + + if ( dx <= ONE_PIXEL / 4 ) + { + gray_render_line( RAS_VAR_ p2.x, p2.y ); + return; + } + + /* We can calculate the number of necessary bisections because */ + /* each bisection predictably reduces deviation exactly 4-fold. */ + /* Even 32-bit deviation would vanish after 16 bisections. */ + shift = 0; + do + { + dx >>= 2; + shift += 1; + + } while ( dx > ONE_PIXEL / 4 ); + + /* + * The (P0,P1,P2) arc equation, for t in [0,1] range: + * + * P(t) = P0*(1-t)^2 + P1*2*t*(1-t) + P2*t^2 + * + * P(t) = P0 + 2*(P1-P0)*t + (P0+P2-2*P1)*t^2 + * = P0 + 2*B*t + A*t^2 + * + * for A = P0 + P2 - 2*P1 + * and B = P1 - P0 + * + * Let's consider the difference when advancing by a small + * parameter h: + * + * Q(h,t) = P(t+h) - P(t) = 2*B*h + A*h^2 + 2*A*h*t + * + * And then its own difference: + * + * R(h,t) = Q(h,t+h) - Q(h,t) = 2*A*h*h = R (constant) + * + * Since R is always a constant, it is possible to compute + * successive positions with: + * + * P = P0 + * Q = Q(h,0) = 2*B*h + A*h*h + * R = 2*A*h*h + * + * loop: + * P += Q + * Q += R + * EMIT(P) + * + * To ensure accurate results, perform computations on 64-bit + * values, after scaling them by 2^32. + * + * h = 1 / 2^N + * + * R << 32 = 2 * A << (32 - N - N) + * = A << (33 - 2*N) + * + * Q << 32 = (2 * B << (32 - N)) + (A << (32 - N - N)) + * = (B << (33 - N)) + (A << (32 - 2*N)) + */ + +#if FT_SSE2 + /* Experience shows that for small shift values, */ + /* SSE2 is actually slower. */ + if ( shift > 2 ) + { + union + { + struct { FT_Int64 ax, ay, bx, by; } i; + struct { __m128i a, b; } vec; + + } u; + + union + { + struct { FT_Int32 px_lo, px_hi, py_lo, py_hi; } i; + __m128i vec; + + } v; + + __m128i a, b; + __m128i r, q, q2; + __m128i p; + + + u.i.ax = ax; + u.i.ay = ay; + u.i.bx = bx; + u.i.by = by; + + a = _mm_load_si128( &u.vec.a ); + b = _mm_load_si128( &u.vec.b ); + + r = _mm_slli_epi64( a, 33 - 2 * shift ); + q = _mm_slli_epi64( b, 33 - shift ); + q2 = _mm_slli_epi64( a, 32 - 2 * shift ); + + q = _mm_add_epi64( q2, q ); + + v.i.px_lo = 0; + v.i.px_hi = p0.x; + v.i.py_lo = 0; + v.i.py_hi = p0.y; + + p = _mm_load_si128( &v.vec ); + + for ( count = 1U << shift; count > 0; count-- ) + { + p = _mm_add_epi64( p, q ); + q = _mm_add_epi64( q, r ); + + _mm_store_si128( &v.vec, p ); + + gray_render_line( RAS_VAR_ v.i.px_hi, v.i.py_hi ); + } + + return; + } +#endif /* FT_SSE2 */ + + rx = LEFT_SHIFT( ax, 33 - 2 * shift ); + ry = LEFT_SHIFT( ay, 33 - 2 * shift ); + + qx = LEFT_SHIFT( bx, 33 - shift ) + LEFT_SHIFT( ax, 32 - 2 * shift ); + qy = LEFT_SHIFT( by, 33 - shift ) + LEFT_SHIFT( ay, 32 - 2 * shift ); + + px = LEFT_SHIFT( p0.x, 32 ); + py = LEFT_SHIFT( p0.y, 32 ); + + for ( count = 1U << shift; count > 0; count-- ) + { + px += qx; + py += qy; + qx += rx; + qy += ry; + + gray_render_line( RAS_VAR_ (FT_Pos)( px >> 32 ), + (FT_Pos)( py >> 32 ) ); + } + } + +#else /* !BEZIER_USE_DDA */ + + /* + * Note that multiple attempts to speed up the function below + * with SSE2 intrinsics, using various data layouts, have turned + * out to be slower than the non-SIMD code below. + */ static void gray_split_conic( FT_Vector* base ) { @@ -1007,7 +1263,7 @@ typedef ptrdiff_t FT_PtrDist; FT_Vector bez_stack[16 * 2 + 1]; /* enough to accommodate bisections */ FT_Vector* arc = bez_stack; TPos dx, dy; - int draw, split; + int draw; arc[0].x = UPSCALE( to->x ); @@ -1050,7 +1306,9 @@ typedef ptrdiff_t FT_PtrDist; /* many times as there are trailing zeros in the counter. */ do { - split = draw & ( -draw ); /* isolate the rightmost 1-bit */ + int split = draw & ( -draw ); /* isolate the rightmost 1-bit */ + + while ( ( split >>= 1 ) ) { gray_split_conic( arc ); @@ -1063,7 +1321,17 @@ typedef ptrdiff_t FT_PtrDist; } while ( --draw ); } +#endif /* !BEZIER_USE_DDA */ + + /* + * For cubic Bézier, binary splits are still faster than DDA + * because the splits are adaptive to how quickly each sub-arc + * approaches their chord trisection points. + * + * It might be useful to experiment with SSE2 to speed up + * `gray_split_cubic`, though. + */ static void gray_split_cubic( FT_Vector* base ) { @@ -1205,125 +1473,133 @@ typedef ptrdiff_t FT_PtrDist; static void - gray_hline( RAS_ARG_ TCoord x, - TCoord y, - TArea coverage, - TCoord acount ) + gray_sweep( RAS_ARG ) { - /* scale the coverage from 0..(ONE_PIXEL*ONE_PIXEL*2) to 0..256 */ - coverage >>= PIXEL_BITS * 2 + 1 - 8; + int fill = ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) ? 0x100 + : INT_MIN; + int coverage; + int y; - /* compute the line's coverage depending on the outline fill rule */ - if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) - { - coverage &= 511; - if ( coverage >= 256 ) - coverage = 511 - coverage; - } - else /* default non-zero winding rule */ + for ( y = ras.min_ey; y < ras.max_ey; y++ ) { - if ( coverage < 0 ) - coverage = ~coverage; /* the same as -coverage - 1 */ + PCell cell = ras.ycells[y - ras.min_ey]; + TCoord x = ras.min_ex; + TArea cover = 0; - if ( coverage >= 256 ) - coverage = 255; - } + unsigned char* line = ras.target.origin - ras.target.pitch * y; - if ( ras.num_spans >= 0 ) /* for FT_RASTER_FLAG_DIRECT only */ - { - FT_Span* span = ras.spans + ras.num_spans++; + + for ( ; cell != ras.cell_null; cell = cell->next ) + { + TArea area; - span->x = (short)x; - span->len = (unsigned short)acount; - span->coverage = (unsigned char)coverage; + if ( cover != 0 && cell->x > x ) + { + FT_FILL_RULE( coverage, cover, fill ); + FT_GRAY_SET( line + x, coverage, cell->x - x ); + } - if ( ras.num_spans == FT_MAX_GRAY_SPANS ) - { - /* flush the span buffer and reset the count */ - ras.render_span( y, ras.num_spans, ras.spans, ras.render_span_data ); - ras.num_spans = 0; - } - } - else - { - unsigned char* q = ras.target.origin - ras.target.pitch * y + x; - unsigned char c = (unsigned char)coverage; + cover += (TArea)cell->cover * ( ONE_PIXEL * 2 ); + area = cover - cell->area; + if ( area != 0 && cell->x >= ras.min_ex ) + { + FT_FILL_RULE( coverage, area, fill ); + line[cell->x] = (unsigned char)coverage; + } + + x = cell->x + 1; + } - /* For small-spans it is faster to do it by ourselves than - * calling `memset'. This is mainly due to the cost of the - * function call. - */ - switch ( acount ) + if ( cover != 0 ) /* only if cropped */ { - case 7: - *q++ = c; - /* fall through */ - case 6: - *q++ = c; - /* fall through */ - case 5: - *q++ = c; - /* fall through */ - case 4: - *q++ = c; - /* fall through */ - case 3: - *q++ = c; - /* fall through */ - case 2: - *q++ = c; - /* fall through */ - case 1: - *q = c; - /* fall through */ - case 0: - break; - default: - FT_MEM_SET( q, c, acount ); + FT_FILL_RULE( coverage, cover, fill ); + FT_GRAY_SET( line + x, coverage, ras.max_ex - x ); } } } static void - gray_sweep( RAS_ARG ) + gray_sweep_direct( RAS_ARG ) { + int fill = ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) ? 0x100 + : INT_MIN; + int coverage; int y; + FT_Span span[FT_MAX_GRAY_SPANS]; + int n = 0; + for ( y = ras.min_ey; y < ras.max_ey; y++ ) { PCell cell = ras.ycells[y - ras.min_ey]; TCoord x = ras.min_ex; TArea cover = 0; - TArea area; - for ( ; cell != NULL; cell = cell->next ) + for ( ; cell != ras.cell_null; cell = cell->next ) { + TArea area; + + if ( cover != 0 && cell->x > x ) - gray_hline( RAS_VAR_ x, y, cover, cell->x - x ); + { + FT_FILL_RULE( coverage, cover, fill ); + + span[n].coverage = (unsigned char)coverage; + span[n].x = (short)x; + span[n].len = (unsigned short)( cell->x - x ); + + if ( ++n == FT_MAX_GRAY_SPANS ) + { + /* flush the span buffer and reset the count */ + ras.render_span( y, n, span, ras.render_span_data ); + n = 0; + } + } cover += (TArea)cell->cover * ( ONE_PIXEL * 2 ); area = cover - cell->area; if ( area != 0 && cell->x >= ras.min_ex ) - gray_hline( RAS_VAR_ cell->x, y, area, 1 ); + { + FT_FILL_RULE( coverage, area, fill ); + + span[n].coverage = (unsigned char)coverage; + span[n].x = (short)cell->x; + span[n].len = 1; + + if ( ++n == FT_MAX_GRAY_SPANS ) + { + /* flush the span buffer and reset the count */ + ras.render_span( y, n, span, ras.render_span_data ); + n = 0; + } + } x = cell->x + 1; } - if ( cover != 0 ) - gray_hline( RAS_VAR_ x, y, cover, ras.max_ex - x ); + if ( cover != 0 ) /* only if cropped */ + { + FT_FILL_RULE( coverage, cover, fill ); + + span[n].coverage = (unsigned char)coverage; + span[n].x = (short)x; + span[n].len = (unsigned short)( ras.max_ex - x ); + + ++n; + } - if ( ras.num_spans > 0 ) /* for FT_RASTER_FLAG_DIRECT only */ + if ( n ) { /* flush the span buffer and reset the count */ - ras.render_span( y, ras.num_spans, ras.spans, ras.render_span_data ); - ras.num_spans = 0; + ras.render_span( y, n, span, ras.render_span_data ); + n = 0; } } } @@ -1604,7 +1880,7 @@ typedef ptrdiff_t FT_PtrDist; } FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); - return 0; + return Smooth_Err_Ok; Exit: FT_TRACE5(( "FT_Outline_Decompose: Error 0x%x\n", error )); @@ -1645,18 +1921,15 @@ typedef ptrdiff_t FT_PtrDist; if ( continued ) FT_Trace_Enable(); - if ( !ras.invalid ) - gray_record_cell( RAS_VAR ); - - FT_TRACE7(( "band [%d..%d]: %ld cell%s\n", + FT_TRACE7(( "band [%d..%d]: %ld cell%s remaining/\n", ras.min_ey, ras.max_ey, - ras.num_cells, - ras.num_cells == 1 ? "" : "s" )); + ras.cell_null - ras.cell_free, + ras.cell_null - ras.cell_free == 1 ? "" : "s" )); } else { - error = FT_THROW( Memory_Overflow ); + error = FT_THROW( Raster_Overflow ); FT_TRACE7(( "band [%d..%d]: to be bisected\n", ras.min_ey, ras.max_ey )); @@ -1682,7 +1955,16 @@ typedef ptrdiff_t FT_PtrDist; int continued = 0; + /* Initialize the null cell at the end of the poll. */ + ras.cell_null = buffer + FT_MAX_GRAY_POOL - 1; + ras.cell_null->x = CELL_MAX_X_VALUE; + ras.cell_null->area = 0; + ras.cell_null->cover = 0; + ras.cell_null->next = NULL; + /* set up vertical bands */ + ras.ycells = (PCell*)buffer; + if ( height > n ) { /* two divisions rounded up */ @@ -1690,13 +1972,6 @@ typedef ptrdiff_t FT_PtrDist; height = ( height + n - 1 ) / n; } - /* memory management */ - n = ( height * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) / sizeof ( TCell ); - - ras.cells = buffer + n; - ras.max_cells = (FT_PtrDist)( FT_MAX_GRAY_POOL - n ); - ras.ycells = (PCell*)buffer; - for ( y = yMin; y < yMax; ) { ras.min_ey = y; @@ -1710,27 +1985,37 @@ typedef ptrdiff_t FT_PtrDist; do { TCoord width = band[0] - band[1]; + TCoord w; int error; - FT_MEM_ZERO( ras.ycells, height * sizeof ( PCell ) ); + for ( w = 0; w < width; ++w ) + ras.ycells[w] = ras.cell_null; - ras.num_cells = 0; - ras.invalid = 1; + /* memory management: skip ycells */ + n = ( (size_t)width * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) / + sizeof ( TCell ); + + ras.cell_free = buffer + n; + ras.cell = ras.cell_null; ras.min_ey = band[1]; ras.max_ey = band[0]; + ras.count_ey = width; error = gray_convert_glyph_inner( RAS_VAR, continued ); continued = 1; if ( !error ) { - gray_sweep( RAS_VAR ); + if ( ras.render_span ) /* for FT_RASTER_FLAG_DIRECT only */ + gray_sweep_direct( RAS_VAR ); + else + gray_sweep( RAS_VAR ); band--; continue; } - else if ( error != ErrRaster_Memory_Overflow ) - return 1; + else if ( error != Smooth_Err_Raster_Overflow ) + return error; /* render pool overflow; we will reduce the render band by half */ width >>= 1; @@ -1739,7 +2024,7 @@ typedef ptrdiff_t FT_PtrDist; if ( width == 0 ) { FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" )); - return 1; + return FT_THROW( Raster_Overflow ); } band++; @@ -1748,7 +2033,7 @@ typedef ptrdiff_t FT_PtrDist; } while ( band >= bands ); } - return 0; + return Smooth_Err_Ok; } @@ -1769,14 +2054,14 @@ typedef ptrdiff_t FT_PtrDist; /* this version does not support monochrome rendering */ if ( !( params->flags & FT_RASTER_FLAG_AA ) ) - return FT_THROW( Invalid_Mode ); + return FT_THROW( Cannot_Render_Glyph ); if ( !outline ) return FT_THROW( Invalid_Outline ); /* return immediately if the outline is empty */ if ( outline->n_points == 0 || outline->n_contours <= 0 ) - return 0; + return Smooth_Err_Ok; if ( !outline->contours || !outline->points ) return FT_THROW( Invalid_Outline ); @@ -1790,11 +2075,10 @@ typedef ptrdiff_t FT_PtrDist; if ( params->flags & FT_RASTER_FLAG_DIRECT ) { if ( !params->gray_spans ) - return 0; + return Smooth_Err_Ok; ras.render_span = (FT_Raster_Span_Func)params->gray_spans; ras.render_span_data = params->user; - ras.num_spans = 0; ras.min_ex = params->clip_box.xMin; ras.min_ey = params->clip_box.yMin; @@ -1809,7 +2093,7 @@ typedef ptrdiff_t FT_PtrDist; /* nothing to do */ if ( !target_map->width || !target_map->rows ) - return 0; + return Smooth_Err_Ok; if ( !target_map->buffer ) return FT_THROW( Invalid_Argument ); @@ -1824,7 +2108,6 @@ typedef ptrdiff_t FT_PtrDist; ras.render_span = (FT_Raster_Span_Func)NULL; ras.render_span_data = NULL; - ras.num_spans = -1; /* invalid */ ras.min_ex = 0; ras.min_ey = 0; @@ -1834,7 +2117,7 @@ typedef ptrdiff_t FT_PtrDist; /* exit if nothing to do */ if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey ) - return 0; + return Smooth_Err_Ok; return gray_convert_glyph( RAS_VAR ); } @@ -1871,19 +2154,17 @@ typedef ptrdiff_t FT_PtrDist; #else /* !STANDALONE_ */ static int - gray_raster_new( FT_Memory memory, - FT_Raster* araster ) + gray_raster_new( FT_Memory memory, + gray_PRaster* araster ) { FT_Error error; gray_PRaster raster = NULL; - *araster = 0; - if ( !FT_ALLOC( raster, sizeof ( gray_TRaster ) ) ) - { + if ( !FT_NEW( raster ) ) raster->memory = memory; - *araster = (FT_Raster)raster; - } + + *araster = raster; return error; } diff --git a/thirdparty/freetype/src/smooth/ftgrays.h b/thirdparty/freetype/src/smooth/ftgrays.h index caba632833..3dad0498dc 100644 --- a/thirdparty/freetype/src/smooth/ftgrays.h +++ b/thirdparty/freetype/src/smooth/ftgrays.h @@ -4,7 +4,7 @@ * * FreeType smooth renderer declaration * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/smooth/ftsmerrs.h b/thirdparty/freetype/src/smooth/ftsmerrs.h index e93f3df9b3..dc2c40cc9f 100644 --- a/thirdparty/freetype/src/smooth/ftsmerrs.h +++ b/thirdparty/freetype/src/smooth/ftsmerrs.h @@ -4,7 +4,7 @@ * * smooth renderer error codes (specification only). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/smooth/ftsmooth.c b/thirdparty/freetype/src/smooth/ftsmooth.c index 5d66bd6fc4..bea3b4a800 100644 --- a/thirdparty/freetype/src/smooth/ftsmooth.c +++ b/thirdparty/freetype/src/smooth/ftsmooth.c @@ -4,7 +4,7 @@ * * Anti-aliasing renderer interface (body). * - * Copyright (C) 2000-2020 by + * Copyright (C) 2000-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/smooth/ftsmooth.h b/thirdparty/freetype/src/smooth/ftsmooth.h index 22a88d54ec..2dd81e84b8 100644 --- a/thirdparty/freetype/src/smooth/ftsmooth.h +++ b/thirdparty/freetype/src/smooth/ftsmooth.h @@ -4,7 +4,7 @@ * * Anti-aliasing renderer interface (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/smooth/module.mk b/thirdparty/freetype/src/smooth/module.mk deleted file mode 100644 index 9b1507f1e0..0000000000 --- a/thirdparty/freetype/src/smooth/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 smooth renderer module definition -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += SMOOTH_RENDERER - -define SMOOTH_RENDERER -$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_renderer_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/smooth/rules.mk b/thirdparty/freetype/src/smooth/rules.mk deleted file mode 100644 index b08056fac5..0000000000 --- a/thirdparty/freetype/src/smooth/rules.mk +++ /dev/null @@ -1,73 +0,0 @@ -# -# FreeType 2 smooth renderer module build rules -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# smooth driver directory -# -SMOOTH_DIR := $(SRC_DIR)/smooth - - -# compilation flags for the driver -# -SMOOTH_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(SMOOTH_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# smooth driver sources (i.e., C files) -# -SMOOTH_DRV_SRC := $(SMOOTH_DIR)/ftgrays.c \ - $(SMOOTH_DIR)/ftsmooth.c - - -# smooth driver headers -# -SMOOTH_DRV_H := $(SMOOTH_DRV_SRC:%c=%h) \ - $(SMOOTH_DIR)/ftsmerrs.h - - -# smooth driver object(s) -# -# SMOOTH_DRV_OBJ_M is used during `multi' builds. -# SMOOTH_DRV_OBJ_S is used during `single' builds. -# -SMOOTH_DRV_OBJ_M := $(SMOOTH_DRV_SRC:$(SMOOTH_DIR)/%.c=$(OBJ_DIR)/%.$O) -SMOOTH_DRV_OBJ_S := $(OBJ_DIR)/smooth.$O - -# smooth driver source file for single build -# -SMOOTH_DRV_SRC_S := $(SMOOTH_DIR)/smooth.c - - -# smooth driver - single object -# -$(SMOOTH_DRV_OBJ_S): $(SMOOTH_DRV_SRC_S) $(SMOOTH_DRV_SRC) \ - $(FREETYPE_H) $(SMOOTH_DRV_H) - $(SMOOTH_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(SMOOTH_DRV_SRC_S)) - - -# smooth driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(SMOOTH_DIR)/%.c $(FREETYPE_H) $(SMOOTH_DRV_H) - $(SMOOTH_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(SMOOTH_DRV_OBJ_S) -DRV_OBJS_M += $(SMOOTH_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/smooth/smooth.c b/thirdparty/freetype/src/smooth/smooth.c index 04b531c087..9e25440635 100644 --- a/thirdparty/freetype/src/smooth/smooth.c +++ b/thirdparty/freetype/src/smooth/smooth.c @@ -4,7 +4,7 @@ * * FreeType anti-aliasing rasterer module component (body only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/truetype/module.mk b/thirdparty/freetype/src/truetype/module.mk deleted file mode 100644 index 2d8d39d1f7..0000000000 --- a/thirdparty/freetype/src/truetype/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 TrueType module definition -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += TRUETYPE_DRIVER - -define TRUETYPE_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, tt_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)truetype $(ECHO_DRIVER_DESC)Windows/Mac font files with extension *.ttf or *.ttc$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/truetype/rules.mk b/thirdparty/freetype/src/truetype/rules.mk deleted file mode 100644 index 2f6fecfc44..0000000000 --- a/thirdparty/freetype/src/truetype/rules.mk +++ /dev/null @@ -1,76 +0,0 @@ -# -# FreeType 2 TrueType driver configuration rules -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# TrueType driver directory -# -TT_DIR := $(SRC_DIR)/truetype - - -# compilation flags for the driver -# -TT_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(TT_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# TrueType driver sources (i.e., C files) -# -TT_DRV_SRC := $(TT_DIR)/ttdriver.c \ - $(TT_DIR)/ttgload.c \ - $(TT_DIR)/ttgxvar.c \ - $(TT_DIR)/ttinterp.c \ - $(TT_DIR)/ttobjs.c \ - $(TT_DIR)/ttpload.c \ - $(TT_DIR)/ttsubpix.c - -# TrueType driver headers -# -TT_DRV_H := $(TT_DRV_SRC:%.c=%.h) \ - $(TT_DIR)/tterrors.h - - -# TrueType driver object(s) -# -# TT_DRV_OBJ_M is used during `multi' builds -# TT_DRV_OBJ_S is used during `single' builds -# -TT_DRV_OBJ_M := $(TT_DRV_SRC:$(TT_DIR)/%.c=$(OBJ_DIR)/%.$O) -TT_DRV_OBJ_S := $(OBJ_DIR)/truetype.$O - -# TrueType driver source file for single build -# -TT_DRV_SRC_S := $(TT_DIR)/truetype.c - - -# TrueType driver - single object -# -$(TT_DRV_OBJ_S): $(TT_DRV_SRC_S) $(TT_DRV_SRC) $(FREETYPE_H) $(TT_DRV_H) - $(TT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(TT_DRV_SRC_S)) - - -# driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(TT_DIR)/%.c $(FREETYPE_H) $(TT_DRV_H) - $(TT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(TT_DRV_OBJ_S) -DRV_OBJS_M += $(TT_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/truetype/truetype.c b/thirdparty/freetype/src/truetype/truetype.c index 41b6808a84..4232aca6ec 100644 --- a/thirdparty/freetype/src/truetype/truetype.c +++ b/thirdparty/freetype/src/truetype/truetype.c @@ -4,7 +4,7 @@ * * FreeType TrueType driver component (body only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/truetype/ttdriver.c b/thirdparty/freetype/src/truetype/ttdriver.c index bf830b1418..6fcfdb23e4 100644 --- a/thirdparty/freetype/src/truetype/ttdriver.c +++ b/thirdparty/freetype/src/truetype/ttdriver.c @@ -4,7 +4,7 @@ * * TrueType font driver implementation (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -108,7 +108,7 @@ return error; } - FT_TRACE0(( "tt_property_set: missing property `%s'\n", + FT_TRACE2(( "tt_property_set: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); } @@ -135,7 +135,7 @@ return error; } - FT_TRACE0(( "tt_property_get: missing property `%s'\n", + FT_TRACE2(( "tt_property_get: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); } @@ -354,7 +354,16 @@ #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - FT_Request_Metrics( size->face, req ); + { + FT_Error err = FT_Request_Metrics( size->face, req ); + + + if ( err ) + { + error = err; + goto Exit; + } + } if ( FT_IS_SCALABLE( size->face ) ) { @@ -382,6 +391,7 @@ #endif } + Exit: return error; } diff --git a/thirdparty/freetype/src/truetype/ttdriver.h b/thirdparty/freetype/src/truetype/ttdriver.h index ee1438eb6e..4e6d52d22c 100644 --- a/thirdparty/freetype/src/truetype/ttdriver.h +++ b/thirdparty/freetype/src/truetype/ttdriver.h @@ -4,7 +4,7 @@ * * High-level TrueType driver interface (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/truetype/tterrors.h b/thirdparty/freetype/src/truetype/tterrors.h index efeafd3a1b..0ce247e376 100644 --- a/thirdparty/freetype/src/truetype/tterrors.h +++ b/thirdparty/freetype/src/truetype/tterrors.h @@ -4,7 +4,7 @@ * * TrueType error codes (specification only). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/truetype/ttgload.c b/thirdparty/freetype/src/truetype/ttgload.c index 1dd319dcbf..11968f6fdc 100644 --- a/thirdparty/freetype/src/truetype/ttgload.c +++ b/thirdparty/freetype/src/truetype/ttgload.c @@ -4,7 +4,7 @@ * * TrueType Glyph Loader (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -197,10 +197,17 @@ } #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - if ( !loader->linear_def ) +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* With the incremental interface, these values are set by */ + /* a call to `tt_get_metrics_incremental'. */ + if ( face->root.internal->incremental_interface == NULL ) +#endif { - loader->linear_def = 1; - loader->linear = advance_width; + if ( !loader->linear_def ) + { + loader->linear_def = 1; + loader->linear = advance_width; + } } return FT_Err_Ok; @@ -210,8 +217,8 @@ #ifdef FT_CONFIG_OPTION_INCREMENTAL static void - tt_get_metrics_incr_overrides( TT_Loader loader, - FT_UInt glyph_index ) + tt_get_metrics_incremental( TT_Loader loader, + FT_UInt glyph_index ) { TT_Face face = loader->face; @@ -451,7 +458,7 @@ (void*)&load->exec->glyphIns, n_ins ); - load->exec->glyphSize = (FT_UShort)tmp; + load->exec->glyphSize = (FT_UInt)tmp; if ( error ) return error; @@ -736,12 +743,14 @@ subglyph->transform.xx / 65536.0, subglyph->transform.yy / 65536.0 )); else if ( subglyph->flags & WE_HAVE_A_2X2 ) - FT_TRACE7(( " scaling: xx=%f, yx=%f\n" - " xy=%f, yy=%f\n", + { + FT_TRACE7(( " scaling: xx=%f, yx=%f\n", subglyph->transform.xx / 65536.0, - subglyph->transform.yx / 65536.0, + subglyph->transform.yx / 65536.0 )); + FT_TRACE7(( " xy=%f, yy=%f\n", subglyph->transform.xy / 65536.0, subglyph->transform.yy / 65536.0 )); + } subglyph++; } @@ -1383,7 +1392,7 @@ FT_READ_USHORT( n_ins ) ) return error; - FT_TRACE5(( " Instructions size = %d\n", n_ins )); + FT_TRACE5(( " Instructions size = %hu\n", n_ins )); /* check it */ max_ins = loader->face->max_profile.maxSizeOfInstructions; @@ -1391,10 +1400,10 @@ { /* don't trust `maxSizeOfInstructions'; */ /* only do a rough safety check */ - if ( (FT_Int)n_ins > loader->byte_len ) + if ( n_ins > loader->byte_len ) { FT_TRACE1(( "TT_Process_Composite_Glyph:" - " too many instructions (%d) for glyph with length %d\n", + " too many instructions (%hu) for glyph with length %u\n", n_ins, loader->byte_len )); return FT_THROW( Too_Many_Hints ); } @@ -1677,7 +1686,7 @@ FT_ZERO( &inc_stream ); FT_Stream_OpenMemory( &inc_stream, glyph_data.pointer, - (FT_ULong)glyph_data.length ); + glyph_data.length ); loader->stream = &inc_stream; } @@ -1685,8 +1694,7 @@ #endif /* FT_CONFIG_OPTION_INCREMENTAL */ - offset = tt_face_get_location( face, glyph_index, - (FT_UInt*)&loader->byte_len ); + offset = tt_face_get_location( face, glyph_index, &loader->byte_len ); if ( loader->byte_len > 0 ) { @@ -1705,7 +1713,7 @@ error = face->access_glyph_frame( loader, glyph_index, face->glyf_offset + offset, - (FT_UInt)loader->byte_len ); + loader->byte_len ); if ( error ) goto Exit; @@ -1739,13 +1747,11 @@ if ( loader->byte_len == 0 || loader->n_contours == 0 ) { - /* must initialize points before (possibly) overriding */ - /* glyph metrics from the incremental interface */ - tt_loader_set_pp( loader ); - #ifdef FT_CONFIG_OPTION_INCREMENTAL - tt_get_metrics_incr_overrides( loader, glyph_index ); + tt_get_metrics_incremental( loader, glyph_index ); #endif + tt_loader_set_pp( loader ); + #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT @@ -1828,13 +1834,11 @@ goto Exit; } - /* must initialize phantom points before (possibly) overriding */ - /* glyph metrics from the incremental interface */ - tt_loader_set_pp( loader ); - #ifdef FT_CONFIG_OPTION_INCREMENTAL - tt_get_metrics_incr_overrides( loader, glyph_index ); + tt_get_metrics_incremental( loader, glyph_index ); #endif + tt_loader_set_pp( loader ); + /***********************************************************************/ /***********************************************************************/ @@ -1844,7 +1848,7 @@ /* (which consists of 10 bytes) */ error = face->access_glyph_frame( loader, glyph_index, face->glyf_offset + offset + 10, - (FT_UInt)loader->byte_len - 10 ); + loader->byte_len - 10 ); if ( error ) goto Exit; @@ -1898,7 +1902,7 @@ /* clear the nodes filled by sibling chains */ node = ft_list_get_node_at( &loader->composites, recurse_count ); for ( node2 = node; node2; node2 = node2->next ) - node2->data = (void*)FT_ULONG_MAX; + node2->data = (void*)-1; /* check whether we already have a composite glyph with this index */ if ( FT_List_Find( &loader->composites, @@ -1915,7 +1919,7 @@ else { - if ( FT_NEW( node ) ) + if ( FT_QNEW( node ) ) goto Exit; node->data = FT_UINT_TO_POINTER( glyph_index ); FT_List_Add( &loader->composites, node ); @@ -2100,7 +2104,7 @@ FT_UInt num_base_subgs = gloader->base.num_subglyphs; FT_Stream old_stream = loader->stream; - FT_Int old_byte_len = loader->byte_len; + FT_UInt old_byte_len = loader->byte_len; FT_GlyphLoader_Add( gloader ); @@ -2713,6 +2717,9 @@ error = tt_size_run_prep( size, pedantic ); if ( error ) return error; + error = TT_Load_Context( exec, face, size ); + if ( error ) + return error; } /* check whether the cvt program has disabled hinting */ diff --git a/thirdparty/freetype/src/truetype/ttgload.h b/thirdparty/freetype/src/truetype/ttgload.h index 8f72cd558c..78fdeaa73d 100644 --- a/thirdparty/freetype/src/truetype/ttgload.h +++ b/thirdparty/freetype/src/truetype/ttgload.h @@ -4,7 +4,7 @@ * * TrueType Glyph Loader (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/truetype/ttgxvar.c b/thirdparty/freetype/src/truetype/ttgxvar.c index b462263de1..7f2db0cbdc 100644 --- a/thirdparty/freetype/src/truetype/ttgxvar.c +++ b/thirdparty/freetype/src/truetype/ttgxvar.c @@ -4,7 +4,7 @@ * * TrueType GX Font Variation loader * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. * * This file is part of the FreeType project, and may only be used, @@ -178,7 +178,7 @@ /* in the nested loops below we increase `i' twice; */ /* it is faster to simply allocate one more slot */ /* than to add another test within the loop */ - if ( FT_NEW_ARRAY( points, n + 1 ) ) + if ( FT_QNEW_ARRAY( points, n + 1 ) ) return NULL; *point_cnt = n; @@ -264,55 +264,80 @@ FT_Fixed *deltas = NULL; FT_UInt runcnt, cnt; FT_UInt i, j; + FT_UInt bytes_used; FT_Memory memory = stream->memory; FT_Error error = FT_Err_Ok; FT_UNUSED( error ); - if ( delta_cnt > size ) - { - FT_TRACE1(( "ft_var_readpackeddeltas: number of points too large\n" )); + if ( FT_QNEW_ARRAY( deltas, delta_cnt ) ) return NULL; - } - if ( FT_NEW_ARRAY( deltas, delta_cnt ) ) - return NULL; + i = 0; + bytes_used = 0; - i = 0; - while ( i < delta_cnt ) + while ( i < delta_cnt && bytes_used < size ) { runcnt = FT_GET_BYTE(); cnt = runcnt & GX_DT_DELTA_RUN_COUNT_MASK; + bytes_used++; + if ( runcnt & GX_DT_DELTAS_ARE_ZERO ) { - /* `runcnt' zeroes get added */ + /* `cnt` + 1 zeroes get added */ for ( j = 0; j <= cnt && i < delta_cnt; j++ ) deltas[i++] = 0; } else if ( runcnt & GX_DT_DELTAS_ARE_WORDS ) { - /* `runcnt' shorts from the stack */ + /* `cnt` + 1 shorts from the stack */ + bytes_used += 2 * ( cnt + 1 ); + if ( bytes_used > size ) + { + FT_TRACE1(( "ft_var_readpackeddeltas:" + " number of short deltas too large\n" )); + goto Fail; + } + for ( j = 0; j <= cnt && i < delta_cnt; j++ ) deltas[i++] = FT_intToFixed( FT_GET_SHORT() ); } else { - /* `runcnt' signed bytes from the stack */ + /* `cnt` + 1 signed bytes from the stack */ + bytes_used += cnt + 1; + if ( bytes_used > size ) + { + FT_TRACE1(( "ft_var_readpackeddeltas:" + " number of byte deltas too large\n" )); + goto Fail; + } + for ( j = 0; j <= cnt && i < delta_cnt; j++ ) deltas[i++] = FT_intToFixed( FT_GET_CHAR() ); } if ( j <= cnt ) { - /* bad format */ - FT_FREE( deltas ); - return NULL; + FT_TRACE1(( "ft_var_readpackeddeltas:" + " number of deltas too large\n" )); + goto Fail; } } + if ( i < delta_cnt ) + { + FT_TRACE1(( "ft_var_readpackeddeltas: not enough deltas\n" )); + goto Fail; + } + return deltas; + + Fail: + FT_FREE( deltas ); + return NULL; } @@ -371,12 +396,13 @@ if ( axisCount != (FT_Long)blend->mmvar->num_axis ) { - FT_TRACE2(( "ft_var_load_avar: number of axes in `avar' and `fvar'\n" - " table are different\n" )); + FT_TRACE2(( "ft_var_load_avar:" + " number of axes in `avar' and `fvar'\n" )); + FT_TRACE2(( " table are different\n" )); goto Exit; } - if ( FT_NEW_ARRAY( blend->avar_segment, axisCount ) ) + if ( FT_QNEW_ARRAY( blend->avar_segment, axisCount ) ) goto Exit; segment = &blend->avar_segment[0]; @@ -385,8 +411,8 @@ FT_TRACE5(( " axis %d:\n", i )); segment->pairCount = FT_GET_USHORT(); - if ( (FT_ULong)segment->pairCount * 4 > table_len || - FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) ) + if ( (FT_ULong)segment->pairCount * 4 > table_len || + FT_QNEW_ARRAY( segment->correspondence, segment->pairCount ) ) { /* Failure. Free everything we have done so far. We must do */ /* it right now since loading the `avar' table is optional. */ @@ -431,7 +457,8 @@ FT_UShort format; FT_ULong region_offset; FT_UInt i, j, k; - FT_UInt shortDeltaCount; + FT_UInt wordDeltaCount; + FT_Bool long_words; GX_Blend blend = face->blend; GX_ItemVarData varData; @@ -466,7 +493,7 @@ /* make temporary copy of item variation data offsets; */ /* we will parse region list first, then come back */ - if ( FT_NEW_ARRAY( dataOffsetArray, itemStore->dataCount ) ) + if ( FT_QNEW_ARRAY( dataOffsetArray, itemStore->dataCount ) ) goto Exit; for ( i = 0; i < itemStore->dataCount; i++ ) @@ -486,13 +513,22 @@ if ( itemStore->axisCount != (FT_Long)blend->mmvar->num_axis ) { FT_TRACE2(( "ft_var_load_item_variation_store:" - " number of axes in item variation store\n" - " " + " number of axes in item variation store\n" )); + FT_TRACE2(( " " " and `fvar' table are different\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } + /* new constraint in OpenType 1.8.4 */ + if ( itemStore->regionCount >= 32768U ) + { + FT_TRACE2(( "ft_var_load_item_variation_store:" + " too many variation region tables\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + if ( FT_NEW_ARRAY( itemStore->varRegionList, itemStore->regionCount ) ) goto Exit; @@ -537,15 +573,18 @@ goto Exit; if ( FT_READ_USHORT( varData->itemCount ) || - FT_READ_USHORT( shortDeltaCount ) || + FT_READ_USHORT( wordDeltaCount ) || FT_READ_USHORT( varData->regionIdxCount ) ) goto Exit; + long_words = !!( wordDeltaCount & 0x8000 ); + wordDeltaCount &= 0x7FFF; + /* check some data consistency */ - if ( shortDeltaCount > varData->regionIdxCount ) + if ( wordDeltaCount > varData->regionIdxCount ) { FT_TRACE2(( "bad short count %d or region count %d\n", - shortDeltaCount, + wordDeltaCount, varData->regionIdxCount )); error = FT_THROW( Invalid_Table ); goto Exit; @@ -581,39 +620,52 @@ /* Parse delta set. */ /* */ - /* On input, deltas are (shortDeltaCount + regionIdxCount) bytes */ - /* each; on output, deltas are expanded to `regionIdxCount' shorts */ - /* each. */ + /* On input, deltas are (wordDeltaCount + regionIdxCount) bytes */ + /* each if `long_words` isn't set, and twice as much otherwise. */ + /* */ + /* On output, deltas are expanded to `regionIdxCount` shorts each. */ if ( FT_NEW_ARRAY( varData->deltaSet, varData->regionIdxCount * varData->itemCount ) ) goto Exit; - /* the delta set is stored as a 2-dimensional array of shorts; */ - /* sign-extend signed bytes to signed shorts */ - for ( j = 0; j < varData->itemCount * varData->regionIdxCount; ) + /* the delta set is stored as a 2-dimensional array of shorts */ + if ( long_words ) + { + /* new in OpenType 1.9, currently for 'COLR' table only; */ + /* the deltas are interpreted as 16.16 fixed-point scaling values */ + + /* not supported yet */ + + error = FT_THROW( Invalid_Table ); + goto Exit; + } + else { - for ( k = 0; k < shortDeltaCount; k++, j++ ) + for ( j = 0; j < varData->itemCount * varData->regionIdxCount; ) { - /* read the short deltas */ - FT_Short delta; + for ( k = 0; k < wordDeltaCount; k++, j++ ) + { + /* read the short deltas */ + FT_Short delta; - if ( FT_READ_SHORT( delta ) ) - goto Exit; + if ( FT_READ_SHORT( delta ) ) + goto Exit; - varData->deltaSet[j] = delta; - } + varData->deltaSet[j] = delta; + } - for ( ; k < varData->regionIdxCount; k++, j++ ) - { - /* read the (signed) byte deltas */ - FT_Char delta; + for ( ; k < varData->regionIdxCount; k++, j++ ) + { + /* read the (signed) byte deltas */ + FT_Char delta; - if ( FT_READ_CHAR( delta ) ) - goto Exit; + if ( FT_READ_CHAR( delta ) ) + goto Exit; - varData->deltaSet[j] = delta; + varData->deltaSet[j] = delta; + } } } } @@ -629,37 +681,66 @@ ft_var_load_delta_set_index_mapping( TT_Face face, FT_ULong offset, GX_DeltaSetIdxMap map, - GX_ItemVarStore itemStore ) + GX_ItemVarStore itemStore, + FT_ULong table_len ) { FT_Stream stream = FT_FACE_STREAM( face ); FT_Memory memory = stream->memory; - FT_Error error; + FT_Error error; - FT_UShort format; - FT_UInt entrySize; - FT_UInt innerBitCount; - FT_UInt innerIndexMask; - FT_UInt i, j; + FT_Byte format; + FT_Byte entryFormat; + FT_UInt entrySize; + FT_UInt innerBitCount; + FT_UInt innerIndexMask; + FT_ULong i; + FT_UInt j; - if ( FT_STREAM_SEEK( offset ) || - FT_READ_USHORT( format ) || - FT_READ_USHORT( map->mapCount ) ) + if ( FT_STREAM_SEEK( offset ) || + FT_READ_BYTE( format ) || + FT_READ_BYTE( entryFormat ) ) goto Exit; - if ( format & 0xFFC0 ) + if ( format == 0 ) + { + if ( FT_READ_USHORT( map->mapCount ) ) + goto Exit; + } + else if ( format == 1 ) /* new in OpenType 1.9 */ + { + if ( FT_READ_ULONG( map->mapCount ) ) + goto Exit; + } + else { FT_TRACE2(( "bad map format %d\n", format )); error = FT_THROW( Invalid_Table ); goto Exit; } + if ( entryFormat & 0xC0 ) + { + FT_TRACE2(( "bad entry format %d\n", format )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + /* bytes per entry: 1, 2, 3, or 4 */ - entrySize = ( ( format & 0x0030 ) >> 4 ) + 1; - innerBitCount = ( format & 0x000F ) + 1; + entrySize = ( ( entryFormat & 0x30 ) >> 4 ) + 1; + innerBitCount = ( entryFormat & 0x0F ) + 1; innerIndexMask = ( 1 << innerBitCount ) - 1; + /* rough sanity check */ + if ( map->mapCount * entrySize > table_len ) + { + FT_TRACE1(( "ft_var_load_delta_set_index_mapping:" + " invalid number of delta-set index mappings\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + if ( FT_NEW_ARRAY( map->innerIndex, map->mapCount ) ) goto Exit; @@ -688,7 +769,7 @@ if ( outerIndex >= itemStore->dataCount ) { - FT_TRACE2(( "outerIndex[%d] == %d out of range\n", + FT_TRACE2(( "outerIndex[%ld] == %d out of range\n", i, outerIndex )); error = FT_THROW( Invalid_Table ); @@ -701,7 +782,7 @@ if ( innerIndex >= itemStore->varData[outerIndex].itemCount ) { - FT_TRACE2(( "innerIndex[%d] == %d out of range\n", + FT_TRACE2(( "innerIndex[%ld] == %d out of range\n", i, innerIndex )); error = FT_THROW( Invalid_Table ); @@ -826,7 +907,8 @@ face, table_offset + widthMap_offset, &table->widthMap, - &table->itemStore ); + &table->itemStore, + table_len ); if ( error ) goto Exit; } @@ -1515,8 +1597,9 @@ if ( gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis ) { - FT_TRACE1(( "ft_var_load_gvar: number of axes in `gvar' and `cvar'\n" - " table are different\n" )); + FT_TRACE1(( "ft_var_load_gvar:" + " number of axes in `gvar' and `cvar'\n" )); + FT_TRACE1(( " table are different\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } @@ -1558,7 +1641,7 @@ goto Exit; /* offsets (one more offset than glyphs, to mark size of last) */ - if ( FT_NEW_ARRAY( blend->glyphoffsets, gvar_head.glyphCount + 1 ) ) + if ( FT_QNEW_ARRAY( blend->glyphoffsets, gvar_head.glyphCount + 1 ) ) goto Fail2; if ( gvar_head.flags & 1 ) @@ -1637,8 +1720,8 @@ goto Fail; } - if ( FT_NEW_ARRAY( blend->tuplecoords, - gvar_head.axisCount * gvar_head.globalCoordCount ) ) + if ( FT_QNEW_ARRAY( blend->tuplecoords, + gvar_head.axisCount * gvar_head.globalCoordCount ) ) goto Fail2; for ( i = 0; i < gvar_head.globalCoordCount; i++ ) @@ -1841,25 +1924,22 @@ FT_TRACE5(( " %d: %.5f\n", i, coord / 65536.0 )); if ( coord > a->maximum || coord < a->minimum ) { - FT_TRACE1(( - "ft_var_to_normalized: design coordinate %.5f\n" - " is out of range [%.5f;%.5f]; clamping\n", - coord / 65536.0, - a->minimum / 65536.0, - a->maximum / 65536.0 )); - - if ( coord > a->maximum ) - coord = a->maximum; - else - coord = a->minimum; + FT_TRACE1(( "ft_var_to_normalized: design coordinate %.5f\n", + coord / 65536.0 )); + FT_TRACE1(( " is out of range [%.5f;%.5f];" + " clamping\n", + a->minimum / 65536.0, + a->maximum / 65536.0 )); } - if ( coord < a->def ) - normalized[i] = -FT_DivFix( SUB_LONG( coord, a->def ), - SUB_LONG( a->minimum, a->def ) ); - else if ( coord > a->def ) - normalized[i] = FT_DivFix( SUB_LONG( coord, a->def ), + if ( coord > a->def ) + normalized[i] = coord >= a->maximum ? 0x10000L : + FT_DivFix( SUB_LONG( coord, a->def ), SUB_LONG( a->maximum, a->def ) ); + else if ( coord < a->def ) + normalized[i] = coord <= a->minimum ? -0x10000L : + FT_DivFix( SUB_LONG( coord, a->def ), + SUB_LONG( a->def, a->minimum ) ); else normalized[i] = 0; } @@ -2049,7 +2129,7 @@ FT_Var_Axis* a; FT_Fixed* c; FT_Var_Named_Style* ns; - GX_FVar_Head fvar_head; + GX_FVar_Head fvar_head = { 0, 0, 0, 0, 0, 0 }; FT_Bool usePsName = 0; FT_UInt num_instances; FT_UInt num_axes; @@ -2115,8 +2195,8 @@ if ( FT_SET_ERROR( face->goto_table( face, TTAG_CFF2, stream, &table_len ) ) ) { - FT_TRACE1(( "\n" - "TT_Get_MM_Var: `gvar' or `CFF2' table is missing\n" )); + FT_TRACE1(( "\n" )); + FT_TRACE1(( "TT_Get_MM_Var: `gvar' or `CFF2' table is missing\n" )); goto Exit; } } @@ -2544,17 +2624,17 @@ num_coords = mmvar->num_axis; } - FT_TRACE5(( "TT_Set_MM_Blend:\n" - " normalized design coordinates:\n" )); + FT_TRACE5(( "TT_Set_MM_Blend:\n" )); + FT_TRACE5(( " normalized design coordinates:\n" )); for ( i = 0; i < num_coords; i++ ) { FT_TRACE5(( " %.5f\n", coords[i] / 65536.0 )); if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) { - FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.5f\n" - " is out of range [-1;1]\n", + FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.5f\n", coords[i] / 65536.0 )); + FT_TRACE1(( " is out of range [-1;1]\n" )); error = FT_THROW( Invalid_Argument ); goto Exit; } @@ -2652,9 +2732,10 @@ } blend->num_axis = mmvar->num_axis; - FT_MEM_COPY( blend->normalizedcoords, - coords, - num_coords * sizeof ( FT_Fixed ) ); + if ( coords ) + FT_MEM_COPY( blend->normalizedcoords, + coords, + num_coords * sizeof ( FT_Fixed ) ); if ( set_design_coords ) ft_var_to_design( face, @@ -2952,8 +3033,8 @@ if ( !face->blend->avar_loaded ) ft_var_load_avar( face ); - FT_TRACE5(( "TT_Set_Var_Design:\n" - " normalized design coordinates:\n" )); + FT_TRACE5(( "TT_Set_Var_Design:\n" )); + FT_TRACE5(( " normalized design coordinates:\n" )); ft_var_to_normalized( face, num_coords, blend->coords, normalized ); error = tt_set_mm_blend( face, mmvar->num_axis, normalized, 0 ); @@ -3152,6 +3233,8 @@ /*************************************************************************/ +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + static FT_Error tt_cvt_ready_iterator( FT_ListNode node, void* user ) @@ -3166,6 +3249,9 @@ return FT_Err_Ok; } +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + /************************************************************************** * @@ -3194,6 +3280,8 @@ tt_face_vary_cvt( TT_Face face, FT_Stream stream ) { +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + FT_Error error; FT_Memory memory = stream->memory; @@ -3229,16 +3317,16 @@ if ( !blend ) { - FT_TRACE2(( "\n" - "tt_face_vary_cvt: no blend specified\n" )); + FT_TRACE2(( "\n" )); + FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" )); error = FT_Err_Ok; goto Exit; } if ( !face->cvt ) { - FT_TRACE2(( "\n" - "tt_face_vary_cvt: no `cvt ' table\n" )); + FT_TRACE2(( "\n" )); + FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" )); error = FT_Err_Ok; goto Exit; } @@ -3397,9 +3485,7 @@ point_count == 0 ? face->cvt_size : point_count ); - if ( !points || - !deltas || - ( localpoints == ALL_POINTS && point_count != face->cvt_size ) ) + if ( !points || !deltas ) ; /* failure, ignore it */ else if ( localpoints == ALL_POINTS ) @@ -3514,6 +3600,16 @@ NULL ); return error; + +#else /* !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + FT_UNUSED( face ); + FT_UNUSED( stream ); + + return FT_Err_Ok; + +#endif /* !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + } diff --git a/thirdparty/freetype/src/truetype/ttgxvar.h b/thirdparty/freetype/src/truetype/ttgxvar.h index 26e89bcf74..ded9ea1d6d 100644 --- a/thirdparty/freetype/src/truetype/ttgxvar.h +++ b/thirdparty/freetype/src/truetype/ttgxvar.h @@ -4,7 +4,7 @@ * * TrueType GX Font Variation loader (specification) * - * Copyright (C) 2004-2020 by + * Copyright (C) 2004-2021 by * David Turner, Robert Wilhelm, Werner Lemberg and George Williams. * * This file is part of the FreeType project, and may only be used, @@ -106,9 +106,9 @@ FT_BEGIN_HEADER typedef struct GX_DeltaSetIdxMapRec_ { - FT_UInt mapCount; - FT_UInt* outerIndex; /* indices to item var data */ - FT_UInt* innerIndex; /* indices to delta set */ + FT_ULong mapCount; + FT_UInt* outerIndex; /* indices to item var data */ + FT_UInt* innerIndex; /* indices to delta set */ } GX_DeltaSetIdxMapRec, *GX_DeltaSetIdxMap; diff --git a/thirdparty/freetype/src/truetype/ttinterp.c b/thirdparty/freetype/src/truetype/ttinterp.c index 0c3cb10ae8..731095ed0c 100644 --- a/thirdparty/freetype/src/truetype/ttinterp.c +++ b/thirdparty/freetype/src/truetype/ttinterp.c @@ -4,7 +4,7 @@ * * TrueType bytecode interpreter (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -251,6 +251,14 @@ FT_FREE( exec->stack ); exec->stackSize = 0; + /* free glyf cvt working area */ + FT_FREE( exec->glyfCvt ); + exec->glyfCvtSize = 0; + + /* free glyf storage working area */ + FT_FREE( exec->glyfStorage ); + exec->glyfStoreSize = 0; + /* free call stack */ FT_FREE( exec->callStack ); exec->callSize = 0; @@ -270,64 +278,6 @@ /************************************************************************** * * @Function: - * Init_Context - * - * @Description: - * Initializes a context object. - * - * @Input: - * memory :: - * A handle to the parent memory object. - * - * @InOut: - * exec :: - * A handle to the target execution context. - * - * @Return: - * FreeType error code. 0 means success. - */ - static FT_Error - Init_Context( TT_ExecContext exec, - FT_Memory memory ) - { - FT_Error error; - - - FT_TRACE1(( "Init_Context: new object at %p\n", (void *)exec )); - - exec->memory = memory; - exec->callSize = 32; - - if ( FT_NEW_ARRAY( exec->callStack, exec->callSize ) ) - goto Fail_Memory; - - /* all values in the context are set to 0 already, but this is */ - /* here as a remainder */ - exec->maxPoints = 0; - exec->maxContours = 0; - - exec->stackSize = 0; - exec->glyphSize = 0; - - exec->stack = NULL; - exec->glyphIns = NULL; - - exec->face = NULL; - exec->size = NULL; - - return FT_Err_Ok; - - Fail_Memory: - FT_ERROR(( "Init_Context: not enough memory for %p\n", (void *)exec )); - TT_Done_Context( exec ); - - return error; - } - - - /************************************************************************** - * - * @Function: * Update_Max * * @Description: @@ -367,7 +317,7 @@ if ( *size < new_max ) { - if ( FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) ) + if ( FT_QREALLOC( *pbuff, *size * multiplier, new_max * multiplier ) ) return error; *size = new_max; } @@ -400,6 +350,8 @@ * * @Note: * Only the glyph loader and debugger should call this function. + * + * Note that not all members of `TT_ExecContext` get initialized. */ FT_LOCAL_DEF( FT_Error ) TT_Load_Context( TT_ExecContext exec, @@ -464,13 +416,13 @@ if ( error ) return error; - tmp = exec->glyphSize; + tmp = (FT_ULong)exec->glyphSize; error = Update_Max( exec->memory, &tmp, sizeof ( FT_Byte ), (void*)&exec->glyphIns, maxp->maxSizeOfInstructions ); - exec->glyphSize = (FT_UShort)tmp; + exec->glyphSize = (FT_UInt)tmp; if ( error ) return error; @@ -609,19 +561,19 @@ memory = driver->root.root.memory; - /* allocate object */ + /* allocate object and zero everything inside */ if ( FT_NEW( exec ) ) goto Fail; - /* initialize it; in case of error this deallocates `exec' too */ - error = Init_Context( exec, memory ); - if ( error ) - goto Fail; + /* create callStack here, other allocations delayed */ + exec->memory = memory; + exec->callSize = 32; - return exec; + if ( FT_QNEW_ARRAY( exec->callStack, exec->callSize ) ) + FT_FREE( exec ); Fail: - return NULL; + return exec; } @@ -1572,11 +1524,36 @@ } + static void + Modify_CVT_Check( TT_ExecContext exc ) + { + /* TT_RunIns sets origCvt and restores cvt to origCvt when done. */ + if ( exc->iniRange == tt_coderange_glyph && + exc->cvt == exc->origCvt ) + { + exc->error = Update_Max( exc->memory, + &exc->glyfCvtSize, + sizeof ( FT_Long ), + (void*)&exc->glyfCvt, + exc->cvtSize ); + if ( exc->error ) + return; + + FT_ARRAY_COPY( exc->glyfCvt, exc->cvt, exc->glyfCvtSize ); + exc->cvt = exc->glyfCvt; + } + } + + FT_CALLBACK_DEF( void ) Write_CVT( TT_ExecContext exc, FT_ULong idx, FT_F26Dot6 value ) { + Modify_CVT_Check( exc ); + if ( exc->error ) + return; + exc->cvt[idx] = value; } @@ -1586,6 +1563,10 @@ FT_ULong idx, FT_F26Dot6 value ) { + Modify_CVT_Check( exc ); + if ( exc->error ) + return; + exc->cvt[idx] = FT_DivFix( value, Current_Ratio( exc ) ); } @@ -1595,6 +1576,10 @@ FT_ULong idx, FT_F26Dot6 value ) { + Modify_CVT_Check( exc ); + if ( exc->error ) + return; + exc->cvt[idx] = ADD_LONG( exc->cvt[idx], value ); } @@ -1604,6 +1589,10 @@ FT_ULong idx, FT_F26Dot6 value ) { + Modify_CVT_Check( exc ); + if ( exc->error ) + return; + exc->cvt[idx] = ADD_LONG( exc->cvt[idx], FT_DivFix( value, Current_Ratio( exc ) ) ); } @@ -3125,7 +3114,30 @@ ARRAY_BOUND_ERROR; } else + { + /* TT_RunIns sets origStorage and restores storage to origStorage */ + /* when done. */ + if ( exc->iniRange == tt_coderange_glyph && + exc->storage == exc->origStorage ) + { + FT_ULong tmp = (FT_ULong)exc->glyfStoreSize; + + + exc->error = Update_Max( exc->memory, + &tmp, + sizeof ( FT_Long ), + (void*)&exc->glyfStorage, + exc->storeSize ); + exc->glyfStoreSize = (FT_UShort)tmp; + if ( exc->error ) + return; + + FT_ARRAY_COPY( exc->glyfStorage, exc->storage, exc->glyfStoreSize ); + exc->storage = exc->glyfStorage; + } + exc->storage[I] = args[1]; + } } @@ -3525,7 +3537,7 @@ return; } - exc->IP += args[0]; + exc->IP = ADD_LONG( exc->IP, args[0] ); if ( exc->IP < 0 || ( exc->callTop > 0 && exc->IP > exc->callStack[exc->callTop - 1].Def->end ) ) @@ -3697,7 +3709,7 @@ /* FDEF is only allowed in `prep' or `fpgm' */ - if ( exc->curRange == tt_coderange_glyph ) + if ( exc->iniRange == tt_coderange_glyph ) { exc->error = FT_THROW( DEF_In_Glyf_Bytecode ); return; @@ -3771,7 +3783,7 @@ if ( opcode_pointer[i] == opcode_size[i] ) { - FT_TRACE6(( "sph: Function %d, opcode ptrn: %d, %s %s\n", + FT_TRACE6(( "sph: Function %d, opcode ptrn: %ld, %s %s\n", i, n, exc->face->root.family_name, exc->face->root.style_name )); @@ -4133,7 +4145,7 @@ /* we enable IDEF only in `prep' or `fpgm' */ - if ( exc->curRange == tt_coderange_glyph ) + if ( exc->iniRange == tt_coderange_glyph ) { exc->error = FT_THROW( DEF_In_Glyf_Bytecode ); return; @@ -4362,7 +4374,7 @@ if ( ( opcode & 1 ) != 0 ) { - C = B; /* counter clockwise rotation */ + C = B; /* counter-clockwise rotation */ B = A; A = NEG_LONG( C ); } @@ -4991,9 +5003,9 @@ #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */ - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - FT_ABS( D ) == 64 ) + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + ( D < 0 ? NEG_LONG( D ) : D ) == 64 ) D += 1; #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ @@ -5050,7 +5062,7 @@ if ( ( opcode & 1 ) != 0 ) { - C = B; /* counter clockwise rotation */ + C = B; /* counter-clockwise rotation */ B = A; A = NEG_LONG( C ); } @@ -5074,7 +5086,7 @@ if ( ( opcode & 1 ) != 0 ) { - C = B; /* counter clockwise rotation */ + C = B; /* counter-clockwise rotation */ B = A; A = NEG_LONG( C ); } @@ -7781,8 +7793,8 @@ if ( num_twilight_points > 0xFFFFU ) num_twilight_points = 0xFFFFU; - FT_TRACE5(( "TT_RunIns: Resetting number of twilight points\n" - " from %d to the more reasonable value %ld\n", + FT_TRACE5(( "TT_RunIns: Resetting number of twilight points\n" )); + FT_TRACE5(( " from %d to the more reasonable value %ld\n", exc->twilight.n_points, num_twilight_points )); exc->twilight.n_points = (FT_UShort)num_twilight_points; @@ -7842,6 +7854,10 @@ exc->func_move_cvt = Move_CVT; } + exc->origCvt = exc->cvt; + exc->origStorage = exc->storage; + exc->iniRange = exc->curRange; + Compute_Funcs( exc ); Compute_Round( exc, (FT_Byte)exc->GS.round_state ); @@ -7850,6 +7866,7 @@ exc->opcode = exc->code[exc->IP]; #ifdef FT_DEBUG_LEVEL_TRACE + if ( ft_trace_levels[trace_ttinterp] >= 6 ) { FT_Long cnt = FT_MIN( 8, exc->top ); FT_Long n; @@ -8566,8 +8583,10 @@ /* increment instruction counter and check if we didn't */ /* run this program for too long (e.g. infinite loops). */ - if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES ) - return FT_THROW( Execution_Too_Long ); + if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES ) { + exc->error = FT_THROW( Execution_Too_Long ); + goto LErrorLabel_; + } LSuiteLabel_: if ( exc->IP >= exc->codeSize ) @@ -8586,6 +8605,10 @@ FT_TRACE4(( " %ld instruction%s executed\n", ins_counter, ins_counter == 1 ? "" : "s" )); + + exc->cvt = exc->origCvt; + exc->storage = exc->origStorage; + return FT_Err_Ok; LErrorCodeOverflow_: @@ -8595,6 +8618,9 @@ if ( exc->error && !exc->instruction_trap ) FT_TRACE1(( " The interpreter returned error 0x%x\n", exc->error )); + exc->cvt = exc->origCvt; + exc->storage = exc->origStorage; + return exc->error; } diff --git a/thirdparty/freetype/src/truetype/ttinterp.h b/thirdparty/freetype/src/truetype/ttinterp.h index 6a83705a6c..9c01ec83cb 100644 --- a/thirdparty/freetype/src/truetype/ttinterp.h +++ b/thirdparty/freetype/src/truetype/ttinterp.h @@ -4,7 +4,7 @@ * * TrueType bytecode interpreter (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -144,37 +144,41 @@ FT_BEGIN_HEADER * * The main structure for the interpreter which collects all necessary * variables and states. + * + * Members that are initialized by `TT_Load_Context` are marked with '!'. + * Members that are initialized by `TT_Run_Context` are marked with '@'. */ typedef struct TT_ExecContextRec_ { - TT_Face face; - TT_Size size; + TT_Face face; /* ! */ + TT_Size size; /* ! */ FT_Memory memory; /* instructions state */ FT_Error error; /* last execution error */ - FT_Long top; /* top of exec. stack */ + FT_Long top; /* @ top of exec. stack */ - FT_Long stackSize; /* size of exec. stack */ - FT_Long* stack; /* current exec. stack */ + FT_Long stackSize; /* ! size of exec. stack */ + FT_Long* stack; /* ! current exec. stack */ FT_Long args; - FT_Long new_top; /* new top after exec. */ + FT_Long new_top; /* new top after exec. */ - TT_GlyphZoneRec zp0, /* zone records */ - zp1, - zp2, - pts, - twilight; + TT_GlyphZoneRec zp0, /* @! zone records */ + zp1, /* @! */ + zp2, /* @! */ + pts, /* ! */ + twilight; /* ! */ - FT_Long pointSize; /* in 26.6 format */ - FT_Size_Metrics metrics; - TT_Size_Metrics tt_metrics; /* size metrics */ + FT_Long pointSize; /* ! in 26.6 format */ + FT_Size_Metrics metrics; /* ! */ + TT_Size_Metrics tt_metrics; /* ! size metrics */ - TT_GraphicsState GS; /* current graphics state */ + TT_GraphicsState GS; /* !@ current graphics state */ + FT_Int iniRange; /* initial code range number */ FT_Int curRange; /* current code range number */ FT_Byte* code; /* current code range */ FT_Long IP; /* current instruction pointer */ @@ -185,43 +189,49 @@ FT_BEGIN_HEADER FT_Bool step_ins; /* true if the interpreter must */ /* increment IP after ins. exec */ - FT_ULong cvtSize; - FT_Long* cvt; + FT_ULong cvtSize; /* ! */ + FT_Long* cvt; /* ! */ + FT_ULong glyfCvtSize; + FT_Long* glyfCvt; /* cvt working copy for glyph */ + FT_Long* origCvt; - FT_UInt glyphSize; /* glyph instructions buffer size */ - FT_Byte* glyphIns; /* glyph instructions buffer */ + FT_UInt glyphSize; /* ! glyph instructions buffer size */ + FT_Byte* glyphIns; /* ! glyph instructions buffer */ - FT_UInt numFDefs; /* number of function defs */ - FT_UInt maxFDefs; /* maximum number of function defs */ - TT_DefArray FDefs; /* table of FDefs entries */ + FT_UInt numFDefs; /* ! number of function defs */ + FT_UInt maxFDefs; /* ! maximum number of function defs */ + TT_DefArray FDefs; /* table of FDefs entries */ - FT_UInt numIDefs; /* number of instruction defs */ - FT_UInt maxIDefs; /* maximum number of ins defs */ - TT_DefArray IDefs; /* table of IDefs entries */ + FT_UInt numIDefs; /* ! number of instruction defs */ + FT_UInt maxIDefs; /* ! maximum number of ins defs */ + TT_DefArray IDefs; /* table of IDefs entries */ - FT_UInt maxFunc; /* maximum function index */ - FT_UInt maxIns; /* maximum instruction index */ + FT_UInt maxFunc; /* ! maximum function index */ + FT_UInt maxIns; /* ! maximum instruction index */ - FT_Int callTop, /* top of call stack during execution */ - callSize; /* size of call stack */ - TT_CallStack callStack; /* call stack */ + FT_Int callTop, /* @ top of call stack during execution */ + callSize; /* size of call stack */ + TT_CallStack callStack; /* call stack */ FT_UShort maxPoints; /* capacity of this context's `pts' */ FT_Short maxContours; /* record, expressed in points and */ /* contours. */ - TT_CodeRangeTable codeRangeTable; /* table of valid code ranges */ - /* useful for the debugger */ + TT_CodeRangeTable codeRangeTable; /* ! table of valid code ranges */ + /* useful for the debugger */ - FT_UShort storeSize; /* size of current storage */ - FT_Long* storage; /* storage area */ + FT_UShort storeSize; /* ! size of current storage */ + FT_Long* storage; /* ! storage area */ + FT_UShort glyfStoreSize; + FT_Long* glyfStorage; /* storage working copy for glyph */ + FT_Long* origStorage; FT_F26Dot6 period; /* values used for the */ FT_F26Dot6 phase; /* `SuperRounding' */ FT_F26Dot6 threshold; - FT_Bool instruction_trap; /* If `True', the interpreter will */ - /* exit after each instruction */ + FT_Bool instruction_trap; /* ! If `True', the interpreter */ + /* exits after each instruction */ TT_GraphicsState default_GS; /* graphics state resulting from */ /* the prep program */ @@ -238,7 +248,7 @@ FT_BEGIN_HEADER func_dualproj, /* current dual proj. function */ func_freeProj; /* current freedom proj. func */ - TT_Move_Func func_move; /* current point move function */ + TT_Move_Func func_move; /* current point move function */ TT_Move_Func func_move_orig; /* move original position function */ TT_Cur_Ppem_Func func_cur_ppem; /* get current proj. ppem value */ @@ -469,16 +479,15 @@ FT_BEGIN_HEADER * TT_New_Context * * @Description: - * Queries the face context for a given font. Note that there is - * now a _single_ execution context in the TrueType driver which is - * shared among faces. + * Create a `TT_ExecContext`. Note that there is now an execution + * context per `TT_Size` that is not shared among faces. * * @Input: - * face :: - * A handle to the source face object. + * driver :: + * A handle to the driver, used for memory allocation. * * @Return: - * A handle to the execution context. Initialized for `face'. + * A handle to a new empty execution context. * * @Note: * Only the glyph loader and debugger should call this function. diff --git a/thirdparty/freetype/src/truetype/ttobjs.c b/thirdparty/freetype/src/truetype/ttobjs.c index 06d4569559..93fc548447 100644 --- a/thirdparty/freetype/src/truetype/ttobjs.c +++ b/thirdparty/freetype/src/truetype/ttobjs.c @@ -4,7 +4,7 @@ * * Objects manager (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -140,7 +140,31 @@ return error; } -#endif /* TT_USE_BYTECODE_INTERPRETER */ + + + /* + * Fonts embedded in PDFs are made unique by prepending randomization + * prefixes to their names: as defined in Section 5.5.3, 'Font Subsets', + * of the PDF Reference, they consist of 6 uppercase letters followed by + * the `+` sign. For safety, we do not skip prefixes violating this rule. + */ + + static const FT_String* + tt_skip_pdffont_random_tag( const FT_String* name ) + { + unsigned int i; + + + if ( ft_strlen( name ) < 8 || name[6] != '+' ) + return name; + + for ( i = 0; i < 6; i++ ) + if ( !ft_isupper( name[i] ) ) + return name; + + FT_TRACE7(( "name without randomization tag: %s\n", name + 7 )); + return name + 7; + } /* Compare the face with a list of well-known `tricky' fonts. */ @@ -151,7 +175,7 @@ { #define TRICK_NAMES_MAX_CHARACTERS 19 -#define TRICK_NAMES_COUNT 26 +#define TRICK_NAMES_COUNT 20 static const char trick_names[TRICK_NAMES_COUNT] [TRICK_NAMES_MAX_CHARACTERS + 1] = @@ -171,22 +195,28 @@ "DFGirl-W6-WIN-BF", /* dftt-h6.ttf; version 1.00, 1993 */ "DFGothic-EB", /* DynaLab Inc. 1992-1995 */ "DFGyoSho-Lt", /* DynaLab Inc. 1992-1995 */ - "DFHei-Md-HK-BF", /* maybe DynaLab Inc. */ + "DFHei", /* DynaLab Inc. 1992-1995 [DFHei-Bd-WIN-HK-BF] */ + /* covers "DFHei-Md-HK-BF", maybe DynaLab Inc. */ + "DFHSGothic-W5", /* DynaLab Inc. 1992-1995 */ "DFHSMincho-W3", /* DynaLab Inc. 1992-1995 */ "DFHSMincho-W7", /* DynaLab Inc. 1992-1995 */ "DFKaiSho-SB", /* dfkaisb.ttf */ - "DFKaiShu", - "DFKaiShu-Md-HK-BF", /* maybe DynaLab Inc. */ + "DFKaiShu", /* covers "DFKaiShu-Md-HK-BF", maybe DynaLab Inc. */ "DFKai-SB", /* kaiu.ttf; version 3.00, 1998 [DFKaiShu-SB-Estd-BF] */ - "DFMing-Bd-HK-BF", /* maybe DynaLab Inc. */ + + "DFMing", /* DynaLab Inc. 1992-1995 [DFMing-Md-WIN-HK-BF] */ + /* covers "DFMing-Bd-HK-BF", maybe DynaLab Inc. */ + "DLC", /* dftt-m7.ttf; version 1.00, 1993 [DLCMingBold] */ /* dftt-f5.ttf; version 1.00, 1993 [DLCFongSung] */ - "DLCHayMedium", /* dftt-b5.ttf; version 1.00, 1993 */ - "DLCHayBold", /* dftt-b7.ttf; version 1.00, 1993 */ - "DLCKaiMedium", /* dftt-k5.ttf; version 1.00, 1992 */ - "DLCLiShu", /* dftt-l5.ttf; version 1.00, 1992 */ - "DLCRoundBold", /* dftt-r7.ttf; version 1.00, 1993 */ + /* covers following */ + /* "DLCHayMedium", dftt-b5.ttf; version 1.00, 1993 */ + /* "DLCHayBold", dftt-b7.ttf; version 1.00, 1993 */ + /* "DLCKaiMedium", dftt-k5.ttf; version 1.00, 1992 */ + /* "DLCLiShu", dftt-l5.ttf; version 1.00, 1992 */ + /* "DLCRoundBold", dftt-r7.ttf; version 1.00, 1993 */ + "HuaTianKaiTi?", /* htkt2.ttf */ "HuaTianSongTi?", /* htst3.ttf */ "Ming(for ISO10646)", /* hkscsiic.ttf; version 0.12, 2007 [Ming] */ @@ -199,10 +229,12 @@ }; int nn; + const FT_String* name_without_tag; + name_without_tag = tt_skip_pdffont_random_tag( name ); for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ ) - if ( ft_strstr( name, trick_names[nn] ) ) + if ( ft_strstr( name_without_tag, trick_names[nn] ) ) return TRUE; return FALSE; @@ -277,7 +309,7 @@ tt_check_trickyness_sfnt_ids( TT_Face face ) { #define TRICK_SFNT_IDS_PER_FACE 3 -#define TRICK_SFNT_IDS_NUM_FACES 29 +#define TRICK_SFNT_IDS_NUM_FACES 31 static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES] [TRICK_SFNT_IDS_PER_FACE] = { @@ -430,6 +462,16 @@ { 0x00170003UL, 0x00000060UL }, /* cvt */ { 0xDBB4306EUL, 0x000058AAUL }, /* fpgm */ { 0xD643482AUL, 0x00000035UL } /* prep */ + }, + { /* DFHei-Bd-WIN-HK-BF, issue #1087 */ + { 0x1269EB58UL, 0x00000350UL }, /* cvt */ + { 0x5CD5957AUL, 0x00006A4EUL }, /* fpgm */ + { 0xF758323AUL, 0x00000380UL } /* prep */ + }, + { /* DFMing-Md-WIN-HK-BF, issue #1087 */ + { 0x122FEB0BUL, 0x00000350UL }, /* cvt */ + { 0x7F10919AUL, 0x000070A9UL }, /* fpgm */ + { 0x7CD7E7B7UL, 0x0000025CUL } /* prep */ } }; @@ -510,17 +552,27 @@ /* For first, check the face name for quick check. */ if ( face->family_name && tt_check_trickyness_family( face->family_name ) ) + { + FT_TRACE3(( "found as a tricky font" + " by its family name: %s\n", face->family_name )); return TRUE; + } /* Type42 fonts may lack `name' tables, we thus try to identify */ /* tricky fonts by checking the checksums of Type42-persistent */ /* sfnt tables (`cvt', `fpgm', and `prep'). */ if ( tt_check_trickyness_sfnt_ids( (TT_Face)face ) ) + { + FT_TRACE3(( "found as a tricky font" + " by its cvt/fpgm/prep table checksum\n" )); return TRUE; + } return FALSE; } +#endif /* TT_USE_BYTECODE_INTERPRETER */ + /* Check whether `.notdef' is the only glyph in the `loca' table. */ static FT_Bool @@ -666,8 +718,10 @@ if ( error ) goto Exit; +#ifdef TT_USE_BYTECODE_INTERPRETER if ( tt_check_trickyness( ttface ) ) ttface->face_flags |= FT_FACE_FLAG_TRICKY; +#endif error = tt_face_load_hdmx( face, stream ); if ( error ) @@ -712,8 +766,8 @@ tt_check_single_notdef( ttface ) ) { FT_TRACE5(( "tt_face_init:" - " Only the `.notdef' glyph has an outline.\n" - " " + " Only the `.notdef' glyph has an outline.\n" )); + FT_TRACE5(( " " " Resetting scalable flag to FALSE.\n" )); ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; @@ -1190,11 +1244,11 @@ /* rescale CVT when needed */ if ( size->cvt_ready < 0 ) { - FT_UInt i; + FT_UShort i; /* all twilight points are originally zero */ - for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ ) + for ( i = 0; i < size->twilight.n_points; i++ ) { size->twilight.org[i].x = 0; size->twilight.org[i].y = 0; @@ -1203,7 +1257,7 @@ } /* clear storage area */ - for ( i = 0; i < (FT_UInt)size->storage_size; i++ ) + for ( i = 0; i < size->storage_size; i++ ) size->storage[i] = 0; size->GS = tt_default_graphics_state; diff --git a/thirdparty/freetype/src/truetype/ttobjs.h b/thirdparty/freetype/src/truetype/ttobjs.h index d986deabc4..fd72378721 100644 --- a/thirdparty/freetype/src/truetype/ttobjs.h +++ b/thirdparty/freetype/src/truetype/ttobjs.h @@ -4,7 +4,7 @@ * * Objects manager (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/truetype/ttpload.c b/thirdparty/freetype/src/truetype/ttpload.c index b1255b88cd..71db75ae1f 100644 --- a/thirdparty/freetype/src/truetype/ttpload.c +++ b/thirdparty/freetype/src/truetype/ttpload.c @@ -4,7 +4,7 @@ * * TrueType-specific tables loader (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -98,36 +98,23 @@ goto Exit; } - if ( face->header.Index_To_Loc_Format != 0 ) - { - shift = 2; + shift = face->header.Index_To_Loc_Format != 0 ? 2 : 1; - if ( table_len >= 0x40000L ) - { - FT_TRACE2(( "table too large\n" )); - table_len = 0x3FFFFL; - } - face->num_locations = table_len >> shift; - } - else + if ( table_len > 0x10000UL << shift ) { - shift = 1; - - if ( table_len >= 0x20000L ) - { - FT_TRACE2(( "table too large\n" )); - table_len = 0x1FFFFL; - } - face->num_locations = table_len >> shift; + FT_TRACE2(( "table too large\n" )); + table_len = 0x10000UL << shift; } + face->num_locations = table_len >> shift; + if ( face->num_locations != (FT_ULong)face->root.num_glyphs + 1 ) { FT_TRACE2(( "glyph count mismatch! loca: %ld, maxp: %ld\n", face->num_locations - 1, face->root.num_glyphs )); /* we only handle the case where `maxp' gives a larger value */ - if ( face->num_locations <= (FT_ULong)face->root.num_glyphs ) + if ( face->num_locations < (FT_ULong)face->root.num_glyphs + 1 ) { FT_ULong new_loca_len = ( (FT_ULong)face->root.num_glyphs + 1 ) << shift; @@ -237,10 +224,11 @@ if ( pos1 > face->glyf_len ) { FT_TRACE1(( "tt_face_get_location:" - " too large offset (0x%08lx) found for glyph index %d,\n" - " " + " too large offset (0x%08lx) found for glyph index %d,\n", + pos1, gindex )); + FT_TRACE1(( " " " exceeding the end of `glyf' table (0x%08lx)\n", - pos1, gindex, face->glyf_len )); + face->glyf_len )); *asize = 0; return 0; } @@ -251,19 +239,21 @@ if ( gindex == face->num_locations - 2 ) { FT_TRACE1(( "tt_face_get_location:" - " too large size (%ld bytes) found for glyph index %d,\n" - " " + " too large size (%ld bytes) found for glyph index %d,\n", + pos2 - pos1, gindex )); + FT_TRACE1(( " " " truncating at the end of `glyf' table to %ld bytes\n", - pos2 - pos1, gindex, face->glyf_len - pos1 )); + face->glyf_len - pos1 )); pos2 = face->glyf_len; } else { FT_TRACE1(( "tt_face_get_location:" - " too large offset (0x%08lx) found for glyph index %d,\n" - " " + " too large offset (0x%08lx) found for glyph index %d,\n", + pos2, gindex + 1 )); + FT_TRACE1(( " " " exceeding the end of `glyf' table (0x%08lx)\n", - pos2, gindex + 1, face->glyf_len )); + face->glyf_len )); *asize = 0; return 0; } @@ -344,7 +334,7 @@ face->cvt_size = table_len / 2; - if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) ) + if ( FT_QNEW_ARRAY( face->cvt, face->cvt_size ) ) goto Exit; if ( FT_FRAME_ENTER( face->cvt_size * 2L ) ) @@ -557,12 +547,6 @@ num_records = FT_NEXT_USHORT( p ); record_size = FT_NEXT_ULONG( p ); - /* The maximum number of bytes in an hdmx device record is the */ - /* maximum number of glyphs + 2; this is 0xFFFF + 2, thus */ - /* explaining why `record_size' is a long (which we read as */ - /* unsigned long for convenience). In practice, two bytes are */ - /* sufficient to hold the size value. */ - /* */ /* There are at least two fonts, HANNOM-A and HANNOM-B version */ /* 2.0 (2005), which get this wrong: The upper two bytes of */ /* the size value are set to 0xFF instead of 0x00. We catch */ @@ -571,19 +555,30 @@ if ( record_size >= 0xFFFF0000UL ) record_size &= 0xFFFFU; + FT_TRACE2(( "Hdmx " )); + /* The limit for `num_records' is a heuristic value. */ - if ( num_records > 255 || - ( num_records > 0 && - ( record_size > 0x10001L || - record_size < 4 ) ) ) + if ( num_records > 255 || num_records == 0 ) { - error = FT_THROW( Invalid_File_Format ); + FT_TRACE2(( "with unreasonable %u records rejected\n", num_records )); goto Fail; } - if ( FT_NEW_ARRAY( face->hdmx_record_sizes, num_records ) ) + /* Out-of-spec tables are rejected. The record size must be */ + /* equal to the number of glyphs + 2 + 32-bit padding. */ + if ( (FT_Long)record_size != ( ( face->root.num_glyphs + 2 + 3 ) & ~3 ) ) + { + FT_TRACE2(( "with record size off by %ld bytes rejected\n", + (FT_Long)record_size - + ( ( face->root.num_glyphs + 2 + 3 ) & ~3 ) )); goto Fail; + } + if ( FT_QNEW_ARRAY( face->hdmx_record_sizes, num_records ) ) + goto Fail; + + /* XXX: We do not check if the records are sorted by ppem */ + /* and cannot use binary search later. */ for ( nn = 0; nn < num_records; nn++ ) { if ( p + record_size > limit ) @@ -597,6 +592,8 @@ face->hdmx_table_size = table_size; face->hdmx_record_size = record_size; + FT_TRACE2(( "%ux%lu loaded\n", num_records, record_size )); + Exit: return error; diff --git a/thirdparty/freetype/src/truetype/ttpload.h b/thirdparty/freetype/src/truetype/ttpload.h index bb669e0278..84c42cdaf4 100644 --- a/thirdparty/freetype/src/truetype/ttpload.h +++ b/thirdparty/freetype/src/truetype/ttpload.h @@ -4,7 +4,7 @@ * * TrueType-specific tables loader (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/truetype/ttsubpix.c b/thirdparty/freetype/src/truetype/ttsubpix.c index 56667deaf7..c484665b95 100644 --- a/thirdparty/freetype/src/truetype/ttsubpix.c +++ b/thirdparty/freetype/src/truetype/ttsubpix.c @@ -4,7 +4,7 @@ * * TrueType Subpixel Hinting. * - * Copyright (C) 2010-2020 by + * Copyright (C) 2010-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -315,7 +315,7 @@ static const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] = { - /* fix vwxyz thinness*/ + /* fix vwxyz thinness */ { "Consolas", 0, "", 0 }, /* Fix thin middle stems */ { "Core MS Legacy Fonts", 0, "Regular", 0 }, @@ -891,12 +891,12 @@ #define TWEAK_RULES( x ) \ if ( sph_test_tweak( face, family, ppem, style, glyph_index, \ x##_Rules, x##_RULES_SIZE ) ) \ - loader->exec->sph_tweak_flags |= SPH_TWEAK_##x; + loader->exec->sph_tweak_flags |= SPH_TWEAK_##x #define TWEAK_RULES_EXCEPTIONS( x ) \ if ( sph_test_tweak( face, family, ppem, style, glyph_index, \ x##_Rules_Exceptions, x##_RULES_EXCEPTIONS_SIZE ) ) \ - loader->exec->sph_tweak_flags &= ~SPH_TWEAK_##x; + loader->exec->sph_tweak_flags &= ~SPH_TWEAK_##x FT_LOCAL_DEF( void ) diff --git a/thirdparty/freetype/src/truetype/ttsubpix.h b/thirdparty/freetype/src/truetype/ttsubpix.h index 229a6cf055..762b7c98a3 100644 --- a/thirdparty/freetype/src/truetype/ttsubpix.h +++ b/thirdparty/freetype/src/truetype/ttsubpix.h @@ -4,7 +4,7 @@ * * TrueType Subpixel Hinting. * - * Copyright (C) 2010-2020 by + * Copyright (C) 2010-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type1/module.mk b/thirdparty/freetype/src/type1/module.mk deleted file mode 100644 index cffb774b45..0000000000 --- a/thirdparty/freetype/src/type1/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 Type1 module definition -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += TYPE1_DRIVER - -define TYPE1_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, t1_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)type1 $(ECHO_DRIVER_DESC)Postscript font files with extension *.pfa or *.pfb$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/type1/rules.mk b/thirdparty/freetype/src/type1/rules.mk deleted file mode 100644 index 213e619247..0000000000 --- a/thirdparty/freetype/src/type1/rules.mk +++ /dev/null @@ -1,76 +0,0 @@ -# -# FreeType 2 Type1 driver configuration rules -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# Type1 driver directory -# -T1_DIR := $(SRC_DIR)/type1 - - -# compilation flags for the driver -# -T1_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(T1_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# Type1 driver sources (i.e., C files) -# -T1_DRV_SRC := $(T1_DIR)/t1parse.c \ - $(T1_DIR)/t1load.c \ - $(T1_DIR)/t1driver.c \ - $(T1_DIR)/t1afm.c \ - $(T1_DIR)/t1gload.c \ - $(T1_DIR)/t1objs.c - -# Type1 driver headers -# -T1_DRV_H := $(T1_DRV_SRC:%.c=%.h) \ - $(T1_DIR)/t1tokens.h \ - $(T1_DIR)/t1errors.h - - -# Type1 driver object(s) -# -# T1_DRV_OBJ_M is used during `multi' builds -# T1_DRV_OBJ_S is used during `single' builds -# -T1_DRV_OBJ_M := $(T1_DRV_SRC:$(T1_DIR)/%.c=$(OBJ_DIR)/%.$O) -T1_DRV_OBJ_S := $(OBJ_DIR)/type1.$O - -# Type1 driver source file for single build -# -T1_DRV_SRC_S := $(T1_DIR)/type1.c - - -# Type1 driver - single object -# -$(T1_DRV_OBJ_S): $(T1_DRV_SRC_S) $(T1_DRV_SRC) $(FREETYPE_H) $(T1_DRV_H) - $(T1_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(T1_DRV_SRC_S)) - - -# Type1 driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(T1_DIR)/%.c $(FREETYPE_H) $(T1_DRV_H) - $(T1_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(T1_DRV_OBJ_S) -DRV_OBJS_M += $(T1_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/type1/t1afm.c b/thirdparty/freetype/src/type1/t1afm.c index b9cd66b045..4c18ed1955 100644 --- a/thirdparty/freetype/src/type1/t1afm.c +++ b/thirdparty/freetype/src/type1/t1afm.c @@ -4,7 +4,7 @@ * * AFM support for Type 1 fonts (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -83,7 +83,7 @@ /* compare two kerning pairs */ - FT_CALLBACK_DEF( int ) + FT_COMPARE_DEF( int ) compare_kern_pairs( const void* a, const void* b ) { diff --git a/thirdparty/freetype/src/type1/t1afm.h b/thirdparty/freetype/src/type1/t1afm.h index edf919c791..86fe45ea3e 100644 --- a/thirdparty/freetype/src/type1/t1afm.h +++ b/thirdparty/freetype/src/type1/t1afm.h @@ -4,7 +4,7 @@ * * AFM support for Type 1 fonts (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type1/t1driver.c b/thirdparty/freetype/src/type1/t1driver.c index b786a87817..f4d7a089ae 100644 --- a/thirdparty/freetype/src/type1/t1driver.c +++ b/thirdparty/freetype/src/type1/t1driver.c @@ -4,7 +4,7 @@ * * Type 1 driver interface (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type1/t1driver.h b/thirdparty/freetype/src/type1/t1driver.h index e7eae0b88c..20a827f898 100644 --- a/thirdparty/freetype/src/type1/t1driver.h +++ b/thirdparty/freetype/src/type1/t1driver.h @@ -4,7 +4,7 @@ * * High-level Type 1 driver interface (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type1/t1errors.h b/thirdparty/freetype/src/type1/t1errors.h index ad03a3d32a..18ef75452b 100644 --- a/thirdparty/freetype/src/type1/t1errors.h +++ b/thirdparty/freetype/src/type1/t1errors.h @@ -4,7 +4,7 @@ * * Type 1 error codes (specification only). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type1/t1gload.c b/thirdparty/freetype/src/type1/t1gload.c index d16b81f246..86649edf3a 100644 --- a/thirdparty/freetype/src/type1/t1gload.c +++ b/thirdparty/freetype/src/type1/t1gload.c @@ -4,7 +4,7 @@ * * Type 1 Glyph Loader (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -79,7 +79,7 @@ /* For ordinary fonts get the character data stored in the face record. */ { char_string->pointer = type1->charstrings[glyph_index]; - char_string->length = (FT_Int)type1->charstrings_len[glyph_index]; + char_string->length = type1->charstrings_len[glyph_index]; } if ( !error ) diff --git a/thirdparty/freetype/src/type1/t1gload.h b/thirdparty/freetype/src/type1/t1gload.h index 9947507c84..a924d551a9 100644 --- a/thirdparty/freetype/src/type1/t1gload.h +++ b/thirdparty/freetype/src/type1/t1gload.h @@ -4,7 +4,7 @@ * * Type 1 Glyph Loader (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type1/t1load.c b/thirdparty/freetype/src/type1/t1load.c index 84986007b0..bb62c79902 100644 --- a/thirdparty/freetype/src/type1/t1load.c +++ b/thirdparty/freetype/src/type1/t1load.c @@ -4,7 +4,7 @@ * * Type 1 font loader (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -117,6 +117,9 @@ goto Exit; blend->num_default_design_vector = 0; + blend->weight_vector = NULL; + blend->default_weight_vector = NULL; + blend->design_pos[0] = NULL; face->blend = blend; } @@ -130,14 +133,11 @@ /* allocate the blend `private' and `font_info' dictionaries */ - if ( FT_NEW_ARRAY( blend->font_infos[1], num_designs ) || - FT_NEW_ARRAY( blend->privates [1], num_designs ) || - FT_NEW_ARRAY( blend->bboxes [1], num_designs ) || - FT_NEW_ARRAY( blend->weight_vector, num_designs * 2 ) ) + if ( FT_NEW_ARRAY( blend->font_infos[1], num_designs ) || + FT_NEW_ARRAY( blend->privates [1], num_designs ) || + FT_NEW_ARRAY( blend->bboxes [1], num_designs ) ) goto Exit; - blend->default_weight_vector = blend->weight_vector + num_designs; - blend->font_infos[0] = &face->type1.font_info; blend->privates [0] = &face->type1.private_dict; blend->bboxes [0] = &face->type1.font_bbox; @@ -164,21 +164,6 @@ blend->num_axis = num_axis; } - /* allocate the blend design pos table if needed */ - num_designs = blend->num_designs; - num_axis = blend->num_axis; - if ( num_designs && num_axis && blend->design_pos[0] == 0 ) - { - FT_UInt n; - - - if ( FT_NEW_ARRAY( blend->design_pos[0], num_designs * num_axis ) ) - goto Exit; - - for ( n = 1; n < num_designs; n++ ) - blend->design_pos[n] = blend->design_pos[0] + num_axis * n; - } - Exit: return error; @@ -580,7 +565,7 @@ { FT_Error error; PS_Blend blend = face->blend; - FT_UInt n, p; + FT_UInt n; FT_Fixed final_blends[T1_MAX_MM_DESIGNS]; @@ -599,7 +584,7 @@ PS_DesignMap map = blend->design_map + n; FT_Long* designs = map->design_points; FT_Fixed* blends = map->blend_points; - FT_Int before = -1, after = -1; + FT_Int p, before = -1, after = -1; /* use a default value if we don't have a coordinate */ @@ -608,7 +593,7 @@ else design = ( designs[map->num_points - 1] - designs[0] ) / 2; - for ( p = 0; p < (FT_UInt)map->num_points; p++ ) + for ( p = 0; p < (FT_Int)map->num_points; p++ ) { FT_Long p_design = designs[p]; @@ -622,11 +607,11 @@ if ( design < p_design ) { - after = (FT_Int)p; + after = p; break; } - before = (FT_Int)p; + before = p; } /* now interpolate if necessary */ @@ -851,7 +836,7 @@ FT_FREE( name ); } - if ( FT_ALLOC( blend->axis_names[n], len + 1 ) ) + if ( FT_QALLOC( blend->axis_names[n], len + 1 ) ) goto Exit; name = (FT_Byte*)blend->axis_names[n]; @@ -872,12 +857,14 @@ { T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS]; FT_Int num_designs; - FT_Int num_axis; - T1_Parser parser = &loader->parser; + FT_Int num_axis = 0; /* make compiler happy */ + T1_Parser parser = &loader->parser; + FT_Memory memory = face->root.memory; + FT_Error error = FT_Err_Ok; + FT_Fixed* design_pos[T1_MAX_MM_DESIGNS]; - FT_Error error = FT_Err_Ok; - PS_Blend blend; + design_pos[0] = NULL; /* get the array of design tokens -- compute number of designs */ T1_ToTokenArray( parser, design_tokens, @@ -899,12 +886,10 @@ { FT_Byte* old_cursor = parser->root.cursor; FT_Byte* old_limit = parser->root.limit; - FT_Int n; + FT_Int n, nn; + PS_Blend blend; - blend = face->blend; - num_axis = 0; /* make compiler happy */ - FT_TRACE4(( " [" )); for ( n = 0; n < num_designs; n++ ) @@ -937,7 +922,13 @@ (FT_UInt)num_axis ); if ( error ) goto Exit; - blend = face->blend; + + /* allocate a blend design pos table */ + if ( FT_QNEW_ARRAY( design_pos[0], num_designs * num_axis ) ) + goto Exit; + + for ( nn = 1; nn < num_designs; nn++ ) + design_pos[nn] = design_pos[0] + num_axis * nn; } else if ( n_axis != num_axis ) { @@ -955,8 +946,8 @@ parser->root.cursor = token2->start; parser->root.limit = token2->limit; - blend->design_pos[n][axis] = T1_ToFixed( parser, 0 ); - FT_TRACE4(( " %f", (double)blend->design_pos[n][axis] / 65536 )); + design_pos[n][axis] = T1_ToFixed( parser, 0 ); + FT_TRACE4(( " %f", (double)design_pos[n][axis] / 65536 )); } FT_TRACE4(( "]" )) ; } @@ -965,9 +956,21 @@ loader->parser.root.cursor = old_cursor; loader->parser.root.limit = old_limit; + + /* a valid BlendDesignPosition has been parsed */ + blend = face->blend; + if ( blend->design_pos[0] ) + FT_FREE( blend->design_pos[0] ); + + for ( n = 0; n < num_designs; n++ ) + { + blend->design_pos[n] = design_pos[n]; + design_pos[n] = NULL; + } } Exit: + FT_FREE( design_pos[0] ); loader->parser.root.error = error; } @@ -1044,7 +1047,7 @@ } /* allocate design map data */ - if ( FT_NEW_ARRAY( map->design_points, num_points * 2 ) ) + if ( FT_QNEW_ARRAY( map->design_points, num_points * 2 ) ) goto Exit; map->blend_points = map->design_points + num_points; map->num_points = (FT_Byte)num_points; @@ -1088,6 +1091,7 @@ T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS]; FT_Int num_designs; FT_Error error = FT_Err_Ok; + FT_Memory memory = face->root.memory; T1_Parser parser = &loader->parser; PS_Blend blend = face->blend; T1_Token token; @@ -1122,13 +1126,19 @@ else if ( blend->num_designs != (FT_UInt)num_designs ) { FT_ERROR(( "parse_weight_vector:" - " /BlendDesignPosition and /WeightVector have\n" - " " + " /BlendDesignPosition and /WeightVector have\n" )); + FT_ERROR(( " " " different number of elements\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } + if ( !blend->weight_vector ) + if ( FT_QNEW_ARRAY( blend->weight_vector, num_designs * 2 ) ) + goto Exit; + + blend->default_weight_vector = blend->weight_vector + num_designs; + old_cursor = parser->root.cursor; old_limit = parser->root.limit; @@ -1307,9 +1317,9 @@ else { FT_TRACE1(( "t1_load_keyword: ignoring keyword `%s'" - " which is not valid at this point\n" - " (probably due to missing keywords)\n", + " which is not valid at this point\n", field->ident )); + FT_TRACE1(( " (probably due to missing keywords)\n" )); error = FT_Err_Ok; } @@ -1858,7 +1868,7 @@ } /* t1_decrypt() shouldn't write to base -- make temporary copy */ - if ( FT_ALLOC( temp, size ) ) + if ( FT_QALLOC( temp, size ) ) goto Fail; FT_MEM_COPY( temp, base, size ); psaux->t1_decrypt( temp, size, 4330 ); @@ -2068,7 +2078,7 @@ } /* t1_decrypt() shouldn't write to base -- make temporary copy */ - if ( FT_ALLOC( temp, size ) ) + if ( FT_QALLOC( temp, size ) ) goto Fail; FT_MEM_COPY( temp, base, size ); psaux->t1_decrypt( temp, size, 4330 ); @@ -2578,7 +2588,15 @@ ( !face->blend->num_designs || !face->blend->num_axis ) ) T1_Done_Blend( face ); - /* another safety check */ + /* the font may have no valid WeightVector */ + if ( face->blend && !face->blend->weight_vector ) + T1_Done_Blend( face ); + + /* the font may have no valid BlendDesignPositions */ + if ( face->blend && !face->blend->design_pos[0] ) + T1_Done_Blend( face ); + + /* the font may have no valid BlendDesignMap */ if ( face->blend ) { FT_UInt i; diff --git a/thirdparty/freetype/src/type1/t1load.h b/thirdparty/freetype/src/type1/t1load.h index 4396415c20..ba19adb147 100644 --- a/thirdparty/freetype/src/type1/t1load.h +++ b/thirdparty/freetype/src/type1/t1load.h @@ -4,7 +4,7 @@ * * Type 1 font loader (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type1/t1objs.c b/thirdparty/freetype/src/type1/t1objs.c index 3b918b7338..50dad038fd 100644 --- a/thirdparty/freetype/src/type1/t1objs.c +++ b/thirdparty/freetype/src/type1/t1objs.c @@ -4,7 +4,7 @@ * * Type 1 objects manager (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -116,11 +116,15 @@ T1_Size_Request( FT_Size t1size, /* T1_Size */ FT_Size_Request req ) { + FT_Error error; + T1_Size size = (T1_Size)t1size; PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); - FT_Request_Metrics( size->root.face, req ); + error = FT_Request_Metrics( size->root.face, req ); + if ( error ) + goto Exit; if ( funcs ) funcs->set_scale( (PSH_Globals)t1size->internal->module_data, @@ -128,7 +132,8 @@ size->root.metrics.y_scale, 0, 0 ); - return FT_Err_Ok; + Exit: + return error; } @@ -217,7 +222,6 @@ { FT_FREE( face->buildchar ); - face->buildchar = NULL; face->len_buildchar = 0; } @@ -598,11 +602,7 @@ /* set default property values, cf. `ftt1drv.h' */ -#ifdef T1_CONFIG_OPTION_OLD_ENGINE - driver->hinting_engine = FT_HINTING_FREETYPE; -#else driver->hinting_engine = FT_HINTING_ADOBE; -#endif driver->no_stem_darkening = TRUE; diff --git a/thirdparty/freetype/src/type1/t1objs.h b/thirdparty/freetype/src/type1/t1objs.h index 536be8ba1e..5f103b5066 100644 --- a/thirdparty/freetype/src/type1/t1objs.h +++ b/thirdparty/freetype/src/type1/t1objs.h @@ -4,7 +4,7 @@ * * Type 1 objects manager (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type1/t1parse.c b/thirdparty/freetype/src/type1/t1parse.c index 74cf38bde7..9f226296a9 100644 --- a/thirdparty/freetype/src/type1/t1parse.c +++ b/thirdparty/freetype/src/type1/t1parse.c @@ -4,7 +4,7 @@ * * Type 1 parser (body). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -221,7 +221,7 @@ else { /* read segment in memory -- this is clumsy, but so does the format */ - if ( FT_ALLOC( parser->base_dict, size ) || + if ( FT_QALLOC( parser->base_dict, size ) || FT_STREAM_READ( parser->base_dict, size ) ) goto Exit; parser->base_len = size; @@ -302,8 +302,8 @@ goto Fail; } - if ( FT_STREAM_SEEK( start_pos ) || - FT_ALLOC( parser->private_dict, parser->private_len ) ) + if ( FT_STREAM_SEEK( start_pos ) || + FT_QALLOC( parser->private_dict, parser->private_len ) ) goto Fail; parser->private_len = 0; @@ -450,7 +450,7 @@ if ( parser->in_memory ) { /* note that we allocate one more byte to put a terminating `0' */ - if ( FT_ALLOC( parser->private_dict, size + 1 ) ) + if ( FT_QALLOC( parser->private_dict, size + 1 ) ) goto Fail; parser->private_len = size; } diff --git a/thirdparty/freetype/src/type1/t1parse.h b/thirdparty/freetype/src/type1/t1parse.h index 1ea0110b50..247ff73b2c 100644 --- a/thirdparty/freetype/src/type1/t1parse.h +++ b/thirdparty/freetype/src/type1/t1parse.h @@ -4,7 +4,7 @@ * * Type 1 parser (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type1/t1tokens.h b/thirdparty/freetype/src/type1/t1tokens.h index c09420355d..13ac8ac1c7 100644 --- a/thirdparty/freetype/src/type1/t1tokens.h +++ b/thirdparty/freetype/src/type1/t1tokens.h @@ -4,7 +4,7 @@ * * Type 1 tokenizer (specification). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type1/type1.c b/thirdparty/freetype/src/type1/type1.c index cadee78994..003b78cb86 100644 --- a/thirdparty/freetype/src/type1/type1.c +++ b/thirdparty/freetype/src/type1/type1.c @@ -4,7 +4,7 @@ * * FreeType Type 1 driver component (body only). * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type42/module.mk b/thirdparty/freetype/src/type42/module.mk deleted file mode 100644 index 6ef3a95ead..0000000000 --- a/thirdparty/freetype/src/type42/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 Type42 module definition -# - - -# Copyright (C) 2002-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += TYPE42_DRIVER - -define TYPE42_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, t42_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)type42 $(ECHO_DRIVER_DESC)Type 42 font files with no known extension$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/type42/rules.mk b/thirdparty/freetype/src/type42/rules.mk deleted file mode 100644 index f4ce91a3b7..0000000000 --- a/thirdparty/freetype/src/type42/rules.mk +++ /dev/null @@ -1,73 +0,0 @@ -# -# FreeType 2 Type42 driver configuration rules -# - - -# Copyright (C) 2002-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# Type42 driver directory -# -T42_DIR := $(SRC_DIR)/type42 - - -# compilation flags for the driver -# -T42_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(T42_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# Type42 driver source -# -T42_DRV_SRC := $(T42_DIR)/t42objs.c \ - $(T42_DIR)/t42parse.c \ - $(T42_DIR)/t42drivr.c - -# Type42 driver headers -# -T42_DRV_H := $(T42_DRV_SRC:%.c=%.h) \ - $(T42_DIR)/t42error.h \ - $(T42_DIR)/t42types.h - - -# Type42 driver object(s) -# -# T42_DRV_OBJ_M is used during `multi' builds -# T42_DRV_OBJ_S is used during `single' builds -# -T42_DRV_OBJ_M := $(T42_DRV_SRC:$(T42_DIR)/%.c=$(OBJ_DIR)/%.$O) -T42_DRV_OBJ_S := $(OBJ_DIR)/type42.$O - -# Type42 driver source file for single build -# -T42_DRV_SRC_S := $(T42_DIR)/type42.c - - -# Type42 driver - single object -# -$(T42_DRV_OBJ_S): $(T42_DRV_SRC_S) $(T42_DRV_SRC) $(FREETYPE_H) $(T42_DRV_H) - $(T42_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(T42_DRV_SRC_S)) - - -# Type42 driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(T42_DIR)/%.c $(FREETYPE_H) $(T42_DRV_H) - $(T42_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(T42_DRV_OBJ_S) -DRV_OBJS_M += $(T42_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/type42/t42drivr.c b/thirdparty/freetype/src/type42/t42drivr.c index 90898b4329..e74ba1deba 100644 --- a/thirdparty/freetype/src/type42/t42drivr.c +++ b/thirdparty/freetype/src/type42/t42drivr.c @@ -4,7 +4,7 @@ * * High-level Type 42 driver interface (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * Roberto Alameda. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type42/t42drivr.h b/thirdparty/freetype/src/type42/t42drivr.h index 8bf2afc755..c6d8a4409e 100644 --- a/thirdparty/freetype/src/type42/t42drivr.h +++ b/thirdparty/freetype/src/type42/t42drivr.h @@ -4,7 +4,7 @@ * * High-level Type 42 driver interface (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * Roberto Alameda. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type42/t42error.h b/thirdparty/freetype/src/type42/t42error.h index e48132ec09..470f5189a8 100644 --- a/thirdparty/freetype/src/type42/t42error.h +++ b/thirdparty/freetype/src/type42/t42error.h @@ -4,7 +4,7 @@ * * Type 42 error codes (specification only). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type42/t42objs.c b/thirdparty/freetype/src/type42/t42objs.c index 6acfcdf401..03955e945b 100644 --- a/thirdparty/freetype/src/type42/t42objs.c +++ b/thirdparty/freetype/src/type42/t42objs.c @@ -4,7 +4,7 @@ * * Type 42 objects manager (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * Roberto Alameda. * * This file is part of the FreeType project, and may only be used, @@ -44,7 +44,7 @@ parser = &loader.parser; - if ( FT_ALLOC( face->ttf_data, 12 ) ) + if ( FT_QALLOC( face->ttf_data, 12 ) ) goto Exit; /* while parsing the font we always update `face->ttf_size' so that */ @@ -510,7 +510,8 @@ error = FT_New_Size( t42face->ttf_face, &ttsize ); - t42size->ttsize = ttsize; + if ( !error ) + t42size->ttsize = ttsize; FT_Activate_Size( ttsize ); @@ -582,6 +583,7 @@ FT_Face face = t42slot->face; T42_Face t42face = (T42_Face)face; FT_GlyphSlot ttslot; + FT_Memory memory = face->memory; FT_Error error = FT_Err_Ok; @@ -593,9 +595,15 @@ else { error = FT_New_GlyphSlot( t42face->ttf_face, &ttslot ); - slot->ttslot = ttslot; + if ( !error ) + slot->ttslot = ttslot; } + /* share the loader so that the autohinter can see it */ + FT_GlyphLoader_Done( slot->ttslot->internal->loader ); + FT_FREE( slot->ttslot->internal ); + slot->ttslot->internal = t42slot->internal; + return error; } @@ -606,6 +614,8 @@ T42_GlyphSlot slot = (T42_GlyphSlot)t42slot; + /* do not destroy the inherited internal structure just yet */ + slot->ttslot->internal = NULL; FT_Done_GlyphSlot( slot->ttslot ); } diff --git a/thirdparty/freetype/src/type42/t42objs.h b/thirdparty/freetype/src/type42/t42objs.h index 69f5cffd44..cbd344ffbd 100644 --- a/thirdparty/freetype/src/type42/t42objs.h +++ b/thirdparty/freetype/src/type42/t42objs.h @@ -4,7 +4,7 @@ * * Type 42 objects manager (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * Roberto Alameda. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type42/t42parse.c b/thirdparty/freetype/src/type42/t42parse.c index 98507699fa..ea2c5198a9 100644 --- a/thirdparty/freetype/src/type42/t42parse.c +++ b/thirdparty/freetype/src/type42/t42parse.c @@ -4,7 +4,7 @@ * * Type 42 font parser (body). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * Roberto Alameda. * * This file is part of the FreeType project, and may only be used, @@ -197,7 +197,7 @@ else { /* read segment in memory */ - if ( FT_ALLOC( parser->base_dict, size ) || + if ( FT_QALLOC( parser->base_dict, size ) || FT_STREAM_READ( parser->base_dict, size ) ) goto Exit; @@ -576,6 +576,9 @@ old_string_size = 0; count = 0; + FT_TRACE2(( "\n" )); + FT_TRACE2(( "t42_parse_sfnts:\n" )); + while ( parser->root.cursor < limit ) { FT_ULong size; @@ -611,7 +614,7 @@ error = FT_THROW( Invalid_File_Format ); goto Fail; } - if ( FT_REALLOC( string_buf, old_string_size, string_size ) ) + if ( FT_QREALLOC( string_buf, old_string_size, string_size ) ) goto Fail; allocated = 1; @@ -680,6 +683,9 @@ goto Fail; } + FT_TRACE2(( " PS string size %5lu bytes, offset 0x%08lx (%lu)\n", + string_size, count, count )); + /* The whole TTF is now loaded into `string_buf'. We are */ /* checking its contents while copying it to `ttf_data'. */ @@ -702,6 +708,9 @@ status = BEFORE_TABLE_DIR; face->ttf_size = 12 + 16 * num_tables; + FT_TRACE2(( " SFNT directory contains %d tables\n", + num_tables )); + if ( (FT_Long)size < face->ttf_size ) { FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" )); @@ -709,7 +718,7 @@ goto Fail; } - if ( FT_REALLOC( face->ttf_data, 12, face->ttf_size ) ) + if ( FT_QREALLOC( face->ttf_data, 12, face->ttf_size ) ) goto Fail; } /* fall through */ @@ -727,12 +736,18 @@ FT_ULong len; + FT_TRACE2(( "\n" )); + FT_TRACE2(( " table length\n" )); + FT_TRACE2(( " ------------------------------\n" )); + for ( i = 0; i < num_tables; i++ ) { FT_Byte* p = face->ttf_data + 12 + 16 * i + 12; len = FT_PEEK_ULONG( p ); + FT_TRACE2(( " %4i 0x%08lx (%lu)\n", i, len, len )); + if ( len > size || face->ttf_size > (FT_Long)( size - len ) ) { @@ -748,8 +763,12 @@ status = OTHER_TABLES; - if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables, - face->ttf_size + 1 ) ) + FT_TRACE2(( "\n" )); + FT_TRACE2(( " allocating %ld bytes\n", face->ttf_size + 1 )); + FT_TRACE2(( "\n" )); + + if ( FT_QREALLOC( face->ttf_data, 12 + 16 * num_tables, + face->ttf_size + 1 ) ) goto Fail; } /* fall through */ diff --git a/thirdparty/freetype/src/type42/t42parse.h b/thirdparty/freetype/src/type42/t42parse.h index 2ccf052d78..0fbd2b5e0b 100644 --- a/thirdparty/freetype/src/type42/t42parse.h +++ b/thirdparty/freetype/src/type42/t42parse.h @@ -4,7 +4,7 @@ * * Type 42 font parser (specification). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * Roberto Alameda. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type42/t42types.h b/thirdparty/freetype/src/type42/t42types.h index ba0cc21429..ea2f03e893 100644 --- a/thirdparty/freetype/src/type42/t42types.h +++ b/thirdparty/freetype/src/type42/t42types.h @@ -4,7 +4,7 @@ * * Type 42 font data types (specification only). * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * Roberto Alameda. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/type42/type42.c b/thirdparty/freetype/src/type42/type42.c index 012559e2fd..d8d3936bdf 100644 --- a/thirdparty/freetype/src/type42/type42.c +++ b/thirdparty/freetype/src/type42/type42.c @@ -4,7 +4,7 @@ * * FreeType Type 42 driver component. * - * Copyright (C) 2002-2020 by + * Copyright (C) 2002-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/winfonts/fnterrs.h b/thirdparty/freetype/src/winfonts/fnterrs.h index 550de386fc..d582a9b99c 100644 --- a/thirdparty/freetype/src/winfonts/fnterrs.h +++ b/thirdparty/freetype/src/winfonts/fnterrs.h @@ -4,7 +4,7 @@ * * Win FNT/FON error codes (specification only). * - * Copyright (C) 2001-2020 by + * Copyright (C) 2001-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/thirdparty/freetype/src/winfonts/module.mk b/thirdparty/freetype/src/winfonts/module.mk deleted file mode 100644 index 4614c55fd0..0000000000 --- a/thirdparty/freetype/src/winfonts/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 Windows FNT/FON module definition -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += WINDOWS_DRIVER - -define WINDOWS_DRIVER -$(OPEN_DRIVER) FT_Driver_ClassRec, winfnt_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)winfnt $(ECHO_DRIVER_DESC)Windows bitmap fonts with extension *.fnt or *.fon$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/thirdparty/freetype/src/winfonts/rules.mk b/thirdparty/freetype/src/winfonts/rules.mk deleted file mode 100644 index e73ef5ea99..0000000000 --- a/thirdparty/freetype/src/winfonts/rules.mk +++ /dev/null @@ -1,68 +0,0 @@ -# -# FreeType 2 Windows FNT/FON driver configuration rules -# - - -# Copyright (C) 1996-2020 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# Windows driver directory -# -FNT_DIR := $(SRC_DIR)/winfonts - - -FNT_COMPILE := $(CC) $(ANSIFLAGS) \ - $I$(subst /,$(COMPILER_SEP),$(FNT_DIR)) \ - $(INCLUDE_FLAGS) \ - $(FT_CFLAGS) - - -# Windows driver sources (i.e., C files) -# -FNT_DRV_SRC := $(FNT_DIR)/winfnt.c - -# Windows driver headers -# -FNT_DRV_H := $(FNT_DRV_SRC:%.c=%.h) \ - $(FNT_DIR)/fnterrs.h - - -# Windows driver object(s) -# -# FNT_DRV_OBJ_M is used during `multi' builds -# FNT_DRV_OBJ_S is used during `single' builds -# -FNT_DRV_OBJ_M := $(FNT_DRV_SRC:$(FNT_DIR)/%.c=$(OBJ_DIR)/%.$O) -FNT_DRV_OBJ_S := $(OBJ_DIR)/winfnt.$O - -# Windows driver source file for single build -# -FNT_DRV_SRC_S := $(FNT_DIR)/winfnt.c - - -# Windows driver - single object -# -$(FNT_DRV_OBJ_S): $(FNT_DRV_SRC_S) $(FNT_DRV_SRC) $(FREETYPE_H) $(FNT_DRV_H) - $(FNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(FNT_DRV_SRC_S)) - - -# Windows driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(FNT_DIR)/%.c $(FREETYPE_H) $(FNT_DRV_H) - $(FNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(FNT_DRV_OBJ_S) -DRV_OBJS_M += $(FNT_DRV_OBJ_M) - - -# EOF diff --git a/thirdparty/freetype/src/winfonts/winfnt.c b/thirdparty/freetype/src/winfonts/winfnt.c index e83312d166..b4fabad283 100644 --- a/thirdparty/freetype/src/winfonts/winfnt.c +++ b/thirdparty/freetype/src/winfonts/winfnt.c @@ -4,7 +4,7 @@ * * FreeType font driver for Windows FNT/FON files * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * Copyright 2003 Huw D M Davies for Codeweavers * Copyright 2007 Dmitry Timoshkov for Codeweavers @@ -217,7 +217,11 @@ /* first of all, read the FNT header */ if ( FT_STREAM_SEEK( font->offset ) || FT_STREAM_READ_FIELDS( winfnt_header_fields, header ) ) + { + FT_TRACE2(( " not a Windows FNT file\n" )); + error = FT_THROW( Unknown_File_Format ); goto Exit; + } /* check header */ if ( header->version != 0x200 && @@ -284,7 +288,10 @@ /* does it begin with an MZ header? */ if ( FT_STREAM_SEEK( 0 ) || FT_STREAM_READ_FIELDS( winmz_header_fields, &mz_header ) ) + { + error = FT_ERR( Unknown_File_Format ); goto Exit; + } error = FT_ERR( Unknown_File_Format ); if ( mz_header.magic == WINFNT_MZ_MAGIC ) @@ -420,12 +427,12 @@ goto Exit; FT_TRACE2(( "magic %04lx, machine %02x, number_of_sections %u, " - "size_of_optional_header %02x\n" - "magic32 %02x, rsrc_virtual_address %04lx, " - "rsrc_size %04lx\n", + "size_of_optional_header %02x\n", pe32_header.magic, pe32_header.machine, pe32_header.number_of_sections, - pe32_header.size_of_optional_header, + pe32_header.size_of_optional_header )); + FT_TRACE2(( "magic32 %02x, rsrc_virtual_address %04lx, " + "rsrc_size %04lx\n", pe32_header.magic32, pe32_header.rsrc_virtual_address, pe32_header.rsrc_size )); @@ -793,7 +800,7 @@ root->style_flags |= FT_STYLE_FLAG_BOLD; /* set up the `fixed_sizes' array */ - if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) + if ( FT_QNEW( root->available_sizes ) ) goto Fail; root->num_fixed_sizes = 1; @@ -885,10 +892,10 @@ } family_size = font->header.file_size - font->header.face_name_offset; /* Some broken fonts don't delimit the face name with a final */ - /* NULL byte -- the frame is erroneously one byte too small. */ + /* null byte -- the frame is erroneously one byte too small. */ /* We thus allocate one more byte, setting it explicitly to */ /* zero. */ - if ( FT_ALLOC( font->family_name, family_size + 1 ) ) + if ( FT_QALLOC( font->family_name, family_size + 1 ) ) goto Fail; FT_MEM_COPY( font->family_name, @@ -897,9 +904,10 @@ font->family_name[family_size] = '\0'; - if ( FT_REALLOC( font->family_name, - family_size, - ft_strlen( font->family_name ) + 1 ) ) + /* shrink it to the actual length */ + if ( FT_QREALLOC( font->family_name, + family_size + 1, + ft_strlen( font->family_name ) + 1 ) ) goto Fail; root->family_name = font->family_name; @@ -1094,7 +1102,7 @@ /* note: since glyphs are stored in columns and not in rows we */ /* can't use ft_glyphslot_set_bitmap */ - if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, pitch ) ) + if ( FT_QALLOC_MULT( bitmap->buffer, bitmap->rows, pitch ) ) goto Exit; column = (FT_Byte*)bitmap->buffer; diff --git a/thirdparty/freetype/src/winfonts/winfnt.h b/thirdparty/freetype/src/winfonts/winfnt.h index 3367c7715e..a7134abd9c 100644 --- a/thirdparty/freetype/src/winfonts/winfnt.h +++ b/thirdparty/freetype/src/winfonts/winfnt.h @@ -4,7 +4,7 @@ * * FreeType font driver for Windows FNT/FON files * - * Copyright (C) 1996-2020 by + * Copyright (C) 1996-2021 by * David Turner, Robert Wilhelm, and Werner Lemberg. * Copyright 2007 Dmitry Timoshkov for Codeweavers * diff --git a/thirdparty/glslang/SPIRV/CInterface/spirv_c_interface.cpp b/thirdparty/glslang/SPIRV/CInterface/spirv_c_interface.cpp deleted file mode 100644 index a0790f48f1..0000000000 --- a/thirdparty/glslang/SPIRV/CInterface/spirv_c_interface.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/** - This code is based on the glslang_c_interface implementation by Viktor Latypov -**/ - -/** -BSD 2-Clause License - -Copyright (c) 2019, Viktor Latypov -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**/ - -#include "glslang/Include/glslang_c_interface.h" - -#include "SPIRV/GlslangToSpv.h" -#include "SPIRV/Logger.h" -#include "SPIRV/SpvTools.h" - -typedef struct glslang_program_s { - glslang::TProgram* program; - std::vector<unsigned int> spirv; - std::string loggerMessages; -} glslang_program_t; - -static EShLanguage c_shader_stage(glslang_stage_t stage) -{ - switch (stage) { - case GLSLANG_STAGE_VERTEX: - return EShLangVertex; - case GLSLANG_STAGE_TESSCONTROL: - return EShLangTessControl; - case GLSLANG_STAGE_TESSEVALUATION: - return EShLangTessEvaluation; - case GLSLANG_STAGE_GEOMETRY: - return EShLangGeometry; - case GLSLANG_STAGE_FRAGMENT: - return EShLangFragment; - case GLSLANG_STAGE_COMPUTE: - return EShLangCompute; - case GLSLANG_STAGE_RAYGEN_NV: - return EShLangRayGen; - case GLSLANG_STAGE_INTERSECT_NV: - return EShLangIntersect; - case GLSLANG_STAGE_ANYHIT_NV: - return EShLangAnyHit; - case GLSLANG_STAGE_CLOSESTHIT_NV: - return EShLangClosestHit; - case GLSLANG_STAGE_MISS_NV: - return EShLangMiss; - case GLSLANG_STAGE_CALLABLE_NV: - return EShLangCallable; - case GLSLANG_STAGE_TASK_NV: - return EShLangTaskNV; - case GLSLANG_STAGE_MESH_NV: - return EShLangMeshNV; - default: - break; - } - return EShLangCount; -} - -GLSLANG_EXPORT void glslang_program_SPIRV_generate(glslang_program_t* program, glslang_stage_t stage) -{ - spv::SpvBuildLogger logger; - glslang::SpvOptions spvOptions; - spvOptions.validate = true; - - const glslang::TIntermediate* intermediate = program->program->getIntermediate(c_shader_stage(stage)); - - glslang::GlslangToSpv(*intermediate, program->spirv, &logger, &spvOptions); - - program->loggerMessages = logger.getAllMessages(); -} - -GLSLANG_EXPORT size_t glslang_program_SPIRV_get_size(glslang_program_t* program) { return program->spirv.size(); } - -GLSLANG_EXPORT void glslang_program_SPIRV_get(glslang_program_t* program, unsigned int* out) -{ - memcpy(out, program->spirv.data(), program->spirv.size() * sizeof(unsigned int)); -} - -GLSLANG_EXPORT unsigned int* glslang_program_SPIRV_get_ptr(glslang_program_t* program) -{ - return program->spirv.data(); -} - -GLSLANG_EXPORT const char* glslang_program_SPIRV_get_messages(glslang_program_t* program) -{ - return program->loggerMessages.empty() ? nullptr : program->loggerMessages.c_str(); -} diff --git a/thirdparty/glslang/StandAlone/DirStackFileIncluder.h b/thirdparty/glslang/StandAlone/DirStackFileIncluder.h deleted file mode 100644 index 5a33c78fa2..0000000000 --- a/thirdparty/glslang/StandAlone/DirStackFileIncluder.h +++ /dev/null @@ -1,149 +0,0 @@ -// -// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. -// Copyright (C) 2017 Google, Inc. -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// -// Neither the name of 3Dlabs Inc. Ltd. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// - -#pragma once - -#include <vector> -#include <string> -#include <fstream> -#include <algorithm> -#include <set> - -#include "./../glslang/Public/ShaderLang.h" - -// Default include class for normal include convention of search backward -// through the stack of active include paths (for nested includes). -// Can be overridden to customize. -class DirStackFileIncluder : public glslang::TShader::Includer { -public: - DirStackFileIncluder() : externalLocalDirectoryCount(0) { } - - virtual IncludeResult* includeLocal(const char* headerName, - const char* includerName, - size_t inclusionDepth) override - { - return readLocalPath(headerName, includerName, (int)inclusionDepth); - } - - virtual IncludeResult* includeSystem(const char* headerName, - const char* /*includerName*/, - size_t /*inclusionDepth*/) override - { - return readSystemPath(headerName); - } - - // Externally set directories. E.g., from a command-line -I<dir>. - // - Most-recently pushed are checked first. - // - All these are checked after the parse-time stack of local directories - // is checked. - // - This only applies to the "local" form of #include. - // - Makes its own copy of the path. - virtual void pushExternalLocalDirectory(const std::string& dir) - { - directoryStack.push_back(dir); - externalLocalDirectoryCount = (int)directoryStack.size(); - } - - virtual void releaseInclude(IncludeResult* result) override - { - if (result != nullptr) { - delete [] static_cast<tUserDataElement*>(result->userData); - delete result; - } - } - - virtual std::set<std::string> getIncludedFiles() - { - return includedFiles; - } - - virtual ~DirStackFileIncluder() override { } - -protected: - typedef char tUserDataElement; - std::vector<std::string> directoryStack; - int externalLocalDirectoryCount; - std::set<std::string> includedFiles; - - // Search for a valid "local" path based on combining the stack of include - // directories and the nominal name of the header. - virtual IncludeResult* readLocalPath(const char* headerName, const char* includerName, int depth) - { - // Discard popped include directories, and - // initialize when at parse-time first level. - directoryStack.resize(depth + externalLocalDirectoryCount); - if (depth == 1) - directoryStack.back() = getDirectory(includerName); - - // Find a directory that works, using a reverse search of the include stack. - for (auto it = directoryStack.rbegin(); it != directoryStack.rend(); ++it) { - std::string path = *it + '/' + headerName; - std::replace(path.begin(), path.end(), '\\', '/'); - std::ifstream file(path, std::ios_base::binary | std::ios_base::ate); - if (file) { - directoryStack.push_back(getDirectory(path)); - includedFiles.insert(path); - return newIncludeResult(path, file, (int)file.tellg()); - } - } - - return nullptr; - } - - // Search for a valid <system> path. - // Not implemented yet; returning nullptr signals failure to find. - virtual IncludeResult* readSystemPath(const char* /*headerName*/) const - { - return nullptr; - } - - // Do actual reading of the file, filling in a new include result. - virtual IncludeResult* newIncludeResult(const std::string& path, std::ifstream& file, int length) const - { - char* content = new tUserDataElement [length]; - file.seekg(0, file.beg); - file.read(content, length); - return new IncludeResult(path, content, length, content); - } - - // If no path markers, return current working directory. - // Otherwise, strip file name and return path leading up to it. - virtual std::string getDirectory(const std::string path) const - { - size_t last = path.find_last_of("/\\"); - return last == std::string::npos ? "." : path.substr(0, last); - } -}; diff --git a/thirdparty/glslang/StandAlone/ResourceLimits.cpp b/thirdparty/glslang/StandAlone/ResourceLimits.cpp deleted file mode 100644 index 7c7f4c4e49..0000000000 --- a/thirdparty/glslang/StandAlone/ResourceLimits.cpp +++ /dev/null @@ -1,496 +0,0 @@ -// -// Copyright (C) 2016 Google, Inc. -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// -// Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#include <cstdlib> -#include <cstring> -#include <sstream> -#include <cctype> - -#include "ResourceLimits.h" - -namespace glslang { - -const TBuiltInResource DefaultTBuiltInResource = { - /* .MaxLights = */ 32, - /* .MaxClipPlanes = */ 6, - /* .MaxTextureUnits = */ 32, - /* .MaxTextureCoords = */ 32, - /* .MaxVertexAttribs = */ 64, - /* .MaxVertexUniformComponents = */ 4096, - /* .MaxVaryingFloats = */ 64, - /* .MaxVertexTextureImageUnits = */ 32, - /* .MaxCombinedTextureImageUnits = */ 80, - /* .MaxTextureImageUnits = */ 32, - /* .MaxFragmentUniformComponents = */ 4096, - /* .MaxDrawBuffers = */ 32, - /* .MaxVertexUniformVectors = */ 128, - /* .MaxVaryingVectors = */ 8, - /* .MaxFragmentUniformVectors = */ 16, - /* .MaxVertexOutputVectors = */ 16, - /* .MaxFragmentInputVectors = */ 15, - /* .MinProgramTexelOffset = */ -8, - /* .MaxProgramTexelOffset = */ 7, - /* .MaxClipDistances = */ 8, - /* .MaxComputeWorkGroupCountX = */ 65535, - /* .MaxComputeWorkGroupCountY = */ 65535, - /* .MaxComputeWorkGroupCountZ = */ 65535, - /* .MaxComputeWorkGroupSizeX = */ 1024, - /* .MaxComputeWorkGroupSizeY = */ 1024, - /* .MaxComputeWorkGroupSizeZ = */ 64, - /* .MaxComputeUniformComponents = */ 1024, - /* .MaxComputeTextureImageUnits = */ 16, - /* .MaxComputeImageUniforms = */ 8, - /* .MaxComputeAtomicCounters = */ 8, - /* .MaxComputeAtomicCounterBuffers = */ 1, - /* .MaxVaryingComponents = */ 60, - /* .MaxVertexOutputComponents = */ 64, - /* .MaxGeometryInputComponents = */ 64, - /* .MaxGeometryOutputComponents = */ 128, - /* .MaxFragmentInputComponents = */ 128, - /* .MaxImageUnits = */ 8, - /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8, - /* .MaxCombinedShaderOutputResources = */ 8, - /* .MaxImageSamples = */ 0, - /* .MaxVertexImageUniforms = */ 0, - /* .MaxTessControlImageUniforms = */ 0, - /* .MaxTessEvaluationImageUniforms = */ 0, - /* .MaxGeometryImageUniforms = */ 0, - /* .MaxFragmentImageUniforms = */ 8, - /* .MaxCombinedImageUniforms = */ 8, - /* .MaxGeometryTextureImageUnits = */ 16, - /* .MaxGeometryOutputVertices = */ 256, - /* .MaxGeometryTotalOutputComponents = */ 1024, - /* .MaxGeometryUniformComponents = */ 1024, - /* .MaxGeometryVaryingComponents = */ 64, - /* .MaxTessControlInputComponents = */ 128, - /* .MaxTessControlOutputComponents = */ 128, - /* .MaxTessControlTextureImageUnits = */ 16, - /* .MaxTessControlUniformComponents = */ 1024, - /* .MaxTessControlTotalOutputComponents = */ 4096, - /* .MaxTessEvaluationInputComponents = */ 128, - /* .MaxTessEvaluationOutputComponents = */ 128, - /* .MaxTessEvaluationTextureImageUnits = */ 16, - /* .MaxTessEvaluationUniformComponents = */ 1024, - /* .MaxTessPatchComponents = */ 120, - /* .MaxPatchVertices = */ 32, - /* .MaxTessGenLevel = */ 64, - /* .MaxViewports = */ 16, - /* .MaxVertexAtomicCounters = */ 0, - /* .MaxTessControlAtomicCounters = */ 0, - /* .MaxTessEvaluationAtomicCounters = */ 0, - /* .MaxGeometryAtomicCounters = */ 0, - /* .MaxFragmentAtomicCounters = */ 8, - /* .MaxCombinedAtomicCounters = */ 8, - /* .MaxAtomicCounterBindings = */ 1, - /* .MaxVertexAtomicCounterBuffers = */ 0, - /* .MaxTessControlAtomicCounterBuffers = */ 0, - /* .MaxTessEvaluationAtomicCounterBuffers = */ 0, - /* .MaxGeometryAtomicCounterBuffers = */ 0, - /* .MaxFragmentAtomicCounterBuffers = */ 1, - /* .MaxCombinedAtomicCounterBuffers = */ 1, - /* .MaxAtomicCounterBufferSize = */ 16384, - /* .MaxTransformFeedbackBuffers = */ 4, - /* .MaxTransformFeedbackInterleavedComponents = */ 64, - /* .MaxCullDistances = */ 8, - /* .MaxCombinedClipAndCullDistances = */ 8, - /* .MaxSamples = */ 4, - /* .maxMeshOutputVerticesNV = */ 256, - /* .maxMeshOutputPrimitivesNV = */ 512, - /* .maxMeshWorkGroupSizeX_NV = */ 32, - /* .maxMeshWorkGroupSizeY_NV = */ 1, - /* .maxMeshWorkGroupSizeZ_NV = */ 1, - /* .maxTaskWorkGroupSizeX_NV = */ 32, - /* .maxTaskWorkGroupSizeY_NV = */ 1, - /* .maxTaskWorkGroupSizeZ_NV = */ 1, - /* .maxMeshViewCountNV = */ 4, - /* .maxDualSourceDrawBuffersEXT = */ 1, - - /* .limits = */ { - /* .nonInductiveForLoops = */ 1, - /* .whileLoops = */ 1, - /* .doWhileLoops = */ 1, - /* .generalUniformIndexing = */ 1, - /* .generalAttributeMatrixVectorIndexing = */ 1, - /* .generalVaryingIndexing = */ 1, - /* .generalSamplerIndexing = */ 1, - /* .generalVariableIndexing = */ 1, - /* .generalConstantMatrixVectorIndexing = */ 1, - }}; - -std::string GetDefaultTBuiltInResourceString() -{ - std::ostringstream ostream; - - ostream << "MaxLights " << DefaultTBuiltInResource.maxLights << "\n" - << "MaxClipPlanes " << DefaultTBuiltInResource.maxClipPlanes << "\n" - << "MaxTextureUnits " << DefaultTBuiltInResource.maxTextureUnits << "\n" - << "MaxTextureCoords " << DefaultTBuiltInResource.maxTextureCoords << "\n" - << "MaxVertexAttribs " << DefaultTBuiltInResource.maxVertexAttribs << "\n" - << "MaxVertexUniformComponents " << DefaultTBuiltInResource.maxVertexUniformComponents << "\n" - << "MaxVaryingFloats " << DefaultTBuiltInResource.maxVaryingFloats << "\n" - << "MaxVertexTextureImageUnits " << DefaultTBuiltInResource.maxVertexTextureImageUnits << "\n" - << "MaxCombinedTextureImageUnits " << DefaultTBuiltInResource.maxCombinedTextureImageUnits << "\n" - << "MaxTextureImageUnits " << DefaultTBuiltInResource.maxTextureImageUnits << "\n" - << "MaxFragmentUniformComponents " << DefaultTBuiltInResource.maxFragmentUniformComponents << "\n" - << "MaxDrawBuffers " << DefaultTBuiltInResource.maxDrawBuffers << "\n" - << "MaxVertexUniformVectors " << DefaultTBuiltInResource.maxVertexUniformVectors << "\n" - << "MaxVaryingVectors " << DefaultTBuiltInResource.maxVaryingVectors << "\n" - << "MaxFragmentUniformVectors " << DefaultTBuiltInResource.maxFragmentUniformVectors << "\n" - << "MaxVertexOutputVectors " << DefaultTBuiltInResource.maxVertexOutputVectors << "\n" - << "MaxFragmentInputVectors " << DefaultTBuiltInResource.maxFragmentInputVectors << "\n" - << "MinProgramTexelOffset " << DefaultTBuiltInResource.minProgramTexelOffset << "\n" - << "MaxProgramTexelOffset " << DefaultTBuiltInResource.maxProgramTexelOffset << "\n" - << "MaxClipDistances " << DefaultTBuiltInResource.maxClipDistances << "\n" - << "MaxComputeWorkGroupCountX " << DefaultTBuiltInResource.maxComputeWorkGroupCountX << "\n" - << "MaxComputeWorkGroupCountY " << DefaultTBuiltInResource.maxComputeWorkGroupCountY << "\n" - << "MaxComputeWorkGroupCountZ " << DefaultTBuiltInResource.maxComputeWorkGroupCountZ << "\n" - << "MaxComputeWorkGroupSizeX " << DefaultTBuiltInResource.maxComputeWorkGroupSizeX << "\n" - << "MaxComputeWorkGroupSizeY " << DefaultTBuiltInResource.maxComputeWorkGroupSizeY << "\n" - << "MaxComputeWorkGroupSizeZ " << DefaultTBuiltInResource.maxComputeWorkGroupSizeZ << "\n" - << "MaxComputeUniformComponents " << DefaultTBuiltInResource.maxComputeUniformComponents << "\n" - << "MaxComputeTextureImageUnits " << DefaultTBuiltInResource.maxComputeTextureImageUnits << "\n" - << "MaxComputeImageUniforms " << DefaultTBuiltInResource.maxComputeImageUniforms << "\n" - << "MaxComputeAtomicCounters " << DefaultTBuiltInResource.maxComputeAtomicCounters << "\n" - << "MaxComputeAtomicCounterBuffers " << DefaultTBuiltInResource.maxComputeAtomicCounterBuffers << "\n" - << "MaxVaryingComponents " << DefaultTBuiltInResource.maxVaryingComponents << "\n" - << "MaxVertexOutputComponents " << DefaultTBuiltInResource.maxVertexOutputComponents << "\n" - << "MaxGeometryInputComponents " << DefaultTBuiltInResource.maxGeometryInputComponents << "\n" - << "MaxGeometryOutputComponents " << DefaultTBuiltInResource.maxGeometryOutputComponents << "\n" - << "MaxFragmentInputComponents " << DefaultTBuiltInResource.maxFragmentInputComponents << "\n" - << "MaxImageUnits " << DefaultTBuiltInResource.maxImageUnits << "\n" - << "MaxCombinedImageUnitsAndFragmentOutputs " << DefaultTBuiltInResource.maxCombinedImageUnitsAndFragmentOutputs << "\n" - << "MaxCombinedShaderOutputResources " << DefaultTBuiltInResource.maxCombinedShaderOutputResources << "\n" - << "MaxImageSamples " << DefaultTBuiltInResource.maxImageSamples << "\n" - << "MaxVertexImageUniforms " << DefaultTBuiltInResource.maxVertexImageUniforms << "\n" - << "MaxTessControlImageUniforms " << DefaultTBuiltInResource.maxTessControlImageUniforms << "\n" - << "MaxTessEvaluationImageUniforms " << DefaultTBuiltInResource.maxTessEvaluationImageUniforms << "\n" - << "MaxGeometryImageUniforms " << DefaultTBuiltInResource.maxGeometryImageUniforms << "\n" - << "MaxFragmentImageUniforms " << DefaultTBuiltInResource.maxFragmentImageUniforms << "\n" - << "MaxCombinedImageUniforms " << DefaultTBuiltInResource.maxCombinedImageUniforms << "\n" - << "MaxGeometryTextureImageUnits " << DefaultTBuiltInResource.maxGeometryTextureImageUnits << "\n" - << "MaxGeometryOutputVertices " << DefaultTBuiltInResource.maxGeometryOutputVertices << "\n" - << "MaxGeometryTotalOutputComponents " << DefaultTBuiltInResource.maxGeometryTotalOutputComponents << "\n" - << "MaxGeometryUniformComponents " << DefaultTBuiltInResource.maxGeometryUniformComponents << "\n" - << "MaxGeometryVaryingComponents " << DefaultTBuiltInResource.maxGeometryVaryingComponents << "\n" - << "MaxTessControlInputComponents " << DefaultTBuiltInResource.maxTessControlInputComponents << "\n" - << "MaxTessControlOutputComponents " << DefaultTBuiltInResource.maxTessControlOutputComponents << "\n" - << "MaxTessControlTextureImageUnits " << DefaultTBuiltInResource.maxTessControlTextureImageUnits << "\n" - << "MaxTessControlUniformComponents " << DefaultTBuiltInResource.maxTessControlUniformComponents << "\n" - << "MaxTessControlTotalOutputComponents " << DefaultTBuiltInResource.maxTessControlTotalOutputComponents << "\n" - << "MaxTessEvaluationInputComponents " << DefaultTBuiltInResource.maxTessEvaluationInputComponents << "\n" - << "MaxTessEvaluationOutputComponents " << DefaultTBuiltInResource.maxTessEvaluationOutputComponents << "\n" - << "MaxTessEvaluationTextureImageUnits " << DefaultTBuiltInResource.maxTessEvaluationTextureImageUnits << "\n" - << "MaxTessEvaluationUniformComponents " << DefaultTBuiltInResource.maxTessEvaluationUniformComponents << "\n" - << "MaxTessPatchComponents " << DefaultTBuiltInResource.maxTessPatchComponents << "\n" - << "MaxPatchVertices " << DefaultTBuiltInResource.maxPatchVertices << "\n" - << "MaxTessGenLevel " << DefaultTBuiltInResource.maxTessGenLevel << "\n" - << "MaxViewports " << DefaultTBuiltInResource.maxViewports << "\n" - << "MaxVertexAtomicCounters " << DefaultTBuiltInResource.maxVertexAtomicCounters << "\n" - << "MaxTessControlAtomicCounters " << DefaultTBuiltInResource.maxTessControlAtomicCounters << "\n" - << "MaxTessEvaluationAtomicCounters " << DefaultTBuiltInResource.maxTessEvaluationAtomicCounters << "\n" - << "MaxGeometryAtomicCounters " << DefaultTBuiltInResource.maxGeometryAtomicCounters << "\n" - << "MaxFragmentAtomicCounters " << DefaultTBuiltInResource.maxFragmentAtomicCounters << "\n" - << "MaxCombinedAtomicCounters " << DefaultTBuiltInResource.maxCombinedAtomicCounters << "\n" - << "MaxAtomicCounterBindings " << DefaultTBuiltInResource.maxAtomicCounterBindings << "\n" - << "MaxVertexAtomicCounterBuffers " << DefaultTBuiltInResource.maxVertexAtomicCounterBuffers << "\n" - << "MaxTessControlAtomicCounterBuffers " << DefaultTBuiltInResource.maxTessControlAtomicCounterBuffers << "\n" - << "MaxTessEvaluationAtomicCounterBuffers " << DefaultTBuiltInResource.maxTessEvaluationAtomicCounterBuffers << "\n" - << "MaxGeometryAtomicCounterBuffers " << DefaultTBuiltInResource.maxGeometryAtomicCounterBuffers << "\n" - << "MaxFragmentAtomicCounterBuffers " << DefaultTBuiltInResource.maxFragmentAtomicCounterBuffers << "\n" - << "MaxCombinedAtomicCounterBuffers " << DefaultTBuiltInResource.maxCombinedAtomicCounterBuffers << "\n" - << "MaxAtomicCounterBufferSize " << DefaultTBuiltInResource.maxAtomicCounterBufferSize << "\n" - << "MaxTransformFeedbackBuffers " << DefaultTBuiltInResource.maxTransformFeedbackBuffers << "\n" - << "MaxTransformFeedbackInterleavedComponents " << DefaultTBuiltInResource.maxTransformFeedbackInterleavedComponents << "\n" - << "MaxCullDistances " << DefaultTBuiltInResource.maxCullDistances << "\n" - << "MaxCombinedClipAndCullDistances " << DefaultTBuiltInResource.maxCombinedClipAndCullDistances << "\n" - << "MaxSamples " << DefaultTBuiltInResource.maxSamples << "\n" - << "MaxMeshOutputVerticesNV " << DefaultTBuiltInResource.maxMeshOutputVerticesNV << "\n" - << "MaxMeshOutputPrimitivesNV " << DefaultTBuiltInResource.maxMeshOutputPrimitivesNV << "\n" - << "MaxMeshWorkGroupSizeX_NV " << DefaultTBuiltInResource.maxMeshWorkGroupSizeX_NV << "\n" - << "MaxMeshWorkGroupSizeY_NV " << DefaultTBuiltInResource.maxMeshWorkGroupSizeY_NV << "\n" - << "MaxMeshWorkGroupSizeZ_NV " << DefaultTBuiltInResource.maxMeshWorkGroupSizeZ_NV << "\n" - << "MaxTaskWorkGroupSizeX_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeX_NV << "\n" - << "MaxTaskWorkGroupSizeY_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeY_NV << "\n" - << "MaxTaskWorkGroupSizeZ_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeZ_NV << "\n" - << "MaxMeshViewCountNV " << DefaultTBuiltInResource.maxMeshViewCountNV << "\n" - << "MaxDualSourceDrawBuffersEXT " << DefaultTBuiltInResource.maxDualSourceDrawBuffersEXT << "\n" - << "nonInductiveForLoops " << DefaultTBuiltInResource.limits.nonInductiveForLoops << "\n" - << "whileLoops " << DefaultTBuiltInResource.limits.whileLoops << "\n" - << "doWhileLoops " << DefaultTBuiltInResource.limits.doWhileLoops << "\n" - << "generalUniformIndexing " << DefaultTBuiltInResource.limits.generalUniformIndexing << "\n" - << "generalAttributeMatrixVectorIndexing " << DefaultTBuiltInResource.limits.generalAttributeMatrixVectorIndexing << "\n" - << "generalVaryingIndexing " << DefaultTBuiltInResource.limits.generalVaryingIndexing << "\n" - << "generalSamplerIndexing " << DefaultTBuiltInResource.limits.generalSamplerIndexing << "\n" - << "generalVariableIndexing " << DefaultTBuiltInResource.limits.generalVariableIndexing << "\n" - << "generalConstantMatrixVectorIndexing " << DefaultTBuiltInResource.limits.generalConstantMatrixVectorIndexing << "\n" - ; - - return ostream.str(); -} - -void DecodeResourceLimits(TBuiltInResource* resources, char* config) -{ - static const char* delims = " \t\n\r"; - - size_t pos = 0; - std::string configStr(config); - - while ((pos = configStr.find_first_not_of(delims, pos)) != std::string::npos) { - const size_t token_s = pos; - const size_t token_e = configStr.find_first_of(delims, token_s); - const size_t value_s = configStr.find_first_not_of(delims, token_e); - const size_t value_e = configStr.find_first_of(delims, value_s); - pos = value_e; - - // Faster to use compare(), but prefering readability. - const std::string tokenStr = configStr.substr(token_s, token_e-token_s); - const std::string valueStr = configStr.substr(value_s, value_e-value_s); - - if (value_s == std::string::npos || ! (valueStr[0] == '-' || isdigit(valueStr[0]))) { - printf("Error: '%s' bad .conf file. Each name must be followed by one number.\n", - valueStr.c_str()); - return; - } - - const int value = std::atoi(valueStr.c_str()); - - if (tokenStr == "MaxLights") - resources->maxLights = value; - else if (tokenStr == "MaxClipPlanes") - resources->maxClipPlanes = value; - else if (tokenStr == "MaxTextureUnits") - resources->maxTextureUnits = value; - else if (tokenStr == "MaxTextureCoords") - resources->maxTextureCoords = value; - else if (tokenStr == "MaxVertexAttribs") - resources->maxVertexAttribs = value; - else if (tokenStr == "MaxVertexUniformComponents") - resources->maxVertexUniformComponents = value; - else if (tokenStr == "MaxVaryingFloats") - resources->maxVaryingFloats = value; - else if (tokenStr == "MaxVertexTextureImageUnits") - resources->maxVertexTextureImageUnits = value; - else if (tokenStr == "MaxCombinedTextureImageUnits") - resources->maxCombinedTextureImageUnits = value; - else if (tokenStr == "MaxTextureImageUnits") - resources->maxTextureImageUnits = value; - else if (tokenStr == "MaxFragmentUniformComponents") - resources->maxFragmentUniformComponents = value; - else if (tokenStr == "MaxDrawBuffers") - resources->maxDrawBuffers = value; - else if (tokenStr == "MaxVertexUniformVectors") - resources->maxVertexUniformVectors = value; - else if (tokenStr == "MaxVaryingVectors") - resources->maxVaryingVectors = value; - else if (tokenStr == "MaxFragmentUniformVectors") - resources->maxFragmentUniformVectors = value; - else if (tokenStr == "MaxVertexOutputVectors") - resources->maxVertexOutputVectors = value; - else if (tokenStr == "MaxFragmentInputVectors") - resources->maxFragmentInputVectors = value; - else if (tokenStr == "MinProgramTexelOffset") - resources->minProgramTexelOffset = value; - else if (tokenStr == "MaxProgramTexelOffset") - resources->maxProgramTexelOffset = value; - else if (tokenStr == "MaxClipDistances") - resources->maxClipDistances = value; - else if (tokenStr == "MaxComputeWorkGroupCountX") - resources->maxComputeWorkGroupCountX = value; - else if (tokenStr == "MaxComputeWorkGroupCountY") - resources->maxComputeWorkGroupCountY = value; - else if (tokenStr == "MaxComputeWorkGroupCountZ") - resources->maxComputeWorkGroupCountZ = value; - else if (tokenStr == "MaxComputeWorkGroupSizeX") - resources->maxComputeWorkGroupSizeX = value; - else if (tokenStr == "MaxComputeWorkGroupSizeY") - resources->maxComputeWorkGroupSizeY = value; - else if (tokenStr == "MaxComputeWorkGroupSizeZ") - resources->maxComputeWorkGroupSizeZ = value; - else if (tokenStr == "MaxComputeUniformComponents") - resources->maxComputeUniformComponents = value; - else if (tokenStr == "MaxComputeTextureImageUnits") - resources->maxComputeTextureImageUnits = value; - else if (tokenStr == "MaxComputeImageUniforms") - resources->maxComputeImageUniforms = value; - else if (tokenStr == "MaxComputeAtomicCounters") - resources->maxComputeAtomicCounters = value; - else if (tokenStr == "MaxComputeAtomicCounterBuffers") - resources->maxComputeAtomicCounterBuffers = value; - else if (tokenStr == "MaxVaryingComponents") - resources->maxVaryingComponents = value; - else if (tokenStr == "MaxVertexOutputComponents") - resources->maxVertexOutputComponents = value; - else if (tokenStr == "MaxGeometryInputComponents") - resources->maxGeometryInputComponents = value; - else if (tokenStr == "MaxGeometryOutputComponents") - resources->maxGeometryOutputComponents = value; - else if (tokenStr == "MaxFragmentInputComponents") - resources->maxFragmentInputComponents = value; - else if (tokenStr == "MaxImageUnits") - resources->maxImageUnits = value; - else if (tokenStr == "MaxCombinedImageUnitsAndFragmentOutputs") - resources->maxCombinedImageUnitsAndFragmentOutputs = value; - else if (tokenStr == "MaxCombinedShaderOutputResources") - resources->maxCombinedShaderOutputResources = value; - else if (tokenStr == "MaxImageSamples") - resources->maxImageSamples = value; - else if (tokenStr == "MaxVertexImageUniforms") - resources->maxVertexImageUniforms = value; - else if (tokenStr == "MaxTessControlImageUniforms") - resources->maxTessControlImageUniforms = value; - else if (tokenStr == "MaxTessEvaluationImageUniforms") - resources->maxTessEvaluationImageUniforms = value; - else if (tokenStr == "MaxGeometryImageUniforms") - resources->maxGeometryImageUniforms = value; - else if (tokenStr == "MaxFragmentImageUniforms") - resources->maxFragmentImageUniforms = value; - else if (tokenStr == "MaxCombinedImageUniforms") - resources->maxCombinedImageUniforms = value; - else if (tokenStr == "MaxGeometryTextureImageUnits") - resources->maxGeometryTextureImageUnits = value; - else if (tokenStr == "MaxGeometryOutputVertices") - resources->maxGeometryOutputVertices = value; - else if (tokenStr == "MaxGeometryTotalOutputComponents") - resources->maxGeometryTotalOutputComponents = value; - else if (tokenStr == "MaxGeometryUniformComponents") - resources->maxGeometryUniformComponents = value; - else if (tokenStr == "MaxGeometryVaryingComponents") - resources->maxGeometryVaryingComponents = value; - else if (tokenStr == "MaxTessControlInputComponents") - resources->maxTessControlInputComponents = value; - else if (tokenStr == "MaxTessControlOutputComponents") - resources->maxTessControlOutputComponents = value; - else if (tokenStr == "MaxTessControlTextureImageUnits") - resources->maxTessControlTextureImageUnits = value; - else if (tokenStr == "MaxTessControlUniformComponents") - resources->maxTessControlUniformComponents = value; - else if (tokenStr == "MaxTessControlTotalOutputComponents") - resources->maxTessControlTotalOutputComponents = value; - else if (tokenStr == "MaxTessEvaluationInputComponents") - resources->maxTessEvaluationInputComponents = value; - else if (tokenStr == "MaxTessEvaluationOutputComponents") - resources->maxTessEvaluationOutputComponents = value; - else if (tokenStr == "MaxTessEvaluationTextureImageUnits") - resources->maxTessEvaluationTextureImageUnits = value; - else if (tokenStr == "MaxTessEvaluationUniformComponents") - resources->maxTessEvaluationUniformComponents = value; - else if (tokenStr == "MaxTessPatchComponents") - resources->maxTessPatchComponents = value; - else if (tokenStr == "MaxPatchVertices") - resources->maxPatchVertices = value; - else if (tokenStr == "MaxTessGenLevel") - resources->maxTessGenLevel = value; - else if (tokenStr == "MaxViewports") - resources->maxViewports = value; - else if (tokenStr == "MaxVertexAtomicCounters") - resources->maxVertexAtomicCounters = value; - else if (tokenStr == "MaxTessControlAtomicCounters") - resources->maxTessControlAtomicCounters = value; - else if (tokenStr == "MaxTessEvaluationAtomicCounters") - resources->maxTessEvaluationAtomicCounters = value; - else if (tokenStr == "MaxGeometryAtomicCounters") - resources->maxGeometryAtomicCounters = value; - else if (tokenStr == "MaxFragmentAtomicCounters") - resources->maxFragmentAtomicCounters = value; - else if (tokenStr == "MaxCombinedAtomicCounters") - resources->maxCombinedAtomicCounters = value; - else if (tokenStr == "MaxAtomicCounterBindings") - resources->maxAtomicCounterBindings = value; - else if (tokenStr == "MaxVertexAtomicCounterBuffers") - resources->maxVertexAtomicCounterBuffers = value; - else if (tokenStr == "MaxTessControlAtomicCounterBuffers") - resources->maxTessControlAtomicCounterBuffers = value; - else if (tokenStr == "MaxTessEvaluationAtomicCounterBuffers") - resources->maxTessEvaluationAtomicCounterBuffers = value; - else if (tokenStr == "MaxGeometryAtomicCounterBuffers") - resources->maxGeometryAtomicCounterBuffers = value; - else if (tokenStr == "MaxFragmentAtomicCounterBuffers") - resources->maxFragmentAtomicCounterBuffers = value; - else if (tokenStr == "MaxCombinedAtomicCounterBuffers") - resources->maxCombinedAtomicCounterBuffers = value; - else if (tokenStr == "MaxAtomicCounterBufferSize") - resources->maxAtomicCounterBufferSize = value; - else if (tokenStr == "MaxTransformFeedbackBuffers") - resources->maxTransformFeedbackBuffers = value; - else if (tokenStr == "MaxTransformFeedbackInterleavedComponents") - resources->maxTransformFeedbackInterleavedComponents = value; - else if (tokenStr == "MaxCullDistances") - resources->maxCullDistances = value; - else if (tokenStr == "MaxCombinedClipAndCullDistances") - resources->maxCombinedClipAndCullDistances = value; - else if (tokenStr == "MaxSamples") - resources->maxSamples = value; - else if (tokenStr == "MaxMeshOutputVerticesNV") - resources->maxMeshOutputVerticesNV = value; - else if (tokenStr == "MaxMeshOutputPrimitivesNV") - resources->maxMeshOutputPrimitivesNV = value; - else if (tokenStr == "MaxMeshWorkGroupSizeX_NV") - resources->maxMeshWorkGroupSizeX_NV = value; - else if (tokenStr == "MaxMeshWorkGroupSizeY_NV") - resources->maxMeshWorkGroupSizeY_NV = value; - else if (tokenStr == "MaxMeshWorkGroupSizeZ_NV") - resources->maxMeshWorkGroupSizeZ_NV = value; - else if (tokenStr == "MaxTaskWorkGroupSizeX_NV") - resources->maxTaskWorkGroupSizeX_NV = value; - else if (tokenStr == "MaxTaskWorkGroupSizeY_NV") - resources->maxTaskWorkGroupSizeY_NV = value; - else if (tokenStr == "MaxTaskWorkGroupSizeZ_NV") - resources->maxTaskWorkGroupSizeZ_NV = value; - else if (tokenStr == "MaxMeshViewCountNV") - resources->maxMeshViewCountNV = value; - else if (tokenStr == "nonInductiveForLoops") - resources->limits.nonInductiveForLoops = (value != 0); - else if (tokenStr == "whileLoops") - resources->limits.whileLoops = (value != 0); - else if (tokenStr == "doWhileLoops") - resources->limits.doWhileLoops = (value != 0); - else if (tokenStr == "generalUniformIndexing") - resources->limits.generalUniformIndexing = (value != 0); - else if (tokenStr == "generalAttributeMatrixVectorIndexing") - resources->limits.generalAttributeMatrixVectorIndexing = (value != 0); - else if (tokenStr == "generalVaryingIndexing") - resources->limits.generalVaryingIndexing = (value != 0); - else if (tokenStr == "generalSamplerIndexing") - resources->limits.generalSamplerIndexing = (value != 0); - else if (tokenStr == "generalVariableIndexing") - resources->limits.generalVariableIndexing = (value != 0); - else if (tokenStr == "generalConstantMatrixVectorIndexing") - resources->limits.generalConstantMatrixVectorIndexing = (value != 0); - else - printf("Warning: unrecognized limit (%s) in configuration file.\n", tokenStr.c_str()); - - } -} - -} // end namespace glslang diff --git a/thirdparty/glslang/StandAlone/ResourceLimits.h b/thirdparty/glslang/StandAlone/ResourceLimits.h deleted file mode 100644 index 736248eb39..0000000000 --- a/thirdparty/glslang/StandAlone/ResourceLimits.h +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright (C) 2016 Google, Inc. -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// -// Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_ -#define _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_ - -#include <string> - -#include "../glslang/Include/ResourceLimits.h" - -namespace glslang { - -// These are the default resources for TBuiltInResources, used for both -// - parsing this string for the case where the user didn't supply one, -// - dumping out a template for user construction of a config file. -extern const TBuiltInResource DefaultTBuiltInResource; - -// Returns the DefaultTBuiltInResource as a human-readable string. -std::string GetDefaultTBuiltInResourceString(); - -// Decodes the resource limits from |config| to |resources|. -void DecodeResourceLimits(TBuiltInResource* resources, char* config); - -} // end namespace glslang - -#endif // _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_ diff --git a/thirdparty/glslang/glslang/CInterface/glslang_c_interface.cpp b/thirdparty/glslang/glslang/CInterface/glslang_c_interface.cpp deleted file mode 100644 index 2e04f53ace..0000000000 --- a/thirdparty/glslang/glslang/CInterface/glslang_c_interface.cpp +++ /dev/null @@ -1,428 +0,0 @@ -/** - This code is based on the glslang_c_interface implementation by Viktor Latypov -**/ - -/** -BSD 2-Clause License - -Copyright (c) 2019, Viktor Latypov -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**/ - -#include "glslang/Include/glslang_c_interface.h" - -#include "StandAlone/DirStackFileIncluder.h" -#include "StandAlone/ResourceLimits.h" -#include "glslang/Include/ShHandle.h" - -#include "glslang/Include/ResourceLimits.h" -#include "glslang/MachineIndependent/Versions.h" - -static_assert(int(GLSLANG_STAGE_COUNT) == EShLangCount, ""); -static_assert(int(GLSLANG_STAGE_MASK_COUNT) == EShLanguageMaskCount, ""); -static_assert(int(GLSLANG_SOURCE_COUNT) == glslang::EShSourceCount, ""); -static_assert(int(GLSLANG_CLIENT_COUNT) == glslang::EShClientCount, ""); -static_assert(int(GLSLANG_TARGET_COUNT) == glslang::EShTargetCount, ""); -static_assert(int(GLSLANG_TARGET_CLIENT_VERSION_COUNT) == glslang::EShTargetClientVersionCount, ""); -static_assert(int(GLSLANG_TARGET_LANGUAGE_VERSION_COUNT) == glslang::EShTargetLanguageVersionCount, ""); -static_assert(int(GLSLANG_OPT_LEVEL_COUNT) == EshOptLevelCount, ""); -static_assert(int(GLSLANG_TEX_SAMP_TRANS_COUNT) == EShTexSampTransCount, ""); -static_assert(int(GLSLANG_MSG_COUNT) == EShMsgCount, ""); -static_assert(int(GLSLANG_REFLECTION_COUNT) == EShReflectionCount, ""); -static_assert(int(GLSLANG_PROFILE_COUNT) == EProfileCount, ""); -static_assert(sizeof(glslang_limits_t) == sizeof(TLimits), ""); -static_assert(sizeof(glslang_resource_t) == sizeof(TBuiltInResource), ""); - -typedef struct glslang_shader_s { - glslang::TShader* shader; - std::string preprocessedGLSL; -} glslang_shader_t; - -typedef struct glslang_program_s { - glslang::TProgram* program; - std::vector<unsigned int> spirv; - std::string loggerMessages; -} glslang_program_t; - -/* Wrapper/Adapter for C glsl_include_callbacks_t functions - - This class contains a 'glsl_include_callbacks_t' structure - with C include_local/include_system callback pointers. - - This class implement TShader::Includer interface - by redirecting C++ virtual methods to C callbacks. - - The 'IncludeResult' instances produced by this Includer - contain a reference to glsl_include_result_t C structure - to allow its lifetime management by another C callback - (CallbackIncluder::callbacks::free_include_result) -*/ -class CallbackIncluder : public glslang::TShader::Includer { -public: - /* Wrapper of IncludeResult which stores a glsl_include_result object internally */ - class CallbackIncludeResult : public glslang::TShader::Includer::IncludeResult { - public: - CallbackIncludeResult(const std::string& headerName, const char* const headerData, const size_t headerLength, - void* userData, glsl_include_result_t* includeResult) - : glslang::TShader::Includer::IncludeResult(headerName, headerData, headerLength, userData), - includeResult(includeResult) - { - } - - virtual ~CallbackIncludeResult() {} - - protected: - friend class CallbackIncluder; - - glsl_include_result_t* includeResult; - }; - -public: - CallbackIncluder(glsl_include_callbacks_t _callbacks, void* _context) : callbacks(_callbacks), context(_context) {} - - virtual ~CallbackIncluder() {} - - virtual IncludeResult* includeSystem(const char* headerName, const char* includerName, - size_t inclusionDepth) override - { - if (this->callbacks.include_system) { - glsl_include_result_t* result = - this->callbacks.include_system(this->context, headerName, includerName, inclusionDepth); - - return new CallbackIncludeResult(std::string(headerName), result->header_data, result->header_length, - nullptr, result); - } - - return glslang::TShader::Includer::includeSystem(headerName, includerName, inclusionDepth); - } - - virtual IncludeResult* includeLocal(const char* headerName, const char* includerName, - size_t inclusionDepth) override - { - if (this->callbacks.include_local) { - glsl_include_result_t* result = - this->callbacks.include_local(this->context, headerName, includerName, inclusionDepth); - - return new CallbackIncludeResult(std::string(headerName), result->header_data, result->header_length, - nullptr, result); - } - - return glslang::TShader::Includer::includeLocal(headerName, includerName, inclusionDepth); - } - - /* This function only calls free_include_result callback - when the IncludeResult instance is allocated by a C function */ - virtual void releaseInclude(IncludeResult* result) override - { - if (result == nullptr) - return; - - if (this->callbacks.free_include_result && (result->userData == nullptr)) { - CallbackIncludeResult* innerResult = static_cast<CallbackIncludeResult*>(result); - /* use internal free() function */ - this->callbacks.free_include_result(this->context, innerResult->includeResult); - /* ignore internal fields of TShader::Includer::IncludeResult */ - delete result; - return; - } - - delete[] static_cast<char*>(result->userData); - delete result; - } - -private: - CallbackIncluder() {} - - /* C callback pointers */ - glsl_include_callbacks_t callbacks; - /* User-defined context */ - void* context; -}; - -GLSLANG_EXPORT int glslang_initialize_process() { return static_cast<int>(glslang::InitializeProcess()); } - -GLSLANG_EXPORT void glslang_finalize_process() { glslang::FinalizeProcess(); } - -static EShLanguage c_shader_stage(glslang_stage_t stage) -{ - switch (stage) { - case GLSLANG_STAGE_VERTEX: - return EShLangVertex; - case GLSLANG_STAGE_TESSCONTROL: - return EShLangTessControl; - case GLSLANG_STAGE_TESSEVALUATION: - return EShLangTessEvaluation; - case GLSLANG_STAGE_GEOMETRY: - return EShLangGeometry; - case GLSLANG_STAGE_FRAGMENT: - return EShLangFragment; - case GLSLANG_STAGE_COMPUTE: - return EShLangCompute; - case GLSLANG_STAGE_RAYGEN_NV: - return EShLangRayGen; - case GLSLANG_STAGE_INTERSECT_NV: - return EShLangIntersect; - case GLSLANG_STAGE_ANYHIT_NV: - return EShLangAnyHit; - case GLSLANG_STAGE_CLOSESTHIT_NV: - return EShLangClosestHit; - case GLSLANG_STAGE_MISS_NV: - return EShLangMiss; - case GLSLANG_STAGE_CALLABLE_NV: - return EShLangCallable; - case GLSLANG_STAGE_TASK_NV: - return EShLangTaskNV; - case GLSLANG_STAGE_MESH_NV: - return EShLangMeshNV; - default: - break; - } - return EShLangCount; -} - -static int c_shader_messages(glslang_messages_t messages) -{ -#define CONVERT_MSG(in, out) \ - if ((messages & in) == in) \ - res |= out; - - int res = 0; - - CONVERT_MSG(GLSLANG_MSG_RELAXED_ERRORS_BIT, EShMsgRelaxedErrors); - CONVERT_MSG(GLSLANG_MSG_SUPPRESS_WARNINGS_BIT, EShMsgSuppressWarnings); - CONVERT_MSG(GLSLANG_MSG_AST_BIT, EShMsgAST); - CONVERT_MSG(GLSLANG_MSG_SPV_RULES_BIT, EShMsgSpvRules); - CONVERT_MSG(GLSLANG_MSG_VULKAN_RULES_BIT, EShMsgVulkanRules); - CONVERT_MSG(GLSLANG_MSG_ONLY_PREPROCESSOR_BIT, EShMsgOnlyPreprocessor); - CONVERT_MSG(GLSLANG_MSG_READ_HLSL_BIT, EShMsgReadHlsl); - CONVERT_MSG(GLSLANG_MSG_CASCADING_ERRORS_BIT, EShMsgCascadingErrors); - CONVERT_MSG(GLSLANG_MSG_KEEP_UNCALLED_BIT, EShMsgKeepUncalled); - CONVERT_MSG(GLSLANG_MSG_HLSL_OFFSETS_BIT, EShMsgHlslOffsets); - CONVERT_MSG(GLSLANG_MSG_DEBUG_INFO_BIT, EShMsgDebugInfo); - CONVERT_MSG(GLSLANG_MSG_HLSL_ENABLE_16BIT_TYPES_BIT, EShMsgHlslEnable16BitTypes); - CONVERT_MSG(GLSLANG_MSG_HLSL_LEGALIZATION_BIT, EShMsgHlslLegalization); - CONVERT_MSG(GLSLANG_MSG_HLSL_DX9_COMPATIBLE_BIT, EShMsgHlslDX9Compatible); - CONVERT_MSG(GLSLANG_MSG_BUILTIN_SYMBOL_TABLE_BIT, EShMsgBuiltinSymbolTable); - return res; -#undef CONVERT_MSG -} - -static glslang::EShTargetLanguageVersion -c_shader_target_language_version(glslang_target_language_version_t target_language_version) -{ - switch (target_language_version) { - case GLSLANG_TARGET_SPV_1_0: - return glslang::EShTargetSpv_1_0; - case GLSLANG_TARGET_SPV_1_1: - return glslang::EShTargetSpv_1_1; - case GLSLANG_TARGET_SPV_1_2: - return glslang::EShTargetSpv_1_2; - case GLSLANG_TARGET_SPV_1_3: - return glslang::EShTargetSpv_1_3; - case GLSLANG_TARGET_SPV_1_4: - return glslang::EShTargetSpv_1_4; - case GLSLANG_TARGET_SPV_1_5: - return glslang::EShTargetSpv_1_5; - default: - break; - } - return glslang::EShTargetSpv_1_0; -} - -static glslang::EShClient c_shader_client(glslang_client_t client) -{ - switch (client) { - case GLSLANG_CLIENT_VULKAN: - return glslang::EShClientVulkan; - case GLSLANG_CLIENT_OPENGL: - return glslang::EShClientOpenGL; - default: - break; - } - - return glslang::EShClientNone; -} - -static glslang::EShTargetClientVersion c_shader_client_version(glslang_target_client_version_t client_version) -{ - switch (client_version) { - case GLSLANG_TARGET_VULKAN_1_1: - return glslang::EShTargetVulkan_1_1; - case GLSLANG_TARGET_OPENGL_450: - return glslang::EShTargetOpenGL_450; - default: - break; - } - - return glslang::EShTargetVulkan_1_0; -} - -static glslang::EShTargetLanguage c_shader_target_language(glslang_target_language_t target_language) -{ - if (target_language == GLSLANG_TARGET_NONE) - return glslang::EShTargetNone; - - return glslang::EShTargetSpv; -} - -static glslang::EShSource c_shader_source(glslang_source_t source) -{ - switch (source) { - case GLSLANG_SOURCE_GLSL: - return glslang::EShSourceGlsl; - case GLSLANG_SOURCE_HLSL: - return glslang::EShSourceHlsl; - default: - break; - } - - return glslang::EShSourceNone; -} - -static EProfile c_shader_profile(glslang_profile_t profile) -{ - switch (profile) { - case GLSLANG_BAD_PROFILE: - return EBadProfile; - case GLSLANG_NO_PROFILE: - return ENoProfile; - case GLSLANG_CORE_PROFILE: - return ECoreProfile; - case GLSLANG_COMPATIBILITY_PROFILE: - return ECompatibilityProfile; - case GLSLANG_ES_PROFILE: - return EEsProfile; - case GLSLANG_PROFILE_COUNT: // Should not use this - break; - } - - return EProfile(); -} - -GLSLANG_EXPORT glslang_shader_t* glslang_shader_create(const glslang_input_t* input) -{ - if (!input || !input->code) { - printf("Error creating shader: null input(%p)/input->code\n", input); - - if (input) - printf("input->code = %p\n", input->code); - - return nullptr; - } - - glslang_shader_t* shader = new glslang_shader_t(); - - shader->shader = new glslang::TShader(c_shader_stage(input->stage)); - shader->shader->setStrings(&input->code, 1); - shader->shader->setEnvInput(c_shader_source(input->language), c_shader_stage(input->stage), - c_shader_client(input->client), input->default_version); - shader->shader->setEnvClient(c_shader_client(input->client), c_shader_client_version(input->client_version)); - shader->shader->setEnvTarget(c_shader_target_language(input->target_language), - c_shader_target_language_version(input->target_language_version)); - - return shader; -} - -GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader) -{ - return shader->preprocessedGLSL.c_str(); -} - -GLSLANG_EXPORT int glslang_shader_preprocess(glslang_shader_t* shader, const glslang_input_t* input) -{ - DirStackFileIncluder Includer; - /* TODO: use custom callbacks if they are available in 'i->callbacks' */ - return shader->shader->preprocess( - reinterpret_cast<const TBuiltInResource*>(input->resource), - input->default_version, - c_shader_profile(input->default_profile), - input->force_default_version_and_profile != 0, - input->forward_compatible != 0, - (EShMessages)c_shader_messages(input->messages), - &shader->preprocessedGLSL, - Includer - ); -} - -GLSLANG_EXPORT int glslang_shader_parse(glslang_shader_t* shader, const glslang_input_t* input) -{ - const char* preprocessedCStr = shader->preprocessedGLSL.c_str(); - shader->shader->setStrings(&preprocessedCStr, 1); - - return shader->shader->parse( - reinterpret_cast<const TBuiltInResource*>(input->resource), - input->default_version, - input->forward_compatible != 0, - (EShMessages)c_shader_messages(input->messages) - ); -} - -GLSLANG_EXPORT const char* glslang_shader_get_info_log(glslang_shader_t* shader) { return shader->shader->getInfoLog(); } - -GLSLANG_EXPORT const char* glslang_shader_get_info_debug_log(glslang_shader_t* shader) { return shader->shader->getInfoDebugLog(); } - -GLSLANG_EXPORT void glslang_shader_delete(glslang_shader_t* shader) -{ - if (!shader) - return; - - delete (shader->shader); - delete (shader); -} - -GLSLANG_EXPORT glslang_program_t* glslang_program_create() -{ - glslang_program_t* p = new glslang_program_t(); - p->program = new glslang::TProgram(); - return p; -} - -GLSLANG_EXPORT void glslang_program_delete(glslang_program_t* program) -{ - if (!program) - return; - - delete (program->program); - delete (program); -} - -GLSLANG_EXPORT void glslang_program_add_shader(glslang_program_t* program, glslang_shader_t* shader) -{ - program->program->addShader(shader->shader); -} - -GLSLANG_EXPORT int glslang_program_link(glslang_program_t* program, int messages) -{ - return (int)program->program->link((EShMessages)messages); -} - -GLSLANG_EXPORT const char* glslang_program_get_info_log(glslang_program_t* program) -{ - return program->program->getInfoLog(); -} - -GLSLANG_EXPORT const char* glslang_program_get_info_debug_log(glslang_program_t* program) -{ - return program->program->getInfoDebugLog(); -} diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh index b77c1f4d44..2f99510925 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh @@ -1038,12 +1038,12 @@ struct Chain goto skip; if (reverse) - c->buffer->reverse (); + _hb_ot_layout_reverse_graphemes (c->buffer); subtable->apply (c); if (reverse) - c->buffer->reverse (); + _hb_ot_layout_reverse_graphemes (c->buffer); (void) c->buffer->message (c->font, "end chainsubtable %d", c->lookup_index); diff --git a/thirdparty/harfbuzz/src/hb-buffer.cc b/thirdparty/harfbuzz/src/hb-buffer.cc index b4f7f72374..be3161a54d 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.cc +++ b/thirdparty/harfbuzz/src/hb-buffer.cc @@ -396,52 +396,6 @@ hb_buffer_t::set_masks (hb_mask_t value, } void -hb_buffer_t::reverse_range (unsigned int start, - unsigned int end) -{ - if (end - start < 2) - return; - - hb_array_t<hb_glyph_info_t> (info, len).reverse (start, end); - - if (have_positions) { - hb_array_t<hb_glyph_position_t> (pos, len).reverse (start, end); - } -} - -void -hb_buffer_t::reverse () -{ - if (unlikely (!len)) - return; - - reverse_range (0, len); -} - -void -hb_buffer_t::reverse_clusters () -{ - unsigned int i, start, count, last_cluster; - - if (unlikely (!len)) - return; - - reverse (); - - count = len; - start = 0; - last_cluster = info[0].cluster; - for (i = 1; i < count; i++) { - if (last_cluster != info[i].cluster) { - reverse_range (start, i); - start = i; - last_cluster = info[i].cluster; - } - } - reverse_range (start, i); -} - -void hb_buffer_t::merge_clusters_impl (unsigned int start, unsigned int end) { @@ -543,7 +497,7 @@ void hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end) { unsigned int cluster = UINT_MAX; - cluster = _unsafe_to_break_find_min_cluster (info, start, end, cluster); + cluster = _infos_find_min_cluster (info, start, end, cluster); _unsafe_to_break_set_mask (info, start, end, cluster); } void @@ -559,8 +513,9 @@ hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int en assert (idx <= end); unsigned int cluster = UINT_MAX; - cluster = _unsafe_to_break_find_min_cluster (out_info, start, out_len, cluster); - cluster = _unsafe_to_break_find_min_cluster (info, idx, end, cluster); + cluster = _infos_find_min_cluster (out_info, start, out_len, cluster); + cluster = _infos_find_min_cluster (info, idx, end, cluster); + _unsafe_to_break_set_mask (out_info, start, out_len, cluster); _unsafe_to_break_set_mask (info, idx, end, cluster); } diff --git a/thirdparty/harfbuzz/src/hb-buffer.hh b/thirdparty/harfbuzz/src/hb-buffer.hh index bde28933e4..0f8140f1b3 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.hh +++ b/thirdparty/harfbuzz/src/hb-buffer.hh @@ -201,9 +201,55 @@ struct hb_buffer_t unsigned int cluster); HB_INTERNAL void add_info (const hb_glyph_info_t &glyph_info); - HB_INTERNAL void reverse_range (unsigned int start, unsigned int end); - HB_INTERNAL void reverse (); - HB_INTERNAL void reverse_clusters (); + void reverse_range (unsigned start, unsigned end) + { + hb_array_t<hb_glyph_info_t> (info, len).reverse (start, end); + if (have_positions) + hb_array_t<hb_glyph_position_t> (pos, len).reverse (start, end); + } + void reverse () { reverse_range (0, len); } + + template <typename FuncType> + void reverse_groups (const FuncType& group, + bool merge_clusters = false) + { + if (unlikely (!len)) + return; + + unsigned start = 0; + unsigned i; + for (i = 1; i < len; i++) + { + if (!group (info[i - 1], info[i])) + { + if (merge_clusters) + this->merge_clusters (start, i); + reverse_range (start, i); + start = i; + } + } + if (merge_clusters) + this->merge_clusters (start, i); + reverse_range (start, i); + + reverse (); + } + + template <typename FuncType> + unsigned group_end (unsigned start, const FuncType& group) const + { + while (++start < len && group (info[start - 1], info[start])) + ; + + return start; + } + + static bool _cluster_group_func (const hb_glyph_info_t& a, + const hb_glyph_info_t& b) + { return a.cluster == b.cluster; } + + void reverse_clusters () { reverse_groups (_cluster_group_func); } + HB_INTERNAL void guess_segment_properties (); HB_INTERNAL void swap_buffers (); @@ -428,10 +474,10 @@ struct hb_buffer_t inf.cluster = cluster; } - unsigned int - _unsafe_to_break_find_min_cluster (const hb_glyph_info_t *infos, - unsigned int start, unsigned int end, - unsigned int cluster) const + static unsigned + _infos_find_min_cluster (const hb_glyph_info_t *infos, + unsigned start, unsigned end, + unsigned cluster) { for (unsigned int i = start; i < end; i++) cluster = hb_min (cluster, infos[i].cluster); @@ -450,36 +496,24 @@ struct hb_buffer_t } } - void unsafe_to_break_all () { unsafe_to_break_impl (0, len); } - void safe_to_break_all () + void clear_glyph_flags (hb_mask_t mask = 0) { for (unsigned int i = 0; i < len; i++) - info[i].mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + info[i].mask = (info[i].mask & ~HB_GLYPH_FLAG_DEFINED) | (mask & HB_GLYPH_FLAG_DEFINED); } }; DECLARE_NULL_INSTANCE (hb_buffer_t); -/* Loop over clusters. Duplicated in foreach_syllable(). */ -#define foreach_cluster(buffer, start, end) \ +#define foreach_group(buffer, start, end, group_func) \ for (unsigned int \ _count = buffer->len, \ - start = 0, end = _count ? _next_cluster (buffer, 0) : 0; \ + start = 0, end = _count ? buffer->group_end (0, group_func) : 0; \ start < _count; \ - start = end, end = _next_cluster (buffer, start)) - -static inline unsigned int -_next_cluster (hb_buffer_t *buffer, unsigned int start) -{ - hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; - - unsigned int cluster = info[start].cluster; - while (++start < count && cluster == info[start].cluster) - ; + start = end, end = buffer->group_end (start, group_func)) - return start; -} +#define foreach_cluster(buffer, start, end) \ + foreach_group (buffer, start, end, hb_buffer_t::_cluster_group_func) #define HB_BUFFER_XALLOCATE_VAR(b, func, var) \ diff --git a/thirdparty/harfbuzz/src/hb-config.hh b/thirdparty/harfbuzz/src/hb-config.hh index ad800f0f74..7d00d9088a 100644 --- a/thirdparty/harfbuzz/src/hb-config.hh +++ b/thirdparty/harfbuzz/src/hb-config.hh @@ -86,8 +86,11 @@ #define HB_NO_LEGACY #endif -#ifdef HAVE_CONFIG_OVERRIDE_H -#include "config-override.h" +#if defined(HAVE_CONFIG_OVERRIDE_H) || defined(HB_CONFIG_OVERRIDE_H) +#ifndef HB_CONFIG_OVERRIDE_H +#define HB_CONFIG_OVERRIDE_H "config-override.h" +#endif +#include HB_CONFIG_OVERRIDE_H #endif /* Closure of options. */ diff --git a/thirdparty/harfbuzz/src/hb-coretext.cc b/thirdparty/harfbuzz/src/hb-coretext.cc index 4b6c67c1ee..a512f3b8b7 100644 --- a/thirdparty/harfbuzz/src/hb-coretext.cc +++ b/thirdparty/harfbuzz/src/hb-coretext.cc @@ -1213,7 +1213,7 @@ resize_and_retry: } } - buffer->unsafe_to_break_all (); + buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK); #undef FAIL diff --git a/thirdparty/harfbuzz/src/hb-directwrite.cc b/thirdparty/harfbuzz/src/hb-directwrite.cc index db7b53b259..dea87b8cd0 100644 --- a/thirdparty/harfbuzz/src/hb-directwrite.cc +++ b/thirdparty/harfbuzz/src/hb-directwrite.cc @@ -43,14 +43,6 @@ * Functions for using HarfBuzz with DirectWrite fonts. **/ -/* Declare object creator for dynamic support of DWRITE */ -typedef HRESULT (* WINAPI t_DWriteCreateFactory)( - DWRITE_FACTORY_TYPE factoryType, - REFIID iid, - IUnknown **factory -); - - /* * DirectWrite font stream helpers */ @@ -145,7 +137,6 @@ public: struct hb_directwrite_face_data_t { - HMODULE dwrite_dll; IDWriteFactory *dwriteFactory; IDWriteFontFile *fontFile; DWriteFontFileStream *fontFileStream; @@ -167,33 +158,12 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face) return nullptr; \ } HB_STMT_END - data->dwrite_dll = LoadLibrary (TEXT ("DWRITE")); - if (unlikely (!data->dwrite_dll)) - FAIL ("Cannot find DWrite.DLL"); - - t_DWriteCreateFactory p_DWriteCreateFactory; - -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-function-type" -#endif - - p_DWriteCreateFactory = (t_DWriteCreateFactory) - GetProcAddress (data->dwrite_dll, "DWriteCreateFactory"); - -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - - if (unlikely (!p_DWriteCreateFactory)) - FAIL ("Cannot find DWriteCreateFactory()."); - HRESULT hr; // TODO: factory and fontFileLoader should be cached separately IDWriteFactory* dwriteFactory; - hr = p_DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), - (IUnknown**) &dwriteFactory); + hr = DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), + (IUnknown**) &dwriteFactory); if (unlikely (hr != S_OK)) FAIL ("Failed to run DWriteCreateFactory()."); @@ -257,8 +227,6 @@ _hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data) delete data->fontFileStream; if (data->faceBlob) hb_blob_destroy (data->faceBlob); - if (data->dwrite_dll) - FreeLibrary (data->dwrite_dll); if (data) delete data; } @@ -794,6 +762,8 @@ retry_getglyphs: if (isRightToLeft) hb_buffer_reverse (buffer); + buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK); + delete [] clusterMap; delete [] glyphIndices; delete [] textProperties; diff --git a/thirdparty/harfbuzz/src/hb-fallback-shape.cc b/thirdparty/harfbuzz/src/hb-fallback-shape.cc index c5b7c2c230..f8524ecc8e 100644 --- a/thirdparty/harfbuzz/src/hb-fallback-shape.cc +++ b/thirdparty/harfbuzz/src/hb-fallback-shape.cc @@ -117,7 +117,7 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED, if (HB_DIRECTION_IS_BACKWARD (direction)) hb_buffer_reverse (buffer); - buffer->safe_to_break_all (); + buffer->clear_glyph_flags (); return true; } diff --git a/thirdparty/harfbuzz/src/hb-ft.cc b/thirdparty/harfbuzz/src/hb-ft.cc index 97a2c82e68..67691e3ff3 100644 --- a/thirdparty/harfbuzz/src/hb-ft.cc +++ b/thirdparty/harfbuzz/src/hb-ft.cc @@ -361,6 +361,7 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, } } +#ifndef HB_NO_VERTICAL static hb_position_t hb_ft_get_glyph_v_advance (hb_font_t *font, void *font_data, @@ -381,7 +382,9 @@ hb_ft_get_glyph_v_advance (hb_font_t *font, * have a Y growing upward. Hence the extra negation. */ return (-v + (1<<9)) >> 10; } +#endif +#ifndef HB_NO_VERTICAL static hb_bool_t hb_ft_get_glyph_v_origin (hb_font_t *font, void *font_data, @@ -409,6 +412,7 @@ hb_ft_get_glyph_v_origin (hb_font_t *font, return true; } +#endif #ifndef HB_NO_OT_SHAPE_FALLBACK static hb_position_t @@ -569,15 +573,20 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft { hb_font_funcs_t *funcs = hb_font_funcs_create (); - hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, nullptr, nullptr); - //hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, nullptr, nullptr); hb_font_funcs_set_nominal_glyph_func (funcs, hb_ft_get_nominal_glyph, nullptr, nullptr); hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ft_get_nominal_glyphs, nullptr, nullptr); hb_font_funcs_set_variation_glyph_func (funcs, hb_ft_get_variation_glyph, nullptr, nullptr); + + hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, nullptr, nullptr); hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ft_get_glyph_h_advances, nullptr, nullptr); - hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, nullptr, nullptr); //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, nullptr, nullptr); + +#ifndef HB_NO_VERTICAL + //hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, nullptr, nullptr); + hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, nullptr, nullptr); hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ft_get_glyph_v_origin, nullptr, nullptr); +#endif + #ifndef HB_NO_OT_SHAPE_FALLBACK hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ft_get_glyph_h_kerning, nullptr, nullptr); #endif diff --git a/thirdparty/harfbuzz/src/hb-graphite2.cc b/thirdparty/harfbuzz/src/hb-graphite2.cc index 209207f1e5..42420ac0b0 100644 --- a/thirdparty/harfbuzz/src/hb-graphite2.cc +++ b/thirdparty/harfbuzz/src/hb-graphite2.cc @@ -439,7 +439,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED, if (feats) gr_featureval_destroy (feats); gr_seg_destroy (seg); - buffer->unsafe_to_break_all (); + buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK); return true; } diff --git a/thirdparty/harfbuzz/src/hb-iter.hh b/thirdparty/harfbuzz/src/hb-iter.hh index 87b8ed880d..ad2e45e3c5 100644 --- a/thirdparty/harfbuzz/src/hb-iter.hh +++ b/thirdparty/harfbuzz/src/hb-iter.hh @@ -581,6 +581,91 @@ struct } HB_FUNCOBJ (hb_zip); +/* hb_concat() */ + +template <typename A, typename B> +struct hb_concat_iter_t : + hb_iter_t<hb_concat_iter_t<A, B>, typename A::item_t> +{ + hb_concat_iter_t () {} + hb_concat_iter_t (A& a, B& b) : a (a), b (b) {} + hb_concat_iter_t (const A& a, const B& b) : a (a), b (b) {} + + + typedef typename A::item_t __item_t__; + static constexpr bool is_random_access_iterator = + A::is_random_access_iterator && + B::is_random_access_iterator; + static constexpr bool is_sorted_iterator = false; + + __item_t__ __item__ () const + { + if (!a) + return *b; + return *a; + } + + __item_t__ __item_at__ (unsigned i) const + { + unsigned a_len = a.len (); + if (i < a_len) + return a[i]; + return b[i - a_len]; + } + + bool __more__ () const { return bool (a) || bool (b); } + + unsigned __len__ () const { return a.len () + b.len (); } + + void __next__ () + { + if (a) + ++a; + else + ++b; + } + + void __forward__ (unsigned n) + { + if (!n) return; + if (!is_random_access_iterator) { + while (n-- && *this) { + (*this)++; + } + return; + } + + unsigned a_len = a.len (); + if (n > a_len) { + n -= a_len; + a.__forward__ (a_len); + b.__forward__ (n); + } else { + a.__forward__ (n); + } + } + + hb_concat_iter_t __end__ () const { return hb_concat_iter_t (a.end (), b.end ()); } + bool operator != (const hb_concat_iter_t& o) const + { + return a != o.a + || b != o.b; + } + + private: + A a; + B b; +}; +struct +{ HB_PARTIALIZE(2); + template <typename A, typename B, + hb_requires (hb_is_iterable (A) && hb_is_iterable (B))> + hb_concat_iter_t<hb_iter_type<A>, hb_iter_type<B>> + operator () (A&& a, B&& b) const + { return hb_concat_iter_t<hb_iter_type<A>, hb_iter_type<B>> (hb_iter (a), hb_iter (b)); } +} +HB_FUNCOBJ (hb_concat); + /* hb_apply() */ template <typename Appl> diff --git a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh index c8a2af1e82..d837adc788 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh @@ -93,120 +93,192 @@ struct CmapSubtableFormat0 struct CmapSubtableFormat4 { + template<typename Iterator, + typename Writer, hb_requires (hb_is_iterator (Iterator))> - HBUINT16* serialize_endcode_array (hb_serialize_context_t *c, - Iterator it) - { - HBUINT16 *endCode = c->start_embed<HBUINT16> (); - hb_codepoint_t prev_endcp = 0xFFFF; + void to_ranges (Iterator it, Writer& range_writer) + { + hb_codepoint_t start_cp = 0, prev_run_start_cp = 0, run_start_cp = 0, end_cp = 0, last_gid = 0; + int run_length = 0 , delta = 0, prev_delta = 0; + + enum { + FIRST_SUB_RANGE, + FOLLOWING_SUB_RANGE, + } mode; + + while (it) { + // Start a new range + start_cp = (*it).first; + prev_run_start_cp = (*it).first; + run_start_cp = (*it).first; + end_cp = (*it).first; + last_gid = (*it).second; + run_length = 1; + prev_delta = 0; + + delta = (*it).second - (*it).first; + mode = FIRST_SUB_RANGE; + it++; + + while (it) { + // Process range + hb_codepoint_t next_cp = (*it).first; + hb_codepoint_t next_gid = (*it).second; + if (next_cp != end_cp + 1) { + // Current range is over, stop processing. + break; + } - for (const auto& _ : +it) - { - if (prev_endcp != 0xFFFF && prev_endcp + 1u != _.first) - { - HBUINT16 end_code; - end_code = prev_endcp; - c->copy<HBUINT16> (end_code); - } - prev_endcp = _.first; - } + if (next_gid == last_gid + 1) { + // The current run continues. + end_cp = next_cp; + run_length++; + last_gid = next_gid; + it++; + continue; + } - { - // last endCode - HBUINT16 endcode; - endcode = prev_endcp; - if (unlikely (!c->copy<HBUINT16> (endcode))) return nullptr; - // There must be a final entry with end_code == 0xFFFF. - if (prev_endcp != 0xFFFF) - { - HBUINT16 finalcode; - finalcode = 0xFFFF; - if (unlikely (!c->copy<HBUINT16> (finalcode))) return nullptr; + // A new run is starting, decide if we want to commit the current run. + int split_cost = (mode == FIRST_SUB_RANGE) ? 8 : 16; + int run_cost = run_length * 2; + if (run_cost >= split_cost) { + commit_current_range(start_cp, + prev_run_start_cp, + run_start_cp, + end_cp, + delta, + prev_delta, + split_cost, + range_writer); + start_cp = next_cp; + } + + // Start the new run + mode = FOLLOWING_SUB_RANGE; + prev_run_start_cp = run_start_cp; + run_start_cp = next_cp; + end_cp = next_cp; + prev_delta = delta; + delta = next_gid - run_start_cp; + run_length = 1; + last_gid = next_gid; + it++; } + + // Finalize range + commit_current_range (start_cp, + prev_run_start_cp, + run_start_cp, + end_cp, + delta, + prev_delta, + 8, + range_writer); } - return endCode; + if (likely (end_cp != 0xFFFF)) { + range_writer (0xFFFF, 0xFFFF, 1); + } } - template<typename Iterator, - hb_requires (hb_is_iterator (Iterator))> - HBUINT16* serialize_startcode_array (hb_serialize_context_t *c, - Iterator it) - { - HBUINT16 *startCode = c->start_embed<HBUINT16> (); - hb_codepoint_t prev_cp = 0xFFFF; - - for (const auto& _ : +it) - { - if (prev_cp == 0xFFFF || prev_cp + 1u != _.first) - { - HBUINT16 start_code; - start_code = _.first; - c->copy<HBUINT16> (start_code); + /* + * Writes the current range as either one or two ranges depending on what is most efficient. + */ + template<typename Writer> + void commit_current_range (hb_codepoint_t start, + hb_codepoint_t prev_run_start, + hb_codepoint_t run_start, + hb_codepoint_t end, + int run_delta, + int previous_run_delta, + int split_cost, + Writer& range_writer) { + bool should_split = false; + if (start < run_start && run_start < end) { + int run_cost = (end - run_start + 1) * 2; + if (run_cost >= split_cost) { + should_split = true; } + } - prev_cp = _.first; + // TODO(grieger): handle case where delta is legitimately 0, mark range offset array instead? + if (should_split) { + if (start == prev_run_start) + range_writer (start, run_start - 1, previous_run_delta); + else + range_writer (start, run_start - 1, 0); + range_writer (run_start, end, run_delta); + return; } - // There must be a final entry with end_code == 0xFFFF. - if (it.len () == 0 || prev_cp != 0xFFFF) - { - HBUINT16 finalcode; - finalcode = 0xFFFF; - if (unlikely (!c->copy<HBUINT16> (finalcode))) return nullptr; + + if (start == run_start) { + // Range is only a run + range_writer (start, end, run_delta); + return; } - return startCode; + // Write only a single non-run range. + range_writer (start, end, 0); } template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> - HBINT16* serialize_idDelta_array (hb_serialize_context_t *c, - Iterator it, - HBUINT16 *endCode, - HBUINT16 *startCode, - unsigned segcount) - { - unsigned i = 0; - hb_codepoint_t last_gid = 0, start_gid = 0, last_cp = 0xFFFF; - bool use_delta = true; - - HBINT16 *idDelta = c->start_embed<HBINT16> (); - if ((char *)idDelta - (char *)startCode != (int) segcount * (int) HBINT16::static_size) - return nullptr; - - for (const auto& _ : +it) - { - if (_.first == startCode[i]) - { - use_delta = true; - start_gid = _.second; + unsigned serialize_find_segcount (Iterator it) { + struct Counter { + unsigned segcount = 0; + + void operator() (hb_codepoint_t start, + hb_codepoint_t end, + int delta) { + segcount++; } - else if (_.second != last_gid + 1) use_delta = false; + } counter; - if (_.first == endCode[i]) - { - HBINT16 delta; - if (use_delta) delta = (int)start_gid - (int)startCode[i]; - else delta = 0; - c->copy<HBINT16> (delta); + to_ranges (+it, counter); + return counter.segcount; + } - i++; + + template<typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + bool serialize_start_end_delta_arrays (hb_serialize_context_t *c, + Iterator it, + int segcount) + { + struct Writer { + hb_serialize_context_t *serializer_; + HBUINT16* end_code_; + HBUINT16* start_code_; + HBINT16* id_delta_; + int index_; + + Writer(hb_serialize_context_t *serializer) + : serializer_(serializer), + end_code_(nullptr), + start_code_(nullptr), + id_delta_(nullptr), + index_ (0) {} + void operator() (hb_codepoint_t start, + hb_codepoint_t end, + int delta) { + start_code_[index_] = start; + end_code_[index_] = end; + id_delta_[index_] = delta; + index_++; } + } writer(c); - last_gid = _.second; - last_cp = _.first; - } + writer.end_code_ = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount); + c->allocate_size<HBUINT16> (2); // padding + writer.start_code_ = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount); + writer.id_delta_ = c->allocate_size<HBINT16> (HBINT16::static_size * segcount); - if (it.len () == 0 || last_cp != 0xFFFF) - { - HBINT16 delta; - delta = 1; - if (unlikely (!c->copy<HBINT16> (delta))) return nullptr; - } + if (unlikely (!writer.end_code_ || !writer.start_code_ || !writer.id_delta_)) return false; - return idDelta; + to_ranges (+it, writer); + return true; } template<typename Iterator, @@ -257,22 +329,14 @@ struct CmapSubtableFormat4 if (unlikely (!c->extend_min (this))) return; this->format = 4; - //serialize endCode[] - HBUINT16 *endCode = serialize_endcode_array (c, format4_iter); - if (unlikely (!endCode)) return; - - unsigned segcount = (c->length () - min_size) / HBUINT16::static_size; - - // 2 bytes of padding. - if (unlikely (!c->allocate_size<HBUINT16> (HBUINT16::static_size))) return; // 2 bytes of padding. - - // serialize startCode[] - HBUINT16 *startCode = serialize_startcode_array (c, format4_iter); - if (unlikely (!startCode)) return; + //serialize endCode[], startCode[], idDelta[] + HBUINT16* endCode = c->start_embed<HBUINT16> (); + unsigned segcount = serialize_find_segcount (format4_iter); + if (unlikely (!serialize_start_end_delta_arrays (c, format4_iter, segcount))) + return; - //serialize idDelta[] - HBINT16 *idDelta = serialize_idDelta_array (c, format4_iter, endCode, startCode, segcount); - if (unlikely (!idDelta)) return; + HBUINT16 *startCode = endCode + segcount + 1; + HBINT16 *idDelta = ((HBINT16*)startCode) + segcount; HBUINT16 *idRangeOffset = serialize_rangeoffset_glyid (c, format4_iter, endCode, startCode, idDelta, segcount); if (unlikely (!c->check_success (idRangeOffset))) return; diff --git a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh index a3c55fa8f4..008422d089 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh @@ -1025,7 +1025,7 @@ struct ClipList if (unlikely (!c->serializer->extend_min (out))) return_trace (false); if (!c->serializer->check_assign (out->format, format, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false); - const hb_set_t& glyphset = *c->plan->_glyphset; + const hb_set_t& glyphset = *c->plan->_glyphset_colred; const hb_map_t &glyph_map = *c->plan->glyph_map; hb_map_t new_gid_offset_map; @@ -1193,7 +1193,7 @@ struct BaseGlyphList : SortedArray32Of<BaseGlyphPaintRecord> TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - const hb_set_t* glyphset = c->plan->_glyphset; + const hb_set_t* glyphset = c->plan->_glyphset_colred; for (const auto& _ : as_array ()) { @@ -1411,10 +1411,9 @@ struct COLR const BaseGlyphRecord* get_base_glyph_record (hb_codepoint_t gid) const { - if ((unsigned int) gid == 0) // Ignore notdef. - return nullptr; const BaseGlyphRecord* record = &(this+baseGlyphsZ).bsearch (numBaseGlyphs, (unsigned int) gid); - if ((record && (hb_codepoint_t) record->glyphId != gid)) + if (record == &Null (BaseGlyphRecord) || + (record && (hb_codepoint_t) record->glyphId != gid)) record = nullptr; return record; } @@ -1432,9 +1431,16 @@ struct COLR TRACE_SUBSET (this); const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map; + const hb_set_t& glyphset = *c->plan->_glyphset_colred; auto base_it = + hb_range (c->plan->num_output_glyphs ()) + | hb_filter ([&](hb_codepoint_t new_gid) + { + hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid); + if (glyphset.has (old_gid)) return true; + return false; + }) | hb_map_retains_sorting ([&](hb_codepoint_t new_gid) { hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid); @@ -1442,7 +1448,6 @@ struct COLR const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid); if (unlikely (!old_record)) return hb_pair_t<bool, BaseGlyphRecord> (false, Null (BaseGlyphRecord)); - BaseGlyphRecord new_record = {}; new_record.glyphId = new_gid; new_record.numLayers = old_record->numLayers; @@ -1455,6 +1460,7 @@ struct COLR auto layer_it = + hb_range (c->plan->num_output_glyphs ()) | hb_map (reverse_glyph_map) + | hb_filter (glyphset) | hb_map_retains_sorting ([&](hb_codepoint_t old_gid) { const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid); diff --git a/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh b/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh index ffbbb1bc53..eff09838af 100644 --- a/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh +++ b/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh @@ -67,8 +67,11 @@ HB_OT_ACCELERATOR (OT, meta) #endif /* Vertical layout. */ +#ifndef HB_NO_VERTICAL HB_OT_TABLE (OT, vhea) HB_OT_ACCELERATOR (OT, vmtx) +HB_OT_TABLE (OT, VORG) +#endif /* TrueType outlines. */ HB_OT_ACCELERATOR (OT, glyf) @@ -77,7 +80,6 @@ HB_OT_ACCELERATOR (OT, glyf) #ifndef HB_NO_CFF HB_OT_ACCELERATOR (OT, cff1) HB_OT_ACCELERATOR (OT, cff2) -HB_OT_TABLE (OT, VORG) #endif /* OpenType variations. */ diff --git a/thirdparty/harfbuzz/src/hb-ot-font.cc b/thirdparty/harfbuzz/src/hb-ot-font.cc index 5c044c1c4f..9f0359a773 100644 --- a/thirdparty/harfbuzz/src/hb-ot-font.cc +++ b/thirdparty/harfbuzz/src/hb-ot-font.cc @@ -118,6 +118,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, } } +#ifndef HB_NO_VERTICAL static void hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, unsigned count, @@ -137,7 +138,9 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); } } +#endif +#ifndef HB_NO_VERTICAL static hb_bool_t hb_ot_get_glyph_v_origin (hb_font_t *font, void *font_data, @@ -150,14 +153,12 @@ hb_ot_get_glyph_v_origin (hb_font_t *font, *x = font->get_glyph_h_advance (glyph) / 2; -#ifndef HB_NO_OT_FONT_CFF const OT::VORG &VORG = *ot_face->VORG; if (VORG.has_data ()) { *y = font->em_scale_y (VORG.get_y_origin (glyph)); return true; } -#endif hb_glyph_extents_t extents = {0}; if (ot_face->glyf->get_extents (font, glyph, &extents)) @@ -174,6 +175,7 @@ hb_ot_get_glyph_v_origin (hb_font_t *font, return true; } +#endif static hb_bool_t hb_ot_get_glyph_extents (hb_font_t *font, @@ -242,6 +244,7 @@ hb_ot_get_font_h_extents (hb_font_t *font, _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, &metrics->line_gap); } +#ifndef HB_NO_VERTICAL static hb_bool_t hb_ot_get_font_v_extents (hb_font_t *font, void *font_data HB_UNUSED, @@ -252,6 +255,7 @@ hb_ot_get_font_v_extents (hb_font_t *font, _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_DESCENDER, &metrics->descender) && _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_LINE_GAP, &metrics->line_gap); } +#endif static inline void free_static_ot_funcs (); @@ -261,17 +265,23 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot { hb_font_funcs_t *funcs = hb_font_funcs_create (); - hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr); - hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr); hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr); hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ot_get_nominal_glyphs, nullptr, nullptr); hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr); + + hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr); hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ot_get_glyph_h_advances, nullptr, nullptr); - hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr); //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr); + +#ifndef HB_NO_VERTICAL + hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr); + hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr); hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr); +#endif + hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr); //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr); + #ifndef HB_NO_OT_FONT_GLYPH_NAMES hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr); hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr); diff --git a/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh b/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh index 6b419ea1ac..6aa34295c7 100644 --- a/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh @@ -93,22 +93,16 @@ struct glyf template<typename Iterator, hb_requires (hb_is_source_of (Iterator, unsigned int))> static bool - _add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets) + _add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets, bool use_short_loca) { - unsigned max_offset = - + padded_offsets - | hb_reduce (hb_add, 0) - ; unsigned num_offsets = padded_offsets.len () + 1; - bool use_short_loca = max_offset < 0x1FFFF; unsigned entry_size = use_short_loca ? 2 : 4; char *loca_prime_data = (char *) hb_calloc (entry_size, num_offsets); if (unlikely (!loca_prime_data)) return false; - DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d " - "max_offset %d size %d", - entry_size, num_offsets, max_offset, entry_size * num_offsets); + DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d size %d", + entry_size, num_offsets, entry_size * num_offsets); if (use_short_loca) _write_loca (padded_offsets, 1, hb_array ((HBUINT16 *) loca_prime_data, num_offsets)); @@ -151,11 +145,12 @@ struct glyf template <typename Iterator> bool serialize (hb_serialize_context_t *c, Iterator it, + bool use_short_loca, const hb_subset_plan_t *plan) { TRACE_SERIALIZE (this); unsigned init_len = c->length (); - for (const auto &_ : it) _.serialize (c, plan); + for (const auto &_ : it) _.serialize (c, use_short_loca, plan); /* As a special case when all glyph in the font are empty, add a zero byte * to the table, so that OTS doesn’t reject it, and to make the table work @@ -183,16 +178,28 @@ struct glyf hb_vector_t<SubsetGlyph> glyphs; _populate_subset_glyphs (c->plan, &glyphs); - glyf_prime->serialize (c->serializer, hb_iter (glyphs), c->plan); - auto padded_offsets = + hb_iter (glyphs) | hb_map (&SubsetGlyph::padded_size) ; + unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0); + bool use_short_loca = max_offset < 0x1FFFF; + + + glyf_prime->serialize (c->serializer, hb_iter (glyphs), use_short_loca, c->plan); + if (!use_short_loca) { + padded_offsets = + + hb_iter (glyphs) + | hb_map (&SubsetGlyph::length) + ; + } + + if (unlikely (c->serializer->in_error ())) return_trace (false); return_trace (c->serializer->check_success (_add_loca_and_head (c->plan, - padded_offsets))); + padded_offsets, + use_short_loca))); } template <typename SubsetGlyph> @@ -792,10 +799,23 @@ struct glyf hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); { for (unsigned i = 0; i < PHANTOM_COUNT; ++i) phantoms[i].init (); - int h_delta = (int) header->xMin - glyf_accelerator.hmtx->get_side_bearing (gid); - int v_orig = (int) header->yMax + glyf_accelerator.vmtx->get_side_bearing (gid); + int h_delta = (int) header->xMin - + glyf_accelerator.hmtx->get_side_bearing (gid); + int v_orig = (int) header->yMax + +#ifndef HB_NO_VERTICAL + glyf_accelerator.vmtx->get_side_bearing (gid) +#else + 0 +#endif + ; unsigned h_adv = glyf_accelerator.hmtx->get_advance (gid); - unsigned v_adv = glyf_accelerator.vmtx->get_advance (gid); + unsigned v_adv = +#ifndef HB_NO_VERTICAL + glyf_accelerator.vmtx->get_advance (gid) +#else + - font->face->get_upem () +#endif + ; phantoms[PHANTOM_LEFT].x = h_delta; phantoms[PHANTOM_RIGHT].x = h_adv + h_delta; phantoms[PHANTOM_TOP].y = v_orig; @@ -910,7 +930,9 @@ struct glyf gvar = nullptr; #endif hmtx = nullptr; +#ifndef HB_NO_VERTICAL vmtx = nullptr; +#endif face = face_; const OT::head &head = *face->table.head; if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0) @@ -924,7 +946,9 @@ struct glyf gvar = face->table.gvar; #endif hmtx = face->table.hmtx; +#ifndef HB_NO_VERTICAL vmtx = face->table.vmtx; +#endif num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1; num_glyphs = hb_min (num_glyphs, face->get_num_glyphs ()); @@ -1037,7 +1061,11 @@ struct glyf success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms)); if (unlikely (!success)) - return is_vertical ? vmtx->get_advance (gid) : hmtx->get_advance (gid); + return +#ifndef HB_NO_VERTICAL + is_vertical ? vmtx->get_advance (gid) : +#endif + hmtx->get_advance (gid); float result = is_vertical ? phantoms[PHANTOM_TOP].y - phantoms[PHANTOM_BOTTOM].y @@ -1053,7 +1081,11 @@ struct glyf contour_point_t phantoms[PHANTOM_COUNT]; if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms)))) - return is_vertical ? vmtx->get_side_bearing (gid) : hmtx->get_side_bearing (gid); + return +#ifndef HB_NO_VERTICAL + is_vertical ? vmtx->get_side_bearing (gid) : +#endif + hmtx->get_side_bearing (gid); return is_vertical ? ceilf (phantoms[PHANTOM_TOP].y) - extents.y_bearing @@ -1250,7 +1282,9 @@ struct glyf const gvar_accelerator_t *gvar; #endif const hmtx_accelerator_t *hmtx; +#ifndef HB_NO_VERTICAL const vmtx_accelerator_t *vmtx; +#endif private: bool short_offset; @@ -1269,13 +1303,14 @@ struct glyf hb_bytes_t dest_end; /* region of source_glyph to copy second */ bool serialize (hb_serialize_context_t *c, + bool use_short_loca, const hb_subset_plan_t *plan) const { TRACE_SERIALIZE (this); hb_bytes_t dest_glyph = dest_start.copy (c); dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length); - unsigned int pad_length = padding (); + unsigned int pad_length = use_short_loca ? padding () : 0; DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length + pad_length, pad_length); HBUINT8 pad; diff --git a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh index 4038329938..7d2d2d3eb8 100644 --- a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh @@ -165,7 +165,14 @@ struct hmtxvmtx { default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face); - num_advances = T::is_horizontal ? face->table.hhea->numberOfLongMetrics : face->table.vhea->numberOfLongMetrics; + num_advances = T::is_horizontal ? + face->table.hhea->numberOfLongMetrics : +#ifndef HB_NO_VERTICAL + face->table.vhea->numberOfLongMetrics +#else + 0 +#endif + ; table = hb_sanitize_context_t ().reference_table<hmtxvmtx> (face, T::tableTag); diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh index 882c3ae96f..4fb1893435 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh @@ -68,8 +68,8 @@ #define HB_MAX_FEATURE_INDICES 1500 #endif -#ifndef HB_MAX_LOOKUP_INDICES -#define HB_MAX_LOOKUP_INDICES 20000 +#ifndef HB_MAX_LOOKUP_VISIT_COUNT +#define HB_MAX_LOOKUP_VISIT_COUNT 35000 #endif @@ -173,7 +173,7 @@ struct hb_subset_layout_context_t : bool visitLookupIndex() { lookup_index_count++; - return lookup_index_count < HB_MAX_LOOKUP_INDICES; + return lookup_index_count < HB_MAX_LOOKUP_VISIT_COUNT; } hb_subset_context_t *subset_context; diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh index a8fb5c7acb..6db3e08940 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh @@ -118,7 +118,13 @@ struct ValueFormat : HBUINT16 if (!format) return ret; hb_font_t *font = c->font; - bool horizontal = HB_DIRECTION_IS_HORIZONTAL (c->direction); + bool horizontal = +#ifndef HB_NO_VERTICAL + HB_DIRECTION_IS_HORIZONTAL (c->direction) +#else + true +#endif + ; if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++, &ret)); if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++, &ret)); diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh index 710c5fbbb9..b7ce30135e 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh @@ -566,7 +566,7 @@ struct AlternateSet { /* Maybe we can do better than unsafe-to-break all; but since we are * changing random state, it would be hard to track that. Good 'nough. */ - c->buffer->unsafe_to_break_all (); + c->buffer->unsafe_to_break (0, c->buffer->len); alt_index = c->random_number () % count + 1; } diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh index 6bc06b50ed..191d3bebc5 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh @@ -81,12 +81,15 @@ struct hb_closure_context_t : nesting_level_left++; } + void reset_lookup_visit_count () + { lookup_count = 0; } + bool lookup_limit_exceeded () - { return lookup_count > HB_MAX_LOOKUP_INDICES; } + { return lookup_count > HB_MAX_LOOKUP_VISIT_COUNT; } bool should_visit_lookup (unsigned int lookup_index) { - if (lookup_count++ > HB_MAX_LOOKUP_INDICES) + if (lookup_count++ > HB_MAX_LOOKUP_VISIT_COUNT) return false; if (is_lookup_done (lookup_index)) @@ -211,7 +214,11 @@ struct hb_closure_lookups_context_t : return; /* Return if new lookup was recursed to before. */ - if (is_lookup_visited (lookup_index)) + if (lookup_limit_exceeded () + || visited_lookups->in_error () + || visited_lookups->has (lookup_index)) + // Don't increment lookup count here, that will be done in the call to closure_lookups() + // made by recurse_func. return; nesting_level_left--; @@ -226,12 +233,20 @@ struct hb_closure_lookups_context_t : { inactive_lookups->add (lookup_index); } bool lookup_limit_exceeded () - { return lookup_count > HB_MAX_LOOKUP_INDICES; } + { + bool ret = lookup_count > HB_MAX_LOOKUP_VISIT_COUNT; + if (ret) + DEBUG_MSG (SUBSET, nullptr, "lookup visit count limit exceeded in lookup closure!"); + return ret; } bool is_lookup_visited (unsigned lookup_index) { - if (unlikely (lookup_count++ > HB_MAX_LOOKUP_INDICES)) + if (unlikely (lookup_count++ > HB_MAX_LOOKUP_VISIT_COUNT)) + { + DEBUG_MSG (SUBSET, nullptr, "total visited lookup count %u exceeds max limit, lookup %u is dropped.", + lookup_count, lookup_index); return true; + } if (unlikely (visited_lookups->in_error ())) return true; @@ -1303,8 +1318,7 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c, } hb_set_add (covered_seq_indicies, seqIndex); - if (pos_glyphs) - c->push_cur_active_glyphs (pos_glyphs); + c->push_cur_active_glyphs (pos_glyphs ? pos_glyphs : c->glyphs); unsigned endIndex = inputCount; if (context_format == ContextFormat::CoverageBasedContext) @@ -1312,10 +1326,9 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c, c->recurse (lookupRecord[i].lookupListIndex, covered_seq_indicies, seqIndex, endIndex); - if (pos_glyphs) { - c->pop_cur_done_glyphs (); + c->pop_cur_done_glyphs (); + if (pos_glyphs) hb_set_destroy (pos_glyphs); - } } hb_set_destroy (covered_seq_indicies); diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc index 4e1d23eba5..60733648c1 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.cc +++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc @@ -1530,6 +1530,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, unsigned int glyphs_length; do { + c.reset_lookup_visit_count (); glyphs_length = glyphs->get_population (); if (lookups) { diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.hh b/thirdparty/harfbuzz/src/hb-ot-layout.hh index b15d053835..2c825e0c81 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout.hh @@ -350,24 +350,20 @@ _hb_glyph_info_is_continuation (const hb_glyph_info_t *info) { return info->unicode_props() & UPROPS_MASK_CONTINUATION; } -/* Loop over grapheme. Based on foreach_cluster(). */ -#define foreach_grapheme(buffer, start, end) \ - for (unsigned int \ - _count = buffer->len, \ - start = 0, end = _count ? _hb_next_grapheme (buffer, 0) : 0; \ - start < _count; \ - start = end, end = _hb_next_grapheme (buffer, start)) -static inline unsigned int -_hb_next_grapheme (hb_buffer_t *buffer, unsigned int start) -{ - hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; +static inline bool +_hb_grapheme_group_func (const hb_glyph_info_t& a HB_UNUSED, + const hb_glyph_info_t& b) +{ return _hb_glyph_info_is_continuation (&b); } - while (++start < count && _hb_glyph_info_is_continuation (&info[start])) - ; +#define foreach_grapheme(buffer, start, end) \ + foreach_group (buffer, start, end, _hb_grapheme_group_func) - return start; +static inline void +_hb_ot_layout_reverse_graphemes (hb_buffer_t *buffer) +{ + buffer->reverse_groups (_hb_grapheme_group_func, + buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); } static inline bool diff --git a/thirdparty/harfbuzz/src/hb-ot-math-table.hh b/thirdparty/harfbuzz/src/hb-ot-math-table.hh index c2e365dbd6..8d0b4317c3 100644 --- a/thirdparty/harfbuzz/src/hb-ot-math-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-math-table.hh @@ -511,7 +511,8 @@ struct MathGlyphInfo | hb_map_retains_sorting (glyph_map) ; - out->extendedShapeCoverage.serialize_serialize (c->serializer, it); + if (it) out->extendedShapeCoverage.serialize_serialize (c->serializer, it); + else out->extendedShapeCoverage = 0; out->mathKernInfo.serialize_subset (c, mathKernInfo, this); return_trace (true); @@ -884,8 +885,11 @@ struct MathVariants if (!o) return_trace (false); o->serialize_subset (c, glyphConstruction[i], this); } - - out->vertGlyphCoverage.serialize_serialize (c->serializer, new_vert_coverage.iter ()); + + if (new_vert_coverage) + out->vertGlyphCoverage.serialize_serialize (c->serializer, new_vert_coverage.iter ()); + + if (new_hori_coverage) out->horizGlyphCoverage.serialize_serialize (c->serializer, new_hori_coverage.iter ()); return_trace (true); } diff --git a/thirdparty/harfbuzz/src/hb-ot-metrics.cc b/thirdparty/harfbuzz/src/hb-ot-metrics.cc index 72aeff82d6..dbd4a1ffbe 100644 --- a/thirdparty/harfbuzz/src/hb-ot-metrics.cc +++ b/thirdparty/harfbuzz/src/hb-ot-metrics.cc @@ -77,6 +77,7 @@ _hb_ot_metrics_get_position_common (hb_font_t *font, (face->table.TABLE->has_data () && \ (position && (*position = font->em_scalef_y (_fix_ascender_descender ( \ face->table.TABLE->ATTR + GET_VAR, metrics_tag))), true)) + case HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER: return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoAscender)) || GET_METRIC_Y (hhea, ascender); @@ -86,9 +87,13 @@ _hb_ot_metrics_get_position_common (hb_font_t *font, case HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP: return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoLineGap)) || GET_METRIC_Y (hhea, lineGap); + +#ifndef HB_NO_VERTICAL case HB_OT_METRICS_TAG_VERTICAL_ASCENDER: return GET_METRIC_X (vhea, ascender); case HB_OT_METRICS_TAG_VERTICAL_DESCENDER: return GET_METRIC_X (vhea, descender); case HB_OT_METRICS_TAG_VERTICAL_LINE_GAP: return GET_METRIC_X (vhea, lineGap); +#endif + #undef GET_METRIC_Y #undef GET_METRIC_X #undef GET_VAR @@ -158,9 +163,11 @@ hb_ot_metrics_get_position (hb_font_t *font, case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE: return GET_METRIC_Y (hhea, caretSlopeRise); case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN: return GET_METRIC_X (hhea, caretSlopeRun); case HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET: return GET_METRIC_X (hhea, caretOffset); +#ifndef HB_NO_VERTICAL case HB_OT_METRICS_TAG_VERTICAL_CARET_RISE: return GET_METRIC_X (vhea, caretSlopeRise); case HB_OT_METRICS_TAG_VERTICAL_CARET_RUN: return GET_METRIC_Y (vhea, caretSlopeRun); case HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET: return GET_METRIC_Y (vhea, caretOffset); +#endif case HB_OT_METRICS_TAG_X_HEIGHT: return GET_METRIC_Y (OS2->v2 (), sxHeight); case HB_OT_METRICS_TAG_CAP_HEIGHT: return GET_METRIC_Y (OS2->v2 (), sCapHeight); case HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_SIZE: return GET_METRIC_X (OS2, ySubscriptXSize); diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc index 4e8a4bc3d1..4dde3520d8 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc @@ -628,20 +628,7 @@ hb_ensure_native_direction (hb_buffer_t *buffer) (HB_DIRECTION_IS_VERTICAL (direction) && direction != HB_DIRECTION_TTB)) { - - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) - foreach_grapheme (buffer, start, end) - { - buffer->merge_clusters (start, end); - buffer->reverse_range (start, end); - } - else - foreach_grapheme (buffer, start, end) - /* form_clusters() merged clusters already, we don't merge. */ - buffer->reverse_range (start, end); - - buffer->reverse (); - + _hb_ot_layout_reverse_graphemes (buffer); buffer->props.direction = HB_DIRECTION_REVERSE (buffer->props.direction); } } @@ -651,6 +638,7 @@ hb_ensure_native_direction (hb_buffer_t *buffer) * Substitute */ +#ifndef HB_NO_VERTICAL static hb_codepoint_t hb_vert_char_for (hb_codepoint_t u) { @@ -701,6 +689,7 @@ hb_vert_char_for (hb_codepoint_t u) return u; } +#endif static inline void hb_ot_rotate_chars (const hb_ot_shape_context_t *c) @@ -723,6 +712,7 @@ hb_ot_rotate_chars (const hb_ot_shape_context_t *c) } } +#ifndef HB_NO_VERTICAL if (HB_DIRECTION_IS_VERTICAL (c->target_direction) && !c->plan->has_vert) { for (unsigned int i = 0; i < count; i++) { @@ -731,6 +721,7 @@ hb_ot_rotate_chars (const hb_ot_shape_context_t *c) info[i].codepoint = codepoint; } } +#endif } static inline void diff --git a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh index fc9bffc23f..2c6316df4f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh @@ -6,7 +6,7 @@ * * on files with these headers: * - * <meta name="updated_at" content="2021-09-02 09:40 PM" /> + * <meta name="updated_at" content="2021-12-09 12:01 AM" /> * File-Date: 2021-08-06 */ @@ -933,6 +933,7 @@ static const LangTag ot_languages[] = { {"mnp", HB_TAG('Z','H','S',' ')}, /* Min Bei Chinese -> Chinese, Simplified */ {"mns", HB_TAG('M','A','N',' ')}, /* Mansi */ {"mnw", HB_TAG('M','O','N',' ')}, /* Mon */ + {"mnw", HB_TAG('M','O','N','T')}, /* Mon -> Thailand Mon */ {"mnx", HB_TAG_NONE }, /* Manikion != Manx */ {"mo", HB_TAG('M','O','L',' ')}, /* Moldavian (retired code) */ {"mod", HB_TAG('C','P','P',' ')}, /* Mobilian -> Creoles */ @@ -1422,6 +1423,7 @@ static const LangTag ot_languages[] = { {"tia", HB_TAG('B','B','R',' ')}, /* Tidikelt Tamazight -> Berber */ {"tig", HB_TAG('T','G','R',' ')}, /* Tigre */ /*{"tiv", HB_TAG('T','I','V',' ')},*/ /* Tiv */ +/*{"tjl", HB_TAG('T','J','L',' ')},*/ /* Tai Laing */ {"tjo", HB_TAG('B','B','R',' ')}, /* Temacine Tamazight -> Berber */ {"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */ {"tkg", HB_TAG('M','L','G',' ')}, /* Tesaka Malagasy -> Malagasy */ @@ -2521,6 +2523,14 @@ hb_ot_tags_from_complex_language (const char *lang_str, *count = 1; return true; } + if (0 == strncmp (&lang_str[1], "nw-", 3) + && subtag_matches (lang_str, limit, "-th")) + { + /* Mon; Thailand */ + tags[0] = HB_TAG('M','O','N','T'); /* Thailand Mon */ + *count = 1; + return true; + } break; case 'n': if (lang_matches (&lang_str[1], "an-hant-hk")) @@ -2884,6 +2894,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("man", -1); /* Mandingo [macrolanguage] */ case HB_TAG('M','O','L',' '): /* Moldavian */ return hb_language_from_string ("ro-MD", -1); /* Romanian; Moldova */ + case HB_TAG('M','O','N','T'): /* Thailand Mon */ + return hb_language_from_string ("mnw-TH", -1); /* Mon; Thailand */ case HB_TAG('M','Y','N',' '): /* Mayan */ return hb_language_from_string ("myn", -1); /* Mayan [family] */ case HB_TAG('N','A','H',' '): /* Nahuatl */ diff --git a/thirdparty/harfbuzz/src/hb-repacker.hh b/thirdparty/harfbuzz/src/hb-repacker.hh index 26faa56ea8..5c46b4cccc 100644 --- a/thirdparty/harfbuzz/src/hb-repacker.hh +++ b/thirdparty/harfbuzz/src/hb-repacker.hh @@ -100,12 +100,18 @@ struct graph_t bool is_leaf () const { - return !obj.links.length; + return !obj.real_links.length && !obj.virtual_links.length; } - void raise_priority () + bool raise_priority () { + if (has_max_priority ()) return false; priority++; + return true; + } + + bool has_max_priority () const { + return priority >= 3; } int64_t modified_distance (unsigned order) const @@ -115,15 +121,22 @@ struct graph_t // it's parent where possible. int64_t modified_distance = - hb_min (hb_max(distance + distance_modifier (), 0), 0x7FFFFFFFFF); - return (modified_distance << 22) | (0x003FFFFF & order); + hb_min (hb_max(distance + distance_modifier (), 0), 0x7FFFFFFFFFF); + if (has_max_priority ()) { + modified_distance = 0; + } + return (modified_distance << 18) | (0x003FFFF & order); } int64_t distance_modifier () const { if (!priority) return 0; int64_t table_size = obj.tail - obj.head; - return -(table_size - table_size / (1 << hb_min(priority, 16u))); + + if (priority == 1) + return -table_size / 2; + + return -table_size; } }; @@ -164,9 +177,10 @@ struct graph_t if (check_success (!vertices_.in_error ())) v->obj = *objects[i]; if (!removed_nil) continue; - for (unsigned i = 0; i < v->obj.links.length; i++) - // Fix indices to account for removed nil object. - v->obj.links[i].objidx--; + // Fix indices to account for removed nil object. + for (auto& l : v->obj.all_links_writer ()) { + l.objidx--; + } } } @@ -203,26 +217,46 @@ struct graph_t /* * serialize graph into the provided serialization buffer. */ - void serialize (hb_serialize_context_t* c) const + hb_blob_t* serialize () const { - c->start_serialize<void> (); + hb_vector_t<char> buffer; + size_t size = serialized_length (); + if (!buffer.alloc (size)) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Unable to allocate output buffer."); + return nullptr; + } + hb_serialize_context_t c((void *) buffer, size); + + c.start_serialize<void> (); for (unsigned i = 0; i < vertices_.length; i++) { - c->push (); + c.push (); size_t size = vertices_[i].obj.tail - vertices_[i].obj.head; - char* start = c->allocate_size <char> (size); - if (!start) return; + char* start = c.allocate_size <char> (size); + if (!start) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Buffer out of space."); + return nullptr; + } memcpy (start, vertices_[i].obj.head, size); - for (const auto& link : vertices_[i].obj.links) - serialize_link (link, start, c); + // Only real links needs to be serialized. + for (const auto& link : vertices_[i].obj.real_links) + serialize_link (link, start, &c); // All duplications are already encoded in the graph, so don't // enable sharing during packing. - c->pop_pack (false); + c.pop_pack (false); } - c->end_serialize (); + c.end_serialize (); + + if (c.in_error ()) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Error during serialization. Err flag: %d", + c.errors); + return nullptr; + } + + return c.copy_blob (); } /* @@ -260,7 +294,7 @@ struct graph_t sorted_graph[new_id] = next; id_map[next_id] = new_id--; - for (const auto& link : next.obj.links) { + for (const auto& link : next.obj.all_links ()) { removed_edges[link.objidx]++; if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx])) queue.push (link.objidx); @@ -314,7 +348,7 @@ struct graph_t sorted_graph[new_id] = next; id_map[next_id] = new_id--; - for (const auto& link : next.obj.links) { + for (const auto& link : next.obj.all_links ()) { removed_edges[link.objidx]++; if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx])) // Add the order that the links were encountered to the priority. @@ -348,7 +382,8 @@ struct graph_t hb_set_t roots; for (unsigned i = 0; i <= root_index; i++) { - for (auto& l : vertices_[i].obj.links) + // Only real links can form 32 bit spaces + for (auto& l : vertices_[i].obj.real_links) { if (l.width == 4 && !l.is_signed) { @@ -466,7 +501,7 @@ struct graph_t void find_subgraph (unsigned node_idx, hb_hashmap_t<unsigned, unsigned>& subgraph) { - for (const auto& link : vertices_[node_idx].obj.links) + for (const auto& link : vertices_[node_idx].obj.all_links ()) { if (subgraph.has (link.objidx)) { @@ -482,7 +517,7 @@ struct graph_t { if (subgraph.has (node_idx)) return; subgraph.add (node_idx); - for (const auto& link : vertices_[node_idx].obj.links) + for (const auto& link : vertices_[node_idx].obj.all_links ()) find_subgraph (link.objidx, subgraph); } @@ -497,7 +532,7 @@ struct graph_t return; index_map.set (node_idx, duplicate (node_idx)); - for (const auto& l : object (node_idx).links) { + for (const auto& l : object (node_idx).all_links ()) { duplicate_subgraph (l.objidx, index_map); } } @@ -523,13 +558,19 @@ struct graph_t clone->parents.reset (); unsigned clone_idx = vertices_.length - 2; - for (const auto& l : child.obj.links) + for (const auto& l : child.obj.real_links) { - clone->obj.links.push (l); + clone->obj.real_links.push (l); + vertices_[l.objidx].parents.push (clone_idx); + } + for (const auto& l : child.obj.virtual_links) + { + clone->obj.virtual_links.push (l); vertices_[l.objidx].parents.push (clone_idx); } - check_success (!clone->obj.links.in_error ()); + check_success (!clone->obj.real_links.in_error ()); + check_success (!clone->obj.virtual_links.in_error ()); // The last object is the root of the graph, so swap back the root to the end. // The root's obj idx does change, however since it's root nothing else refers to it. @@ -539,7 +580,7 @@ struct graph_t vertices_[vertices_.length - 1] = root; // Since the root moved, update the parents arrays of all children on the root. - for (const auto& l : root.obj.links) + for (const auto& l : root.obj.all_links ()) vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ()); return clone_idx; @@ -555,7 +596,7 @@ struct graph_t update_parents (); unsigned links_to_child = 0; - for (const auto& l : vertices_[parent_idx].obj.links) + for (const auto& l : vertices_[parent_idx].obj.all_links ()) { if (l.objidx == child_idx) links_to_child++; } @@ -578,9 +619,8 @@ struct graph_t if (parent_idx == clone_idx) parent_idx++; auto& parent = vertices_[parent_idx]; - for (unsigned i = 0; i < parent.obj.links.length; i++) + for (auto& l : parent.obj.all_links_writer ()) { - auto& l = parent.obj.links[i]; if (l.objidx != child_idx) continue; @@ -593,7 +633,7 @@ struct graph_t /* * Raises the sorting priority of all children. */ - void raise_childrens_priority (unsigned parent_idx) + bool raise_childrens_priority (unsigned parent_idx) { DEBUG_MSG (SUBSET_REPACK, nullptr, " Raising priority of all children of %d", parent_idx); @@ -601,8 +641,10 @@ struct graph_t // to invalidate positions. It does not change graph structure so no need // to update distances or edge counts. auto& parent = vertices_[parent_idx].obj; - for (unsigned i = 0; i < parent.links.length; i++) - vertices_[parent.links[i].objidx].raise_priority (); + bool made_change = false; + for (auto& l : parent.all_links_writer ()) + made_change |= vertices_[l.objidx].raise_priority (); + return made_change; } /* @@ -615,7 +657,8 @@ struct graph_t for (int parent_idx = vertices_.length - 1; parent_idx >= 0; parent_idx--) { - for (const auto& link : vertices_[parent_idx].obj.links) + // Don't need to check virtual links for overflow + for (const auto& link : vertices_[parent_idx].obj.real_links) { int64_t offset = compute_offset (parent_idx, link); if (is_valid_offset (offset, link)) @@ -655,8 +698,10 @@ struct graph_t if (!DEBUG_ENABLED(SUBSET_REPACK)) return; update_parents (); + int limit = 10; for (const auto& o : overflows) { + if (!limit--) break; const auto& parent = vertices_[o.parent]; const auto& child = vertices_[o.child]; DEBUG_MSG (SUBSET_REPACK, nullptr, @@ -665,13 +710,16 @@ struct graph_t "%4d (%4d in, %4d out, space %2d)", o.parent, parent.incoming_edges (), - parent.obj.links.length, + parent.obj.real_links.length + parent.obj.virtual_links.length, space_for (o.parent), o.child, child.incoming_edges (), - child.obj.links.length, + child.obj.real_links.length + child.obj.virtual_links.length, space_for (o.child)); } + if (overflows.length > 10) { + DEBUG_MSG (SUBSET_REPACK, nullptr, " ... plus %d more overflows.", overflows.length - 10); + } } unsigned num_roots_for_space (unsigned space) const @@ -684,12 +732,19 @@ struct graph_t return num_roots_for_space_.length; } - void move_to_new_space (unsigned index) + void move_to_new_space (const hb_set_t& indices) { - auto& node = vertices_[index]; - num_roots_for_space_.push (1); - num_roots_for_space_[node.space] = num_roots_for_space_[node.space] - 1; - node.space = num_roots_for_space_.length - 1; + num_roots_for_space_.push (0); + unsigned new_space = num_roots_for_space_.length - 1; + + for (unsigned index : indices) { + auto& node = vertices_[index]; + num_roots_for_space_[node.space] = num_roots_for_space_[node.space] - 1; + num_roots_for_space_[new_space] = num_roots_for_space_[new_space] + 1; + node.space = new_space; + distance_invalid = true; + positions_invalid = true; + } } unsigned space_for (unsigned index, unsigned* root = nullptr) const @@ -716,6 +771,15 @@ struct graph_t private: + size_t serialized_length () const { + size_t total_size = 0; + for (unsigned i = 0; i < vertices_.length; i++) { + size_t size = vertices_[i].obj.tail - vertices_[i].obj.head; + total_size += size; + } + return total_size; + } + /* * Returns the numbers of incoming edges that are 32bits wide. */ @@ -728,7 +792,8 @@ struct graph_t if (visited.has (p)) continue; visited.add (p); - for (const auto& l : vertices_[p].obj.links) + // Only real links can be wide + for (const auto& l : vertices_[p].obj.real_links) { if (l.objidx == node_idx && l.width == 4 && !l.is_signed) { @@ -755,7 +820,7 @@ struct graph_t for (unsigned p = 0; p < vertices_.length; p++) { - for (auto& l : vertices_[p].obj.links) + for (auto& l : vertices_[p].obj.all_links ()) { vertices_[l.objidx].parents.push (p); } @@ -823,7 +888,7 @@ struct graph_t int64_t next_distance = vertices_[next_idx].distance; visited[next_idx] = true; - for (const auto& link : next.obj.links) + for (const auto& link : next.obj.all_links ()) { if (visited[link.objidx]) continue; @@ -922,9 +987,8 @@ struct graph_t if (!id_map) return; for (unsigned i : subgraph) { - for (unsigned j = 0; j < vertices_[i].obj.links.length; j++) + for (auto& link : vertices_[i].obj.all_links_writer ()) { - auto& link = vertices_[i].obj.links[j]; if (!id_map.has (link.objidx)) continue; if (only_wide && !(link.width == 4 && !link.is_signed)) continue; @@ -942,9 +1006,8 @@ struct graph_t for (unsigned i = 0; i < sorted_graph->length; i++) { (*sorted_graph)[i].remap_parents (id_map); - for (unsigned j = 0; j < (*sorted_graph)[i].obj.links.length; j++) + for (auto& link : (*sorted_graph)[i].obj.all_links_writer ()) { - auto& link = (*sorted_graph)[i].obj.links[j]; link.objidx = id_map[link.objidx]; } } @@ -1023,7 +1086,7 @@ struct graph_t const auto& v = vertices_[start_idx]; // Graph is treated as undirected so search children and parents of start_idx - for (const auto& l : v.obj.links) + for (const auto& l : v.obj.all_links ()) find_connected_nodes (l.objidx, targets, visited, connected); for (unsigned p : v.parents) @@ -1044,27 +1107,50 @@ struct graph_t static bool _try_isolating_subgraphs (const hb_vector_t<graph_t::overflow_record_t>& overflows, graph_t& sorted_graph) { + unsigned space = 0; + hb_set_t roots_to_isolate; + for (int i = overflows.length - 1; i >= 0; i--) { const graph_t::overflow_record_t& r = overflows[i]; - unsigned root = 0; - unsigned space = sorted_graph.space_for (r.parent, &root); - if (!space) continue; - if (sorted_graph.num_roots_for_space (space) <= 1) continue; - DEBUG_MSG (SUBSET_REPACK, nullptr, "Overflow in space %d moving subgraph %d to space %d.", - space, - root, - sorted_graph.next_space ()); + unsigned root; + unsigned overflow_space = sorted_graph.space_for (r.parent, &root); + if (!overflow_space) continue; + if (sorted_graph.num_roots_for_space (overflow_space) <= 1) continue; - hb_set_t roots; - roots.add (root); - sorted_graph.isolate_subgraph (roots); - for (unsigned new_root : roots) - sorted_graph.move_to_new_space (new_root); - return true; + if (!space) { + space = overflow_space; + } + + if (space == overflow_space) + roots_to_isolate.add(root); } - return false; + + if (!roots_to_isolate) return false; + + unsigned maximum_to_move = hb_max ((sorted_graph.num_roots_for_space (space) / 2u), 1u); + if (roots_to_isolate.get_population () > maximum_to_move) { + // Only move at most half of the roots in a space at a time. + unsigned extra = roots_to_isolate.get_population () - maximum_to_move; + while (extra--) { + unsigned root = HB_SET_VALUE_INVALID; + roots_to_isolate.previous (&root); + roots_to_isolate.del (root); + } + } + + DEBUG_MSG (SUBSET_REPACK, nullptr, + "Overflow in space %d (%d roots). Moving %d roots to space %d.", + space, + sorted_graph.num_roots_for_space (space), + roots_to_isolate.get_population (), + sorted_graph.next_space ()); + + sorted_graph.isolate_subgraph (roots_to_isolate); + sorted_graph.move_to_new_space (roots_to_isolate); + + return true; } static bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& overflows, @@ -1093,16 +1179,16 @@ static bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& o // TODO(garretrieger): initially limiting this to leaf's since they can be // moved closer with fewer consequences. However, this can // likely can be used for non-leafs as well. - // TODO(garretrieger): add a maximum priority, don't try to raise past this. // TODO(garretrieger): also try lowering priority of the parent. Make it // get placed further up in the ordering, closer to it's children. // this is probably preferable if the total size of the parent object // is < then the total size of the children (and the parent can be moved). // Since in that case moving the parent will cause a smaller increase in // the length of other offsets. - sorted_graph.raise_childrens_priority (r.parent); - priority_bumped_parents.add (r.parent); - resolution_attempted = true; + if (sorted_graph.raise_childrens_priority (r.parent)) { + priority_bumped_parents.add (r.parent); + resolution_attempted = true; + } continue; } @@ -1127,19 +1213,17 @@ static bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& o * For a detailed writeup describing how the algorithm operates see: * docs/repacker.md */ -inline void +inline hb_blob_t* hb_resolve_overflows (const hb_vector_t<hb_serialize_context_t::object_t *>& packed, hb_tag_t table_tag, - hb_serialize_context_t* c, - unsigned max_rounds = 10) { + unsigned max_rounds = 20) { // Kahn sort is ~twice as fast as shortest distance sort and works for many fonts // so try it first to save time. graph_t sorted_graph (packed); sorted_graph.sort_kahn (); if (!sorted_graph.will_overflow ()) { - sorted_graph.serialize (c); - return; + return sorted_graph.serialize (); } sorted_graph.sort_shortest_distance (); @@ -1178,17 +1262,17 @@ hb_resolve_overflows (const hb_vector_t<hb_serialize_context_t::object_t *>& pac if (sorted_graph.in_error ()) { - c->err (HB_SERIALIZE_ERROR_OTHER); - return; + DEBUG_MSG (SUBSET_REPACK, nullptr, "Sorted graph in error state."); + return nullptr; } if (sorted_graph.will_overflow ()) { - c->err (HB_SERIALIZE_ERROR_OFFSET_OVERFLOW); DEBUG_MSG (SUBSET_REPACK, nullptr, "Offset overflow resolution failed."); - return; + return nullptr; } - sorted_graph.serialize (c); + + return sorted_graph.serialize (); } #endif /* HB_REPACKER_HH */ diff --git a/thirdparty/harfbuzz/src/hb-serialize.hh b/thirdparty/harfbuzz/src/hb-serialize.hh index d22ae06087..823c0be8b5 100644 --- a/thirdparty/harfbuzz/src/hb-serialize.hh +++ b/thirdparty/harfbuzz/src/hb-serialize.hh @@ -65,19 +65,26 @@ struct hb_serialize_context_t struct object_t { - void fini () { links.fini (); } + void fini () { + real_links.fini (); + virtual_links.fini (); + } bool operator == (const object_t &o) const { + // Virtual links aren't considered for equality since they don't affect the functionality + // of the object. return (tail - head == o.tail - o.head) - && (links.length == o.links.length) + && (real_links.length == o.real_links.length) && 0 == hb_memcmp (head, o.head, tail - head) - && links.as_bytes () == o.links.as_bytes (); + && real_links.as_bytes () == o.real_links.as_bytes (); } uint32_t hash () const { + // Virtual links aren't considered for equality since they don't affect the functionality + // of the object. return hb_bytes_t (head, tail - head).hash () ^ - links.as_bytes ().hash (); + real_links.as_bytes ().hash (); } struct link_t @@ -92,8 +99,14 @@ struct hb_serialize_context_t char *head; char *tail; - hb_vector_t<link_t> links; + hb_vector_t<link_t> real_links; + hb_vector_t<link_t> virtual_links; object_t *next; + + auto all_links () const HB_AUTO_RETURN + (( hb_concat (this->real_links, this->virtual_links) )); + auto all_links_writer () HB_AUTO_RETURN + (( hb_concat (this->real_links.writer (), this->virtual_links.writer ()) )); }; struct snapshot_t @@ -101,12 +114,14 @@ struct hb_serialize_context_t char *head; char *tail; object_t *current; // Just for sanity check - unsigned num_links; + unsigned num_real_links; + unsigned num_virtual_links; hb_serialize_error_t errors; }; snapshot_t snapshot () - { return snapshot_t { head, tail, current, current->links.length, errors }; } + { return snapshot_t { + head, tail, current, current->real_links.length, current->virtual_links.length, errors }; } hb_serialize_context_t (void *start_, unsigned int size) : start ((char *) start_), @@ -282,7 +297,8 @@ struct hb_serialize_context_t if (!len) { - assert (!obj->links.length); + assert (!obj->real_links.length); + assert (!obj->virtual_links.length); return 0; } @@ -292,6 +308,7 @@ struct hb_serialize_context_t objidx = packed_map.get (obj); if (objidx) { + merge_virtual_links (obj, objidx); obj->fini (); return objidx; } @@ -327,7 +344,8 @@ struct hb_serialize_context_t // Overflows that happened after the snapshot will be erased by the revert. if (unlikely (in_error () && !only_overflow ())) return; assert (snap.current == current); - current->links.shrink (snap.num_links); + current->real_links.shrink (snap.num_real_links); + current->virtual_links.shrink (snap.num_virtual_links); errors = snap.errors; revert (snap.head, snap.tail); } @@ -375,8 +393,8 @@ struct hb_serialize_context_t assert (current); - auto& link = *current->links.push (); - if (current->links.in_error ()) + auto& link = *current->virtual_links.push (); + if (current->virtual_links.in_error ()) err (HB_SERIALIZE_ERROR_OTHER); link.width = 0; @@ -400,8 +418,8 @@ struct hb_serialize_context_t assert (current); assert (current->head <= (const char *) &ofs); - auto& link = *current->links.push (); - if (current->links.in_error ()) + auto& link = *current->real_links.push (); + if (current->real_links.in_error ()) err (HB_SERIALIZE_ERROR_OTHER); link.width = sizeof (T); @@ -440,10 +458,8 @@ struct hb_serialize_context_t assert (packed.length > 1); for (const object_t* parent : ++hb_iter (packed)) - for (const object_t::link_t &link : parent->links) + for (const object_t::link_t &link : parent->real_links) { - if (unlikely (!link.width)) continue; // Don't need to resolve virtual offsets - const object_t* child = packed[link.objidx]; if (unlikely (!child)) { err (HB_SERIALIZE_ERROR_OTHER); return; } unsigned offset = 0; @@ -642,6 +658,13 @@ struct hb_serialize_context_t private: + void merge_virtual_links (const object_t* from, objidx_t to_idx) { + object_t* to = packed[to_idx]; + for (const auto& l : from->virtual_links) { + to->virtual_links.push (l); + } + } + /* Object memory pool. */ hb_pool_t<object_t> object_pool; diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc index 53f8664d92..883ab82093 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.cc +++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc @@ -248,7 +248,6 @@ static void _colr_closure (hb_face_t *face, unsigned glyphs_num; { glyphs_num = glyphs_colred->get_population (); - // Collect all glyphs referenced by COLRv0 hb_set_t glyphset_colrv0; for (hb_codepoint_t gid : glyphs_colred->iter ()) @@ -397,6 +396,7 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, _colr_closure (plan->source, plan->colrv1_layers, plan->colr_palettes, &cur_glyphset); _remove_invalid_gids (&cur_glyphset, plan->source->get_num_glyphs ()); + hb_set_set (plan->_glyphset_colred, &cur_glyphset); // Populate a full set of glyphs to retain by adding all referenced // composite glyphs. for (hb_codepoint_t gid : cur_glyphset.iter ()) @@ -511,6 +511,7 @@ hb_subset_plan_create (hb_face_t *face, plan->_glyphset = hb_set_create (); plan->_glyphset_gsub = hb_set_create (); plan->_glyphset_mathed = hb_set_create (); + plan->_glyphset_colred = hb_set_create (); plan->codepoint_to_glyph = hb_map_create (); plan->glyph_map = hb_map_create (); plan->reverse_glyph_map = hb_map_create (); @@ -579,6 +580,7 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) hb_set_destroy (plan->_glyphset); hb_set_destroy (plan->_glyphset_gsub); hb_set_destroy (plan->_glyphset_mathed); + hb_set_destroy (plan->_glyphset_colred); hb_map_destroy (plan->gsub_lookups); hb_map_destroy (plan->gpos_lookups); hb_map_destroy (plan->gsub_features); diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.hh b/thirdparty/harfbuzz/src/hb-subset-plan.hh index c0232480bf..b9244e5cb2 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.hh +++ b/thirdparty/harfbuzz/src/hb-subset-plan.hh @@ -78,6 +78,7 @@ struct hb_subset_plan_t hb_set_t *_glyphset; hb_set_t *_glyphset_gsub; hb_set_t *_glyphset_mathed; + hb_set_t *_glyphset_colred; //active lookups we'd like to retain hb_map_t *gsub_lookups; diff --git a/thirdparty/harfbuzz/src/hb-subset.cc b/thirdparty/harfbuzz/src/hb-subset.cc index 048bdf1888..bb46e5b97f 100644 --- a/thirdparty/harfbuzz/src/hb-subset.cc +++ b/thirdparty/harfbuzz/src/hb-subset.cc @@ -104,20 +104,16 @@ _repack (hb_tag_t tag, const hb_serialize_context_t& c) if (!c.offset_overflow ()) return c.copy_blob (); - hb_vector_t<char> buf; - int buf_size = c.end - c.start; - if (unlikely (!buf.alloc (buf_size))) - return nullptr; - - hb_serialize_context_t repacked ((void *) buf, buf_size); - hb_resolve_overflows (c.object_graph (), tag, &repacked); + hb_blob_t* result = hb_resolve_overflows (c.object_graph (), tag); - if (unlikely (repacked.in_error ())) - // TODO(garretrieger): refactor so we can share the resize/retry logic with the subset - // portion. + if (unlikely (!result)) + { + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c offset overflow resolution failed.", + HB_UNTAG (tag)); return nullptr; + } - return repacked.copy_blob (); + return result; } template<typename TableType> diff --git a/thirdparty/harfbuzz/src/hb-uniscribe.cc b/thirdparty/harfbuzz/src/hb-uniscribe.cc index 3dc4c0937d..0e5a114f7d 100644 --- a/thirdparty/harfbuzz/src/hb-uniscribe.cc +++ b/thirdparty/harfbuzz/src/hb-uniscribe.cc @@ -878,7 +878,7 @@ retry: if (backward) hb_buffer_reverse (buffer); - buffer->unsafe_to_break_all (); + buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK); /* Wow, done! */ return true; diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h index c9fefa1df6..52b124b745 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 2 +#define HB_VERSION_MICRO 0 /** * HB_VERSION_STRING: * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "3.1.2" +#define HB_VERSION_STRING "3.2.0" /** * HB_VERSION_ATLEAST: diff --git a/thirdparty/nanosvg/LICENSE.txt b/thirdparty/nanosvg/LICENSE.txt deleted file mode 100644 index f896f2eb0f..0000000000 --- a/thirdparty/nanosvg/LICENSE.txt +++ /dev/null @@ -1,18 +0,0 @@ -Copyright (c) 2013-14 Mikko Mononen memon@inside.org - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not -claim that you wrote the original software. If you use this software -in a product, an acknowledgment in the product documentation would be -appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. - diff --git a/thirdparty/nanosvg/nanosvg.cc b/thirdparty/nanosvg/nanosvg.cc deleted file mode 100644 index 3e8e86c792..0000000000 --- a/thirdparty/nanosvg/nanosvg.cc +++ /dev/null @@ -1,8 +0,0 @@ -#include "stdio.h" -#include "string.h" -#include "math.h" -#define NANOSVG_ALL_COLOR_KEYWORDS -#define NANOSVG_IMPLEMENTATION -#include "nanosvg.h" -#define NANOSVGRAST_IMPLEMENTATION -#include "nanosvgrast.h" diff --git a/thirdparty/nanosvg/nanosvg.h b/thirdparty/nanosvg/nanosvg.h deleted file mode 100644 index f5058b179a..0000000000 --- a/thirdparty/nanosvg/nanosvg.h +++ /dev/null @@ -1,3008 +0,0 @@ -/* - * Copyright (c) 2013-14 Mikko Mononen memon@inside.org - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * The SVG parser is based on Anti-Grain Geometry 2.4 SVG example - * Copyright (C) 2002-2004 Maxim Shemanarev (McSeem) (http://www.antigrain.com/) - * - * Arc calculation code based on canvg (https://code.google.com/p/canvg/) - * - * Bounding box calculation based on http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html - * - */ - -#ifndef NANOSVG_H -#define NANOSVG_H - -#ifndef NANOSVG_CPLUSPLUS -#ifdef __cplusplus -extern "C" { -#endif -#endif - -// NanoSVG is a simple stupid single-header-file SVG parse. The output of the parser is a list of cubic bezier shapes. -// -// The library suits well for anything from rendering scalable icons in your editor application to prototyping a game. -// -// NanoSVG supports a wide range of SVG features, but something may be missing, feel free to create a pull request! -// -// The shapes in the SVG images are transformed by the viewBox and converted to specified units. -// That is, you should get the same looking data as your designed in your favorite app. -// -// NanoSVG can return the paths in few different units. For example if you want to render an image, you may choose -// to get the paths in pixels, or if you are feeding the data into a CNC-cutter, you may want to use millimeters. -// -// The units passed to NanoSVG should be one of: 'px', 'pt', 'pc' 'mm', 'cm', or 'in'. -// DPI (dots-per-inch) controls how the unit conversion is done. -// -// If you don't know or care about the units stuff, "px" and 96 should get you going. - - -/* Example Usage: - // Load SVG - NSVGimage* image; - image = nsvgParseFromFile("test.svg", "px", 96); - printf("size: %f x %f\n", image->width, image->height); - // Use... - for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) { - for (NSVGpath *path = shape->paths; path != NULL; path = path->next) { - for (int i = 0; i < path->npts-1; i += 3) { - float* p = &path->pts[i*2]; - drawCubicBez(p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7]); - } - } - } - // Delete - nsvgDelete(image); -*/ - -enum NSVGpaintType { - NSVG_PAINT_NONE = 0, - NSVG_PAINT_COLOR = 1, - NSVG_PAINT_LINEAR_GRADIENT = 2, - NSVG_PAINT_RADIAL_GRADIENT = 3 -}; - -enum NSVGspreadType { - NSVG_SPREAD_PAD = 0, - NSVG_SPREAD_REFLECT = 1, - NSVG_SPREAD_REPEAT = 2 -}; - -enum NSVGlineJoin { - NSVG_JOIN_MITER = 0, - NSVG_JOIN_ROUND = 1, - NSVG_JOIN_BEVEL = 2 -}; - -enum NSVGlineCap { - NSVG_CAP_BUTT = 0, - NSVG_CAP_ROUND = 1, - NSVG_CAP_SQUARE = 2 -}; - -enum NSVGfillRule { - NSVG_FILLRULE_NONZERO = 0, - NSVG_FILLRULE_EVENODD = 1 -}; - -enum NSVGflags { - NSVG_FLAGS_VISIBLE = 0x01 -}; - -typedef struct NSVGgradientStop { - unsigned int color; - float offset; -} NSVGgradientStop; - -typedef struct NSVGgradient { - float xform[6]; - char spread; - float fx, fy; - int nstops; - NSVGgradientStop stops[1]; -} NSVGgradient; - -typedef struct NSVGpaint { - char type; - union { - unsigned int color; - NSVGgradient* gradient; - }; -} NSVGpaint; - -typedef struct NSVGpath -{ - float* pts; // Cubic bezier points: x0,y0, [cpx1,cpx1,cpx2,cpy2,x1,y1], ... - int npts; // Total number of bezier points. - char closed; // Flag indicating if shapes should be treated as closed. - float bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy]. - struct NSVGpath* next; // Pointer to next path, or NULL if last element. -} NSVGpath; - -typedef struct NSVGshape -{ - char id[64]; // Optional 'id' attr of the shape or its group - NSVGpaint fill; // Fill paint - NSVGpaint stroke; // Stroke paint - float opacity; // Opacity of the shape. - float strokeWidth; // Stroke width (scaled). - float strokeDashOffset; // Stroke dash offset (scaled). - float strokeDashArray[8]; // Stroke dash array (scaled). - char strokeDashCount; // Number of dash values in dash array. - char strokeLineJoin; // Stroke join type. - char strokeLineCap; // Stroke cap type. - float miterLimit; // Miter limit - char fillRule; // Fill rule, see NSVGfillRule. - unsigned char flags; // Logical or of NSVG_FLAGS_* flags - float bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy]. - NSVGpath* paths; // Linked list of paths in the image. - struct NSVGshape* next; // Pointer to next shape, or NULL if last element. -} NSVGshape; - -typedef struct NSVGimage -{ - float width; // Width of the image. - float height; // Height of the image. - NSVGshape* shapes; // Linked list of shapes in the image. -} NSVGimage; - -// Parses SVG file from a file, returns SVG image as paths. -NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi); - -// Parses SVG file from a null terminated string, returns SVG image as paths. -// Important note: changes the string. -NSVGimage* nsvgParse(char* input, const char* units, float dpi); - -// Duplicates a path. -NSVGpath* nsvgDuplicatePath(NSVGpath* p); - -// Deletes an image. -void nsvgDelete(NSVGimage* image); - -#ifndef NANOSVG_CPLUSPLUS -#ifdef __cplusplus -} -#endif -#endif - -#endif // NANOSVG_H - -#ifdef NANOSVG_IMPLEMENTATION - -#include <string.h> -#include <stdlib.h> -#include <math.h> - -#define NSVG_PI (3.14159265358979323846264338327f) -#define NSVG_KAPPA90 (0.5522847493f) // Length proportional to radius of a cubic bezier handle for 90deg arcs. - -#define NSVG_ALIGN_MIN 0 -#define NSVG_ALIGN_MID 1 -#define NSVG_ALIGN_MAX 2 -#define NSVG_ALIGN_NONE 0 -#define NSVG_ALIGN_MEET 1 -#define NSVG_ALIGN_SLICE 2 - -#define NSVG_NOTUSED(v) do { (void)(1 ? (void)0 : ( (void)(v) ) ); } while(0) -#define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16)) - -#ifdef _MSC_VER - #pragma warning (disable: 4996) // Switch off security warnings - #pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings - #ifdef __cplusplus - #define NSVG_INLINE inline - #else - #define NSVG_INLINE - #endif -#else - #define NSVG_INLINE inline -#endif - - -static int nsvg__isspace(char c) -{ - return strchr(" \t\n\v\f\r", c) != 0; -} - -static int nsvg__isdigit(char c) -{ - return c >= '0' && c <= '9'; -} - -static NSVG_INLINE float nsvg__minf(float a, float b) { return a < b ? a : b; } -static NSVG_INLINE float nsvg__maxf(float a, float b) { return a > b ? a : b; } - - -// Simple XML parser - -#define NSVG_XML_TAG 1 -#define NSVG_XML_CONTENT 2 -#define NSVG_XML_MAX_ATTRIBS 256 - -static void nsvg__parseContent(char* s, - void (*contentCb)(void* ud, const char* s), - void* ud) -{ - // Trim start white spaces - while (*s && nsvg__isspace(*s)) s++; - if (!*s) return; - - if (contentCb) - (*contentCb)(ud, s); -} - -static void nsvg__parseElement(char* s, - void (*startelCb)(void* ud, const char* el, const char** attr), - void (*endelCb)(void* ud, const char* el), - void* ud) -{ - const char* attr[NSVG_XML_MAX_ATTRIBS]; - int nattr = 0; - char* name; - int start = 0; - int end = 0; - char quote; - - // Skip white space after the '<' - while (*s && nsvg__isspace(*s)) s++; - - // Check if the tag is end tag - if (*s == '/') { - s++; - end = 1; - } else { - start = 1; - } - - // Skip comments, data and preprocessor stuff. - if (!*s || *s == '?' || *s == '!') - return; - - // Get tag name - name = s; - while (*s && !nsvg__isspace(*s)) s++; - if (*s) { *s++ = '\0'; } - - // Get attribs - while (!end && *s && nattr < NSVG_XML_MAX_ATTRIBS-3) { - char* name = NULL; - char* value = NULL; - - // Skip white space before the attrib name - while (*s && nsvg__isspace(*s)) s++; - if (!*s) break; - if (*s == '/') { - end = 1; - break; - } - name = s; - // Find end of the attrib name. - while (*s && !nsvg__isspace(*s) && *s != '=') s++; - if (*s) { *s++ = '\0'; } - // Skip until the beginning of the value. - while (*s && *s != '\"' && *s != '\'') s++; - if (!*s) break; - quote = *s; - s++; - // Store value and find the end of it. - value = s; - while (*s && *s != quote) s++; - if (*s) { *s++ = '\0'; } - - // Store only well formed attributes - if (name && value) { - attr[nattr++] = name; - attr[nattr++] = value; - } - } - - // List terminator - attr[nattr++] = 0; - attr[nattr++] = 0; - - // Call callbacks. - if (start && startelCb) - (*startelCb)(ud, name, attr); - if (end && endelCb) - (*endelCb)(ud, name); -} - -int nsvg__parseXML(char* input, - void (*startelCb)(void* ud, const char* el, const char** attr), - void (*endelCb)(void* ud, const char* el), - void (*contentCb)(void* ud, const char* s), - void* ud) -{ - char* s = input; - char* mark = s; - int state = NSVG_XML_CONTENT; - while (*s) { - if (*s == '<' && state == NSVG_XML_CONTENT) { - // Start of a tag - *s++ = '\0'; - nsvg__parseContent(mark, contentCb, ud); - mark = s; - state = NSVG_XML_TAG; - } else if (*s == '>' && state == NSVG_XML_TAG) { - // Start of a content or new tag. - *s++ = '\0'; - nsvg__parseElement(mark, startelCb, endelCb, ud); - mark = s; - state = NSVG_XML_CONTENT; - } else { - s++; - } - } - - return 1; -} - - -/* Simple SVG parser. */ - -#define NSVG_MAX_ATTR 128 - -enum NSVGgradientUnits { - NSVG_USER_SPACE = 0, - NSVG_OBJECT_SPACE = 1 -}; - -#define NSVG_MAX_DASHES 8 - -enum NSVGunits { - NSVG_UNITS_USER, - NSVG_UNITS_PX, - NSVG_UNITS_PT, - NSVG_UNITS_PC, - NSVG_UNITS_MM, - NSVG_UNITS_CM, - NSVG_UNITS_IN, - NSVG_UNITS_PERCENT, - NSVG_UNITS_EM, - NSVG_UNITS_EX -}; - -typedef struct NSVGcoordinate { - float value; - int units; -} NSVGcoordinate; - -typedef struct NSVGlinearData { - NSVGcoordinate x1, y1, x2, y2; -} NSVGlinearData; - -typedef struct NSVGradialData { - NSVGcoordinate cx, cy, r, fx, fy; -} NSVGradialData; - -typedef struct NSVGgradientData -{ - char id[64]; - char ref[64]; - char type; - union { - NSVGlinearData linear; - NSVGradialData radial; - }; - char spread; - char units; - float xform[6]; - int nstops; - NSVGgradientStop* stops; - struct NSVGgradientData* next; -} NSVGgradientData; - -typedef struct NSVGattrib -{ - char id[64]; - float xform[6]; - unsigned int fillColor; - unsigned int strokeColor; - float opacity; - float fillOpacity; - float strokeOpacity; - char fillGradient[64]; - char strokeGradient[64]; - float strokeWidth; - float strokeDashOffset; - float strokeDashArray[NSVG_MAX_DASHES]; - int strokeDashCount; - char strokeLineJoin; - char strokeLineCap; - float miterLimit; - char fillRule; - float fontSize; - unsigned int stopColor; - float stopOpacity; - float stopOffset; - char hasFill; - char hasStroke; - char visible; -} NSVGattrib; - -typedef struct NSVGparser -{ - NSVGattrib attr[NSVG_MAX_ATTR]; - int attrHead; - float* pts; - int npts; - int cpts; - NSVGpath* plist; - NSVGimage* image; - NSVGgradientData* gradients; - NSVGshape* shapesTail; - float viewMinx, viewMiny, viewWidth, viewHeight; - int alignX, alignY, alignType; - float dpi; - char pathFlag; - char defsFlag; -} NSVGparser; - -static void nsvg__xformIdentity(float* t) -{ - t[0] = 1.0f; t[1] = 0.0f; - t[2] = 0.0f; t[3] = 1.0f; - t[4] = 0.0f; t[5] = 0.0f; -} - -static void nsvg__xformSetTranslation(float* t, float tx, float ty) -{ - t[0] = 1.0f; t[1] = 0.0f; - t[2] = 0.0f; t[3] = 1.0f; - t[4] = tx; t[5] = ty; -} - -static void nsvg__xformSetScale(float* t, float sx, float sy) -{ - t[0] = sx; t[1] = 0.0f; - t[2] = 0.0f; t[3] = sy; - t[4] = 0.0f; t[5] = 0.0f; -} - -static void nsvg__xformSetSkewX(float* t, float a) -{ - t[0] = 1.0f; t[1] = 0.0f; - t[2] = tanf(a); t[3] = 1.0f; - t[4] = 0.0f; t[5] = 0.0f; -} - -static void nsvg__xformSetSkewY(float* t, float a) -{ - t[0] = 1.0f; t[1] = tanf(a); - t[2] = 0.0f; t[3] = 1.0f; - t[4] = 0.0f; t[5] = 0.0f; -} - -static void nsvg__xformSetRotation(float* t, float a) -{ - float cs = cosf(a), sn = sinf(a); - t[0] = cs; t[1] = sn; - t[2] = -sn; t[3] = cs; - t[4] = 0.0f; t[5] = 0.0f; -} - -static void nsvg__xformMultiply(float* t, float* s) -{ - float t0 = t[0] * s[0] + t[1] * s[2]; - float t2 = t[2] * s[0] + t[3] * s[2]; - float t4 = t[4] * s[0] + t[5] * s[2] + s[4]; - t[1] = t[0] * s[1] + t[1] * s[3]; - t[3] = t[2] * s[1] + t[3] * s[3]; - t[5] = t[4] * s[1] + t[5] * s[3] + s[5]; - t[0] = t0; - t[2] = t2; - t[4] = t4; -} - -static void nsvg__xformInverse(float* inv, float* t) -{ - double invdet, det = (double)t[0] * t[3] - (double)t[2] * t[1]; - if (det > -1e-6 && det < 1e-6) { - nsvg__xformIdentity(t); - return; - } - invdet = 1.0 / det; - inv[0] = (float)(t[3] * invdet); - inv[2] = (float)(-t[2] * invdet); - inv[4] = (float)(((double)t[2] * t[5] - (double)t[3] * t[4]) * invdet); - inv[1] = (float)(-t[1] * invdet); - inv[3] = (float)(t[0] * invdet); - inv[5] = (float)(((double)t[1] * t[4] - (double)t[0] * t[5]) * invdet); -} - -static void nsvg__xformPremultiply(float* t, float* s) -{ - float s2[6]; - memcpy(s2, s, sizeof(float)*6); - nsvg__xformMultiply(s2, t); - memcpy(t, s2, sizeof(float)*6); -} - -static void nsvg__xformPoint(float* dx, float* dy, float x, float y, float* t) -{ - *dx = x*t[0] + y*t[2] + t[4]; - *dy = x*t[1] + y*t[3] + t[5]; -} - -static void nsvg__xformVec(float* dx, float* dy, float x, float y, float* t) -{ - *dx = x*t[0] + y*t[2]; - *dy = x*t[1] + y*t[3]; -} - -#define NSVG_EPSILON (1e-12) - -static int nsvg__ptInBounds(float* pt, float* bounds) -{ - return pt[0] >= bounds[0] && pt[0] <= bounds[2] && pt[1] >= bounds[1] && pt[1] <= bounds[3]; -} - - -static double nsvg__evalBezier(double t, double p0, double p1, double p2, double p3) -{ - double it = 1.0-t; - return it*it*it*p0 + 3.0*it*it*t*p1 + 3.0*it*t*t*p2 + t*t*t*p3; -} - -static void nsvg__curveBounds(float* bounds, float* curve) -{ - int i, j, count; - double roots[2], a, b, c, b2ac, t, v; - float* v0 = &curve[0]; - float* v1 = &curve[2]; - float* v2 = &curve[4]; - float* v3 = &curve[6]; - - // Start the bounding box by end points - bounds[0] = nsvg__minf(v0[0], v3[0]); - bounds[1] = nsvg__minf(v0[1], v3[1]); - bounds[2] = nsvg__maxf(v0[0], v3[0]); - bounds[3] = nsvg__maxf(v0[1], v3[1]); - - // Bezier curve fits inside the convex hull of it's control points. - // If control points are inside the bounds, we're done. - if (nsvg__ptInBounds(v1, bounds) && nsvg__ptInBounds(v2, bounds)) - return; - - // Add bezier curve inflection points in X and Y. - for (i = 0; i < 2; i++) { - a = -3.0 * v0[i] + 9.0 * v1[i] - 9.0 * v2[i] + 3.0 * v3[i]; - b = 6.0 * v0[i] - 12.0 * v1[i] + 6.0 * v2[i]; - c = 3.0 * v1[i] - 3.0 * v0[i]; - count = 0; - if (fabs(a) < NSVG_EPSILON) { - if (fabs(b) > NSVG_EPSILON) { - t = -c / b; - if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON) - roots[count++] = t; - } - } else { - b2ac = b*b - 4.0*c*a; - if (b2ac > NSVG_EPSILON) { - t = (-b + sqrt(b2ac)) / (2.0 * a); - if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON) - roots[count++] = t; - t = (-b - sqrt(b2ac)) / (2.0 * a); - if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON) - roots[count++] = t; - } - } - for (j = 0; j < count; j++) { - v = nsvg__evalBezier(roots[j], v0[i], v1[i], v2[i], v3[i]); - bounds[0+i] = nsvg__minf(bounds[0+i], (float)v); - bounds[2+i] = nsvg__maxf(bounds[2+i], (float)v); - } - } -} - -static NSVGparser* nsvg__createParser() -{ - NSVGparser* p; - p = (NSVGparser*)malloc(sizeof(NSVGparser)); - if (p == NULL) goto error; - memset(p, 0, sizeof(NSVGparser)); - - p->image = (NSVGimage*)malloc(sizeof(NSVGimage)); - if (p->image == NULL) goto error; - memset(p->image, 0, sizeof(NSVGimage)); - - // Init style - nsvg__xformIdentity(p->attr[0].xform); - memset(p->attr[0].id, 0, sizeof p->attr[0].id); - p->attr[0].fillColor = NSVG_RGB(0,0,0); - p->attr[0].strokeColor = NSVG_RGB(0,0,0); - p->attr[0].opacity = 1; - p->attr[0].fillOpacity = 1; - p->attr[0].strokeOpacity = 1; - p->attr[0].stopOpacity = 1; - p->attr[0].strokeWidth = 1; - p->attr[0].strokeLineJoin = NSVG_JOIN_MITER; - p->attr[0].strokeLineCap = NSVG_CAP_BUTT; - p->attr[0].miterLimit = 4; - p->attr[0].fillRule = NSVG_FILLRULE_NONZERO; - p->attr[0].hasFill = 1; - p->attr[0].visible = 1; - - return p; - -error: - if (p) { - if (p->image) free(p->image); - free(p); - } - return NULL; -} - -static void nsvg__deletePaths(NSVGpath* path) -{ - while (path) { - NSVGpath *next = path->next; - if (path->pts != NULL) - free(path->pts); - free(path); - path = next; - } -} - -static void nsvg__deletePaint(NSVGpaint* paint) -{ - if (paint->type == NSVG_PAINT_LINEAR_GRADIENT || paint->type == NSVG_PAINT_RADIAL_GRADIENT) - free(paint->gradient); -} - -static void nsvg__deleteGradientData(NSVGgradientData* grad) -{ - NSVGgradientData* next; - while (grad != NULL) { - next = grad->next; - free(grad->stops); - free(grad); - grad = next; - } -} - -static void nsvg__deleteParser(NSVGparser* p) -{ - if (p != NULL) { - nsvg__deletePaths(p->plist); - nsvg__deleteGradientData(p->gradients); - nsvgDelete(p->image); - free(p->pts); - free(p); - } -} - -static void nsvg__resetPath(NSVGparser* p) -{ - p->npts = 0; -} - -static void nsvg__addPoint(NSVGparser* p, float x, float y) -{ - if (p->npts+1 > p->cpts) { - p->cpts = p->cpts ? p->cpts*2 : 8; - p->pts = (float*)realloc(p->pts, p->cpts*2*sizeof(float)); - if (!p->pts) return; - } - p->pts[p->npts*2+0] = x; - p->pts[p->npts*2+1] = y; - p->npts++; -} - -static void nsvg__moveTo(NSVGparser* p, float x, float y) -{ - if (p->npts > 0) { - p->pts[(p->npts-1)*2+0] = x; - p->pts[(p->npts-1)*2+1] = y; - } else { - nsvg__addPoint(p, x, y); - } -} - -static void nsvg__lineTo(NSVGparser* p, float x, float y) -{ - float px,py, dx,dy; - if (p->npts > 0) { - px = p->pts[(p->npts-1)*2+0]; - py = p->pts[(p->npts-1)*2+1]; - dx = x - px; - dy = y - py; - nsvg__addPoint(p, px + dx/3.0f, py + dy/3.0f); - nsvg__addPoint(p, x - dx/3.0f, y - dy/3.0f); - nsvg__addPoint(p, x, y); - } -} - -static void nsvg__cubicBezTo(NSVGparser* p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y) -{ - if (p->npts > 0) { - nsvg__addPoint(p, cpx1, cpy1); - nsvg__addPoint(p, cpx2, cpy2); - nsvg__addPoint(p, x, y); - } -} - -static NSVGattrib* nsvg__getAttr(NSVGparser* p) -{ - return &p->attr[p->attrHead]; -} - -static void nsvg__pushAttr(NSVGparser* p) -{ - if (p->attrHead < NSVG_MAX_ATTR-1) { - p->attrHead++; - memcpy(&p->attr[p->attrHead], &p->attr[p->attrHead-1], sizeof(NSVGattrib)); - } -} - -static void nsvg__popAttr(NSVGparser* p) -{ - if (p->attrHead > 0) - p->attrHead--; -} - -static float nsvg__actualOrigX(NSVGparser* p) -{ - return p->viewMinx; -} - -static float nsvg__actualOrigY(NSVGparser* p) -{ - return p->viewMiny; -} - -static float nsvg__actualWidth(NSVGparser* p) -{ - return p->viewWidth; -} - -static float nsvg__actualHeight(NSVGparser* p) -{ - return p->viewHeight; -} - -static float nsvg__actualLength(NSVGparser* p) -{ - float w = nsvg__actualWidth(p), h = nsvg__actualHeight(p); - return sqrtf(w*w + h*h) / sqrtf(2.0f); -} - -static float nsvg__convertToPixels(NSVGparser* p, NSVGcoordinate c, float orig, float length) -{ - NSVGattrib* attr = nsvg__getAttr(p); - switch (c.units) { - case NSVG_UNITS_USER: return c.value; - case NSVG_UNITS_PX: return c.value; - case NSVG_UNITS_PT: return c.value / 72.0f * p->dpi; - case NSVG_UNITS_PC: return c.value / 6.0f * p->dpi; - case NSVG_UNITS_MM: return c.value / 25.4f * p->dpi; - case NSVG_UNITS_CM: return c.value / 2.54f * p->dpi; - case NSVG_UNITS_IN: return c.value * p->dpi; - case NSVG_UNITS_EM: return c.value * attr->fontSize; - case NSVG_UNITS_EX: return c.value * attr->fontSize * 0.52f; // x-height of Helvetica. - case NSVG_UNITS_PERCENT: return orig + c.value / 100.0f * length; - default: return c.value; - } - return c.value; -} - -static NSVGgradientData* nsvg__findGradientData(NSVGparser* p, const char* id) -{ - NSVGgradientData* grad = p->gradients; - if (id == NULL || *id == '\0') - return NULL; - while (grad != NULL) { - if (strcmp(grad->id, id) == 0) - return grad; - grad = grad->next; - } - return NULL; -} - -static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const float* localBounds, char* paintType) -{ - NSVGattrib* attr = nsvg__getAttr(p); - NSVGgradientData* data = NULL; - NSVGgradientData* ref = NULL; - NSVGgradientStop* stops = NULL; - NSVGgradient* grad; - float ox, oy, sw, sh, sl; - int nstops = 0; - int refIter; - - data = nsvg__findGradientData(p, id); - if (data == NULL) return NULL; - - // TODO: use ref to fill in all unset values too. - ref = data; - refIter = 0; - while (ref != NULL) { - NSVGgradientData* nextRef = NULL; - if (stops == NULL && ref->stops != NULL) { - stops = ref->stops; - nstops = ref->nstops; - break; - } - nextRef = nsvg__findGradientData(p, ref->ref); - if (nextRef == ref) break; // prevent infite loops on malformed data - ref = nextRef; - refIter++; - if (refIter > 32) break; // prevent infite loops on malformed data - } - if (stops == NULL) return NULL; - - grad = (NSVGgradient*)malloc(sizeof(NSVGgradient) + sizeof(NSVGgradientStop)*(nstops-1)); - if (grad == NULL) return NULL; - - // The shape width and height. - if (data->units == NSVG_OBJECT_SPACE) { - ox = localBounds[0]; - oy = localBounds[1]; - sw = localBounds[2] - localBounds[0]; - sh = localBounds[3] - localBounds[1]; - } else { - ox = nsvg__actualOrigX(p); - oy = nsvg__actualOrigY(p); - sw = nsvg__actualWidth(p); - sh = nsvg__actualHeight(p); - } - sl = sqrtf(sw*sw + sh*sh) / sqrtf(2.0f); - - if (data->type == NSVG_PAINT_LINEAR_GRADIENT) { - float x1, y1, x2, y2, dx, dy; - x1 = nsvg__convertToPixels(p, data->linear.x1, ox, sw); - y1 = nsvg__convertToPixels(p, data->linear.y1, oy, sh); - x2 = nsvg__convertToPixels(p, data->linear.x2, ox, sw); - y2 = nsvg__convertToPixels(p, data->linear.y2, oy, sh); - // Calculate transform aligned to the line - dx = x2 - x1; - dy = y2 - y1; - grad->xform[0] = dy; grad->xform[1] = -dx; - grad->xform[2] = dx; grad->xform[3] = dy; - grad->xform[4] = x1; grad->xform[5] = y1; - } else { - float cx, cy, fx, fy, r; - cx = nsvg__convertToPixels(p, data->radial.cx, ox, sw); - cy = nsvg__convertToPixels(p, data->radial.cy, oy, sh); - fx = nsvg__convertToPixels(p, data->radial.fx, ox, sw); - fy = nsvg__convertToPixels(p, data->radial.fy, oy, sh); - r = nsvg__convertToPixels(p, data->radial.r, 0, sl); - // Calculate transform aligned to the circle - grad->xform[0] = r; grad->xform[1] = 0; - grad->xform[2] = 0; grad->xform[3] = r; - grad->xform[4] = cx; grad->xform[5] = cy; - grad->fx = fx / r; - grad->fy = fy / r; - } - - nsvg__xformMultiply(grad->xform, data->xform); - nsvg__xformMultiply(grad->xform, attr->xform); - - grad->spread = data->spread; - memcpy(grad->stops, stops, nstops*sizeof(NSVGgradientStop)); - grad->nstops = nstops; - - *paintType = data->type; - - return grad; -} - -static float nsvg__getAverageScale(float* t) -{ - float sx = sqrtf(t[0]*t[0] + t[2]*t[2]); - float sy = sqrtf(t[1]*t[1] + t[3]*t[3]); - return (sx + sy) * 0.5f; -} - -static void nsvg__getLocalBounds(float* bounds, NSVGshape *shape, float* xform) -{ - NSVGpath* path; - float curve[4*2], curveBounds[4]; - int i, first = 1; - for (path = shape->paths; path != NULL; path = path->next) { - nsvg__xformPoint(&curve[0], &curve[1], path->pts[0], path->pts[1], xform); - for (i = 0; i < path->npts-1; i += 3) { - nsvg__xformPoint(&curve[2], &curve[3], path->pts[(i+1)*2], path->pts[(i+1)*2+1], xform); - nsvg__xformPoint(&curve[4], &curve[5], path->pts[(i+2)*2], path->pts[(i+2)*2+1], xform); - nsvg__xformPoint(&curve[6], &curve[7], path->pts[(i+3)*2], path->pts[(i+3)*2+1], xform); - nsvg__curveBounds(curveBounds, curve); - if (first) { - bounds[0] = curveBounds[0]; - bounds[1] = curveBounds[1]; - bounds[2] = curveBounds[2]; - bounds[3] = curveBounds[3]; - first = 0; - } else { - bounds[0] = nsvg__minf(bounds[0], curveBounds[0]); - bounds[1] = nsvg__minf(bounds[1], curveBounds[1]); - bounds[2] = nsvg__maxf(bounds[2], curveBounds[2]); - bounds[3] = nsvg__maxf(bounds[3], curveBounds[3]); - } - curve[0] = curve[6]; - curve[1] = curve[7]; - } - } -} - -static void nsvg__addShape(NSVGparser* p) -{ - NSVGattrib* attr = nsvg__getAttr(p); - float scale = 1.0f; - NSVGshape* shape; - NSVGpath* path; - int i; - - if (p->plist == NULL) - return; - - shape = (NSVGshape*)malloc(sizeof(NSVGshape)); - if (shape == NULL) goto error; - memset(shape, 0, sizeof(NSVGshape)); - - memcpy(shape->id, attr->id, sizeof shape->id); - scale = nsvg__getAverageScale(attr->xform); - shape->strokeWidth = attr->strokeWidth * scale; - shape->strokeDashOffset = attr->strokeDashOffset * scale; - shape->strokeDashCount = (char)attr->strokeDashCount; - for (i = 0; i < attr->strokeDashCount; i++) - shape->strokeDashArray[i] = attr->strokeDashArray[i] * scale; - shape->strokeLineJoin = attr->strokeLineJoin; - shape->strokeLineCap = attr->strokeLineCap; - shape->miterLimit = attr->miterLimit; - shape->fillRule = attr->fillRule; - shape->opacity = attr->opacity; - - shape->paths = p->plist; - p->plist = NULL; - - // Calculate shape bounds - shape->bounds[0] = shape->paths->bounds[0]; - shape->bounds[1] = shape->paths->bounds[1]; - shape->bounds[2] = shape->paths->bounds[2]; - shape->bounds[3] = shape->paths->bounds[3]; - for (path = shape->paths->next; path != NULL; path = path->next) { - shape->bounds[0] = nsvg__minf(shape->bounds[0], path->bounds[0]); - shape->bounds[1] = nsvg__minf(shape->bounds[1], path->bounds[1]); - shape->bounds[2] = nsvg__maxf(shape->bounds[2], path->bounds[2]); - shape->bounds[3] = nsvg__maxf(shape->bounds[3], path->bounds[3]); - } - - // Set fill - if (attr->hasFill == 0) { - shape->fill.type = NSVG_PAINT_NONE; - } else if (attr->hasFill == 1) { - shape->fill.type = NSVG_PAINT_COLOR; - shape->fill.color = attr->fillColor; - shape->fill.color |= (unsigned int)(attr->fillOpacity*255) << 24; - } else if (attr->hasFill == 2) { - float inv[6], localBounds[4]; - nsvg__xformInverse(inv, attr->xform); - nsvg__getLocalBounds(localBounds, shape, inv); - shape->fill.gradient = nsvg__createGradient(p, attr->fillGradient, localBounds, &shape->fill.type); - if (shape->fill.gradient == NULL) { - shape->fill.type = NSVG_PAINT_NONE; - } - } - - // Set stroke - if (attr->hasStroke == 0) { - shape->stroke.type = NSVG_PAINT_NONE; - } else if (attr->hasStroke == 1) { - shape->stroke.type = NSVG_PAINT_COLOR; - shape->stroke.color = attr->strokeColor; - shape->stroke.color |= (unsigned int)(attr->strokeOpacity*255) << 24; - } else if (attr->hasStroke == 2) { - float inv[6], localBounds[4]; - nsvg__xformInverse(inv, attr->xform); - nsvg__getLocalBounds(localBounds, shape, inv); - shape->stroke.gradient = nsvg__createGradient(p, attr->strokeGradient, localBounds, &shape->stroke.type); - if (shape->stroke.gradient == NULL) - shape->stroke.type = NSVG_PAINT_NONE; - } - - // Set flags - shape->flags = (attr->visible ? NSVG_FLAGS_VISIBLE : 0x00); - - // Add to tail - if (p->image->shapes == NULL) - p->image->shapes = shape; - else - p->shapesTail->next = shape; - p->shapesTail = shape; - - return; - -error: - if (shape) free(shape); -} - -static void nsvg__addPath(NSVGparser* p, char closed) -{ - NSVGattrib* attr = nsvg__getAttr(p); - NSVGpath* path = NULL; - float bounds[4]; - float* curve; - int i; - - if (p->npts < 4) - return; - - if (closed) - nsvg__lineTo(p, p->pts[0], p->pts[1]); - - // Expect 1 + N*3 points (N = number of cubic bezier segments). - if ((p->npts % 3) != 1) - return; - - path = (NSVGpath*)malloc(sizeof(NSVGpath)); - if (path == NULL) goto error; - memset(path, 0, sizeof(NSVGpath)); - - path->pts = (float*)malloc(p->npts*2*sizeof(float)); - if (path->pts == NULL) goto error; - path->closed = closed; - path->npts = p->npts; - - // Transform path. - for (i = 0; i < p->npts; ++i) - nsvg__xformPoint(&path->pts[i*2], &path->pts[i*2+1], p->pts[i*2], p->pts[i*2+1], attr->xform); - - // Find bounds - for (i = 0; i < path->npts-1; i += 3) { - curve = &path->pts[i*2]; - nsvg__curveBounds(bounds, curve); - if (i == 0) { - path->bounds[0] = bounds[0]; - path->bounds[1] = bounds[1]; - path->bounds[2] = bounds[2]; - path->bounds[3] = bounds[3]; - } else { - path->bounds[0] = nsvg__minf(path->bounds[0], bounds[0]); - path->bounds[1] = nsvg__minf(path->bounds[1], bounds[1]); - path->bounds[2] = nsvg__maxf(path->bounds[2], bounds[2]); - path->bounds[3] = nsvg__maxf(path->bounds[3], bounds[3]); - } - } - - path->next = p->plist; - p->plist = path; - - return; - -error: - if (path != NULL) { - if (path->pts != NULL) free(path->pts); - free(path); - } -} - -// We roll our own string to float because the std library one uses locale and messes things up. -static double nsvg__atof(const char* s) -{ - char* cur = (char*)s; - char* end = NULL; - double res = 0.0, sign = 1.0; - long long intPart = 0, fracPart = 0; - char hasIntPart = 0, hasFracPart = 0; - - // Parse optional sign - if (*cur == '+') { - cur++; - } else if (*cur == '-') { - sign = -1; - cur++; - } - - // Parse integer part - if (nsvg__isdigit(*cur)) { - // Parse digit sequence - intPart = strtoll(cur, &end, 10); - if (cur != end) { - res = (double)intPart; - hasIntPart = 1; - cur = end; - } - } - - // Parse fractional part. - if (*cur == '.') { - cur++; // Skip '.' - if (nsvg__isdigit(*cur)) { - // Parse digit sequence - fracPart = strtoll(cur, &end, 10); - if (cur != end) { - res += (double)fracPart / pow(10.0, (double)(end - cur)); - hasFracPart = 1; - cur = end; - } - } - } - - // A valid number should have integer or fractional part. - if (!hasIntPart && !hasFracPart) - return 0.0; - - // Parse optional exponent - if (*cur == 'e' || *cur == 'E') { - long expPart = 0; - cur++; // skip 'E' - expPart = strtol(cur, &end, 10); // Parse digit sequence with sign - if (cur != end) { - res *= pow(10.0, (double)expPart); - } - } - - return res * sign; -} - - -static const char* nsvg__parseNumber(const char* s, char* it, const int size) -{ - const int last = size-1; - int i = 0; - - // sign - if (*s == '-' || *s == '+') { - if (i < last) it[i++] = *s; - s++; - } - // integer part - while (*s && nsvg__isdigit(*s)) { - if (i < last) it[i++] = *s; - s++; - } - if (*s == '.') { - // decimal point - if (i < last) it[i++] = *s; - s++; - // fraction part - while (*s && nsvg__isdigit(*s)) { - if (i < last) it[i++] = *s; - s++; - } - } - // exponent - if ((*s == 'e' || *s == 'E') && (s[1] != 'm' && s[1] != 'x')) { - if (i < last) it[i++] = *s; - s++; - if (*s == '-' || *s == '+') { - if (i < last) it[i++] = *s; - s++; - } - while (*s && nsvg__isdigit(*s)) { - if (i < last) it[i++] = *s; - s++; - } - } - it[i] = '\0'; - - return s; -} - -static const char* nsvg__getNextPathItem(const char* s, char* it) -{ - it[0] = '\0'; - // Skip white spaces and commas - while (*s && (nsvg__isspace(*s) || *s == ',')) s++; - if (!*s) return s; - if (*s == '-' || *s == '+' || *s == '.' || nsvg__isdigit(*s)) { - s = nsvg__parseNumber(s, it, 64); - } else { - // Parse command - it[0] = *s++; - it[1] = '\0'; - return s; - } - - return s; -} - -static unsigned int nsvg__parseColorHex(const char* str) -{ - unsigned int r=0, g=0, b=0; - if (sscanf(str, "#%2x%2x%2x", &r, &g, &b) == 3 ) // 2 digit hex - return NSVG_RGB(r, g, b); - if (sscanf(str, "#%1x%1x%1x", &r, &g, &b) == 3 ) // 1 digit hex, e.g. #abc -> 0xccbbaa - return NSVG_RGB(r*17, g*17, b*17); // same effect as (r<<4|r), (g<<4|g), .. - return NSVG_RGB(128, 128, 128); -} - -static unsigned int nsvg__parseColorRGB(const char* str) -{ - unsigned int r=0, g=0, b=0; - if (sscanf(str, "rgb(%u, %u, %u)", &r, &g, &b) == 3) // decimal integers - return NSVG_RGB(r, g, b); - if (sscanf(str, "rgb(%u%%, %u%%, %u%%)", &r, &g, &b) == 3) // decimal integer percentage - return NSVG_RGB(r*255/100, g*255/100, b*255/100); - return NSVG_RGB(128, 128, 128); -} - -typedef struct NSVGNamedColor { - const char* name; - unsigned int color; -} NSVGNamedColor; - -NSVGNamedColor nsvg__colors[] = { - - { "red", NSVG_RGB(255, 0, 0) }, - { "green", NSVG_RGB( 0, 128, 0) }, - { "blue", NSVG_RGB( 0, 0, 255) }, - { "yellow", NSVG_RGB(255, 255, 0) }, - { "cyan", NSVG_RGB( 0, 255, 255) }, - { "magenta", NSVG_RGB(255, 0, 255) }, - { "black", NSVG_RGB( 0, 0, 0) }, - { "grey", NSVG_RGB(128, 128, 128) }, - { "gray", NSVG_RGB(128, 128, 128) }, - { "white", NSVG_RGB(255, 255, 255) }, - -#ifdef NANOSVG_ALL_COLOR_KEYWORDS - { "aliceblue", NSVG_RGB(240, 248, 255) }, - { "antiquewhite", NSVG_RGB(250, 235, 215) }, - { "aqua", NSVG_RGB( 0, 255, 255) }, - { "aquamarine", NSVG_RGB(127, 255, 212) }, - { "azure", NSVG_RGB(240, 255, 255) }, - { "beige", NSVG_RGB(245, 245, 220) }, - { "bisque", NSVG_RGB(255, 228, 196) }, - { "blanchedalmond", NSVG_RGB(255, 235, 205) }, - { "blueviolet", NSVG_RGB(138, 43, 226) }, - { "brown", NSVG_RGB(165, 42, 42) }, - { "burlywood", NSVG_RGB(222, 184, 135) }, - { "cadetblue", NSVG_RGB( 95, 158, 160) }, - { "chartreuse", NSVG_RGB(127, 255, 0) }, - { "chocolate", NSVG_RGB(210, 105, 30) }, - { "coral", NSVG_RGB(255, 127, 80) }, - { "cornflowerblue", NSVG_RGB(100, 149, 237) }, - { "cornsilk", NSVG_RGB(255, 248, 220) }, - { "crimson", NSVG_RGB(220, 20, 60) }, - { "darkblue", NSVG_RGB( 0, 0, 139) }, - { "darkcyan", NSVG_RGB( 0, 139, 139) }, - { "darkgoldenrod", NSVG_RGB(184, 134, 11) }, - { "darkgray", NSVG_RGB(169, 169, 169) }, - { "darkgreen", NSVG_RGB( 0, 100, 0) }, - { "darkgrey", NSVG_RGB(169, 169, 169) }, - { "darkkhaki", NSVG_RGB(189, 183, 107) }, - { "darkmagenta", NSVG_RGB(139, 0, 139) }, - { "darkolivegreen", NSVG_RGB( 85, 107, 47) }, - { "darkorange", NSVG_RGB(255, 140, 0) }, - { "darkorchid", NSVG_RGB(153, 50, 204) }, - { "darkred", NSVG_RGB(139, 0, 0) }, - { "darksalmon", NSVG_RGB(233, 150, 122) }, - { "darkseagreen", NSVG_RGB(143, 188, 143) }, - { "darkslateblue", NSVG_RGB( 72, 61, 139) }, - { "darkslategray", NSVG_RGB( 47, 79, 79) }, - { "darkslategrey", NSVG_RGB( 47, 79, 79) }, - { "darkturquoise", NSVG_RGB( 0, 206, 209) }, - { "darkviolet", NSVG_RGB(148, 0, 211) }, - { "deeppink", NSVG_RGB(255, 20, 147) }, - { "deepskyblue", NSVG_RGB( 0, 191, 255) }, - { "dimgray", NSVG_RGB(105, 105, 105) }, - { "dimgrey", NSVG_RGB(105, 105, 105) }, - { "dodgerblue", NSVG_RGB( 30, 144, 255) }, - { "firebrick", NSVG_RGB(178, 34, 34) }, - { "floralwhite", NSVG_RGB(255, 250, 240) }, - { "forestgreen", NSVG_RGB( 34, 139, 34) }, - { "fuchsia", NSVG_RGB(255, 0, 255) }, - { "gainsboro", NSVG_RGB(220, 220, 220) }, - { "ghostwhite", NSVG_RGB(248, 248, 255) }, - { "gold", NSVG_RGB(255, 215, 0) }, - { "goldenrod", NSVG_RGB(218, 165, 32) }, - { "greenyellow", NSVG_RGB(173, 255, 47) }, - { "honeydew", NSVG_RGB(240, 255, 240) }, - { "hotpink", NSVG_RGB(255, 105, 180) }, - { "indianred", NSVG_RGB(205, 92, 92) }, - { "indigo", NSVG_RGB( 75, 0, 130) }, - { "ivory", NSVG_RGB(255, 255, 240) }, - { "khaki", NSVG_RGB(240, 230, 140) }, - { "lavender", NSVG_RGB(230, 230, 250) }, - { "lavenderblush", NSVG_RGB(255, 240, 245) }, - { "lawngreen", NSVG_RGB(124, 252, 0) }, - { "lemonchiffon", NSVG_RGB(255, 250, 205) }, - { "lightblue", NSVG_RGB(173, 216, 230) }, - { "lightcoral", NSVG_RGB(240, 128, 128) }, - { "lightcyan", NSVG_RGB(224, 255, 255) }, - { "lightgoldenrodyellow", NSVG_RGB(250, 250, 210) }, - { "lightgray", NSVG_RGB(211, 211, 211) }, - { "lightgreen", NSVG_RGB(144, 238, 144) }, - { "lightgrey", NSVG_RGB(211, 211, 211) }, - { "lightpink", NSVG_RGB(255, 182, 193) }, - { "lightsalmon", NSVG_RGB(255, 160, 122) }, - { "lightseagreen", NSVG_RGB( 32, 178, 170) }, - { "lightskyblue", NSVG_RGB(135, 206, 250) }, - { "lightslategray", NSVG_RGB(119, 136, 153) }, - { "lightslategrey", NSVG_RGB(119, 136, 153) }, - { "lightsteelblue", NSVG_RGB(176, 196, 222) }, - { "lightyellow", NSVG_RGB(255, 255, 224) }, - { "lime", NSVG_RGB( 0, 255, 0) }, - { "limegreen", NSVG_RGB( 50, 205, 50) }, - { "linen", NSVG_RGB(250, 240, 230) }, - { "maroon", NSVG_RGB(128, 0, 0) }, - { "mediumaquamarine", NSVG_RGB(102, 205, 170) }, - { "mediumblue", NSVG_RGB( 0, 0, 205) }, - { "mediumorchid", NSVG_RGB(186, 85, 211) }, - { "mediumpurple", NSVG_RGB(147, 112, 219) }, - { "mediumseagreen", NSVG_RGB( 60, 179, 113) }, - { "mediumslateblue", NSVG_RGB(123, 104, 238) }, - { "mediumspringgreen", NSVG_RGB( 0, 250, 154) }, - { "mediumturquoise", NSVG_RGB( 72, 209, 204) }, - { "mediumvioletred", NSVG_RGB(199, 21, 133) }, - { "midnightblue", NSVG_RGB( 25, 25, 112) }, - { "mintcream", NSVG_RGB(245, 255, 250) }, - { "mistyrose", NSVG_RGB(255, 228, 225) }, - { "moccasin", NSVG_RGB(255, 228, 181) }, - { "navajowhite", NSVG_RGB(255, 222, 173) }, - { "navy", NSVG_RGB( 0, 0, 128) }, - { "oldlace", NSVG_RGB(253, 245, 230) }, - { "olive", NSVG_RGB(128, 128, 0) }, - { "olivedrab", NSVG_RGB(107, 142, 35) }, - { "orange", NSVG_RGB(255, 165, 0) }, - { "orangered", NSVG_RGB(255, 69, 0) }, - { "orchid", NSVG_RGB(218, 112, 214) }, - { "palegoldenrod", NSVG_RGB(238, 232, 170) }, - { "palegreen", NSVG_RGB(152, 251, 152) }, - { "paleturquoise", NSVG_RGB(175, 238, 238) }, - { "palevioletred", NSVG_RGB(219, 112, 147) }, - { "papayawhip", NSVG_RGB(255, 239, 213) }, - { "peachpuff", NSVG_RGB(255, 218, 185) }, - { "peru", NSVG_RGB(205, 133, 63) }, - { "pink", NSVG_RGB(255, 192, 203) }, - { "plum", NSVG_RGB(221, 160, 221) }, - { "powderblue", NSVG_RGB(176, 224, 230) }, - { "purple", NSVG_RGB(128, 0, 128) }, - { "rosybrown", NSVG_RGB(188, 143, 143) }, - { "royalblue", NSVG_RGB( 65, 105, 225) }, - { "saddlebrown", NSVG_RGB(139, 69, 19) }, - { "salmon", NSVG_RGB(250, 128, 114) }, - { "sandybrown", NSVG_RGB(244, 164, 96) }, - { "seagreen", NSVG_RGB( 46, 139, 87) }, - { "seashell", NSVG_RGB(255, 245, 238) }, - { "sienna", NSVG_RGB(160, 82, 45) }, - { "silver", NSVG_RGB(192, 192, 192) }, - { "skyblue", NSVG_RGB(135, 206, 235) }, - { "slateblue", NSVG_RGB(106, 90, 205) }, - { "slategray", NSVG_RGB(112, 128, 144) }, - { "slategrey", NSVG_RGB(112, 128, 144) }, - { "snow", NSVG_RGB(255, 250, 250) }, - { "springgreen", NSVG_RGB( 0, 255, 127) }, - { "steelblue", NSVG_RGB( 70, 130, 180) }, - { "tan", NSVG_RGB(210, 180, 140) }, - { "teal", NSVG_RGB( 0, 128, 128) }, - { "thistle", NSVG_RGB(216, 191, 216) }, - { "tomato", NSVG_RGB(255, 99, 71) }, - { "turquoise", NSVG_RGB( 64, 224, 208) }, - { "violet", NSVG_RGB(238, 130, 238) }, - { "wheat", NSVG_RGB(245, 222, 179) }, - { "whitesmoke", NSVG_RGB(245, 245, 245) }, - { "yellowgreen", NSVG_RGB(154, 205, 50) }, -#endif -}; - -static unsigned int nsvg__parseColorName(const char* str) -{ - int i, ncolors = sizeof(nsvg__colors) / sizeof(NSVGNamedColor); - - for (i = 0; i < ncolors; i++) { - if (strcmp(nsvg__colors[i].name, str) == 0) { - return nsvg__colors[i].color; - } - } - - return NSVG_RGB(128, 128, 128); -} - -static unsigned int nsvg__parseColor(const char* str) -{ - size_t len = 0; - while(*str == ' ') ++str; - len = strlen(str); - if (len >= 1 && *str == '#') - return nsvg__parseColorHex(str); - else if (len >= 4 && str[0] == 'r' && str[1] == 'g' && str[2] == 'b' && str[3] == '(') - return nsvg__parseColorRGB(str); - return nsvg__parseColorName(str); -} - -static float nsvg__parseOpacity(const char* str) -{ - float val = nsvg__atof(str); - if (val < 0.0f) val = 0.0f; - if (val > 1.0f) val = 1.0f; - return val; -} - -static float nsvg__parseMiterLimit(const char* str) -{ - float val = nsvg__atof(str); - if (val < 0.0f) val = 0.0f; - return val; -} - -static int nsvg__parseUnits(const char* units) -{ - if (units[0] == 'p' && units[1] == 'x') - return NSVG_UNITS_PX; - else if (units[0] == 'p' && units[1] == 't') - return NSVG_UNITS_PT; - else if (units[0] == 'p' && units[1] == 'c') - return NSVG_UNITS_PC; - else if (units[0] == 'm' && units[1] == 'm') - return NSVG_UNITS_MM; - else if (units[0] == 'c' && units[1] == 'm') - return NSVG_UNITS_CM; - else if (units[0] == 'i' && units[1] == 'n') - return NSVG_UNITS_IN; - else if (units[0] == '%') - return NSVG_UNITS_PERCENT; - else if (units[0] == 'e' && units[1] == 'm') - return NSVG_UNITS_EM; - else if (units[0] == 'e' && units[1] == 'x') - return NSVG_UNITS_EX; - return NSVG_UNITS_USER; -} - -static int nsvg__isCoordinate(const char* s) -{ - // optional sign - if (*s == '-' || *s == '+') - s++; - // must have at least one digit, or start by a dot - return (nsvg__isdigit(*s) || *s == '.'); -} - -static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str) -{ - NSVGcoordinate coord = {0, NSVG_UNITS_USER}; - char buf[64]; - coord.units = nsvg__parseUnits(nsvg__parseNumber(str, buf, 64)); - coord.value = nsvg__atof(buf); - return coord; -} - -static NSVGcoordinate nsvg__coord(float v, int units) -{ - NSVGcoordinate coord = {v, units}; - return coord; -} - -static float nsvg__parseCoordinate(NSVGparser* p, const char* str, float orig, float length) -{ - NSVGcoordinate coord = nsvg__parseCoordinateRaw(str); - return nsvg__convertToPixels(p, coord, orig, length); -} - -static int nsvg__parseTransformArgs(const char* str, float* args, int maxNa, int* na) -{ - const char* end; - const char* ptr; - char it[64]; - - *na = 0; - ptr = str; - while (*ptr && *ptr != '(') ++ptr; - if (*ptr == 0) - return 1; - end = ptr; - while (*end && *end != ')') ++end; - if (*end == 0) - return 1; - - while (ptr < end) { - if (*ptr == '-' || *ptr == '+' || *ptr == '.' || nsvg__isdigit(*ptr)) { - if (*na >= maxNa) return 0; - ptr = nsvg__parseNumber(ptr, it, 64); - args[(*na)++] = (float)nsvg__atof(it); - } else { - ++ptr; - } - } - return (int)(end - str); -} - - -static int nsvg__parseMatrix(float* xform, const char* str) -{ - float t[6]; - int na = 0; - int len = nsvg__parseTransformArgs(str, t, 6, &na); - if (na != 6) return len; - memcpy(xform, t, sizeof(float)*6); - return len; -} - -static int nsvg__parseTranslate(float* xform, const char* str) -{ - float args[2]; - float t[6]; - int na = 0; - int len = nsvg__parseTransformArgs(str, args, 2, &na); - if (na == 1) args[1] = 0.0; - - nsvg__xformSetTranslation(t, args[0], args[1]); - memcpy(xform, t, sizeof(float)*6); - return len; -} - -static int nsvg__parseScale(float* xform, const char* str) -{ - float args[2]; - int na = 0; - float t[6]; - int len = nsvg__parseTransformArgs(str, args, 2, &na); - if (na == 1) args[1] = args[0]; - nsvg__xformSetScale(t, args[0], args[1]); - memcpy(xform, t, sizeof(float)*6); - return len; -} - -static int nsvg__parseSkewX(float* xform, const char* str) -{ - float args[1]; - int na = 0; - float t[6]; - int len = nsvg__parseTransformArgs(str, args, 1, &na); - nsvg__xformSetSkewX(t, args[0]/180.0f*NSVG_PI); - memcpy(xform, t, sizeof(float)*6); - return len; -} - -static int nsvg__parseSkewY(float* xform, const char* str) -{ - float args[1]; - int na = 0; - float t[6]; - int len = nsvg__parseTransformArgs(str, args, 1, &na); - nsvg__xformSetSkewY(t, args[0]/180.0f*NSVG_PI); - memcpy(xform, t, sizeof(float)*6); - return len; -} - -static int nsvg__parseRotate(float* xform, const char* str) -{ - float args[3]; - int na = 0; - float m[6]; - float t[6]; - int len = nsvg__parseTransformArgs(str, args, 3, &na); - if (na == 1) - args[1] = args[2] = 0.0f; - nsvg__xformIdentity(m); - - if (na > 1) { - nsvg__xformSetTranslation(t, -args[1], -args[2]); - nsvg__xformMultiply(m, t); - } - - nsvg__xformSetRotation(t, args[0]/180.0f*NSVG_PI); - nsvg__xformMultiply(m, t); - - if (na > 1) { - nsvg__xformSetTranslation(t, args[1], args[2]); - nsvg__xformMultiply(m, t); - } - - memcpy(xform, m, sizeof(float)*6); - - return len; -} - -static void nsvg__parseTransform(float* xform, const char* str) -{ - float t[6]; - int len; - nsvg__xformIdentity(xform); - while (*str) - { - if (strncmp(str, "matrix", 6) == 0) - len = nsvg__parseMatrix(t, str); - else if (strncmp(str, "translate", 9) == 0) - len = nsvg__parseTranslate(t, str); - else if (strncmp(str, "scale", 5) == 0) - len = nsvg__parseScale(t, str); - else if (strncmp(str, "rotate", 6) == 0) - len = nsvg__parseRotate(t, str); - else if (strncmp(str, "skewX", 5) == 0) - len = nsvg__parseSkewX(t, str); - else if (strncmp(str, "skewY", 5) == 0) - len = nsvg__parseSkewY(t, str); - else{ - ++str; - continue; - } - if (len != 0) { - str += len; - } else { - ++str; - continue; - } - - nsvg__xformPremultiply(xform, t); - } -} - -static void nsvg__parseUrl(char* id, const char* str) -{ - int i = 0; - str += 4; // "url("; - if (*str == '#') - str++; - while (i < 63 && *str != ')') { - id[i] = *str++; - i++; - } - id[i] = '\0'; -} - -static char nsvg__parseLineCap(const char* str) -{ - if (strcmp(str, "butt") == 0) - return NSVG_CAP_BUTT; - else if (strcmp(str, "round") == 0) - return NSVG_CAP_ROUND; - else if (strcmp(str, "square") == 0) - return NSVG_CAP_SQUARE; - // TODO: handle inherit. - return NSVG_CAP_BUTT; -} - -static char nsvg__parseLineJoin(const char* str) -{ - if (strcmp(str, "miter") == 0) - return NSVG_JOIN_MITER; - else if (strcmp(str, "round") == 0) - return NSVG_JOIN_ROUND; - else if (strcmp(str, "bevel") == 0) - return NSVG_JOIN_BEVEL; - // TODO: handle inherit. - return NSVG_JOIN_MITER; -} - -static char nsvg__parseFillRule(const char* str) -{ - if (strcmp(str, "nonzero") == 0) - return NSVG_FILLRULE_NONZERO; - else if (strcmp(str, "evenodd") == 0) - return NSVG_FILLRULE_EVENODD; - // TODO: handle inherit. - return NSVG_FILLRULE_NONZERO; -} - -static const char* nsvg__getNextDashItem(const char* s, char* it) -{ - int n = 0; - it[0] = '\0'; - // Skip white spaces and commas - while (*s && (nsvg__isspace(*s) || *s == ',')) s++; - // Advance until whitespace, comma or end. - while (*s && (!nsvg__isspace(*s) && *s != ',')) { - if (n < 63) - it[n++] = *s; - s++; - } - it[n++] = '\0'; - return s; -} - -static int nsvg__parseStrokeDashArray(NSVGparser* p, const char* str, float* strokeDashArray) -{ - char item[64]; - int count = 0, i; - float sum = 0.0f; - - // Handle "none" - if (str[0] == 'n') - return 0; - - // Parse dashes - while (*str) { - str = nsvg__getNextDashItem(str, item); - if (!*item) break; - if (count < NSVG_MAX_DASHES) - strokeDashArray[count++] = fabsf(nsvg__parseCoordinate(p, item, 0.0f, nsvg__actualLength(p))); - } - - for (i = 0; i < count; i++) - sum += strokeDashArray[i]; - if (sum <= 1e-6f) - count = 0; - - return count; -} - -static void nsvg__parseStyle(NSVGparser* p, const char* str); - -static int nsvg__parseAttr(NSVGparser* p, const char* name, const char* value) -{ - float xform[6]; - NSVGattrib* attr = nsvg__getAttr(p); - if (!attr) return 0; - - if (strcmp(name, "style") == 0) { - nsvg__parseStyle(p, value); - } else if (strcmp(name, "display") == 0) { - if (strcmp(value, "none") == 0) - attr->visible = 0; - // Don't reset ->visible on display:inline, one display:none hides the whole subtree - - } else if (strcmp(name, "fill") == 0) { - if (strcmp(value, "none") == 0) { - attr->hasFill = 0; - } else if (strncmp(value, "url(", 4) == 0) { - attr->hasFill = 2; - nsvg__parseUrl(attr->fillGradient, value); - } else { - attr->hasFill = 1; - attr->fillColor = nsvg__parseColor(value); - } - } else if (strcmp(name, "opacity") == 0) { - attr->opacity = nsvg__parseOpacity(value); - } else if (strcmp(name, "fill-opacity") == 0) { - attr->fillOpacity = nsvg__parseOpacity(value); - } else if (strcmp(name, "stroke") == 0) { - if (strcmp(value, "none") == 0) { - attr->hasStroke = 0; - } else if (strncmp(value, "url(", 4) == 0) { - attr->hasStroke = 2; - nsvg__parseUrl(attr->strokeGradient, value); - } else { - attr->hasStroke = 1; - attr->strokeColor = nsvg__parseColor(value); - } - } else if (strcmp(name, "stroke-width") == 0) { - attr->strokeWidth = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); - } else if (strcmp(name, "stroke-dasharray") == 0) { - attr->strokeDashCount = nsvg__parseStrokeDashArray(p, value, attr->strokeDashArray); - } else if (strcmp(name, "stroke-dashoffset") == 0) { - attr->strokeDashOffset = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); - } else if (strcmp(name, "stroke-opacity") == 0) { - attr->strokeOpacity = nsvg__parseOpacity(value); - } else if (strcmp(name, "stroke-linecap") == 0) { - attr->strokeLineCap = nsvg__parseLineCap(value); - } else if (strcmp(name, "stroke-linejoin") == 0) { - attr->strokeLineJoin = nsvg__parseLineJoin(value); - } else if (strcmp(name, "stroke-miterlimit") == 0) { - attr->miterLimit = nsvg__parseMiterLimit(value); - } else if (strcmp(name, "fill-rule") == 0) { - attr->fillRule = nsvg__parseFillRule(value); - } else if (strcmp(name, "font-size") == 0) { - attr->fontSize = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); - } else if (strcmp(name, "transform") == 0) { - nsvg__parseTransform(xform, value); - nsvg__xformPremultiply(attr->xform, xform); - } else if (strcmp(name, "stop-color") == 0) { - attr->stopColor = nsvg__parseColor(value); - } else if (strcmp(name, "stop-opacity") == 0) { - attr->stopOpacity = nsvg__parseOpacity(value); - } else if (strcmp(name, "offset") == 0) { - attr->stopOffset = nsvg__parseCoordinate(p, value, 0.0f, 1.0f); - } else if (strcmp(name, "id") == 0) { - strncpy(attr->id, value, 63); - attr->id[63] = '\0'; - } else { - return 0; - } - return 1; -} - -static int nsvg__parseNameValue(NSVGparser* p, const char* start, const char* end) -{ - const char* str; - const char* val; - char name[512]; - char value[512]; - int n; - - str = start; - while (str < end && *str != ':') ++str; - - val = str; - - // Right Trim - while (str > start && (*str == ':' || nsvg__isspace(*str))) --str; - ++str; - - n = (int)(str - start); - if (n > 511) n = 511; - if (n) memcpy(name, start, n); - name[n] = 0; - - while (val < end && (*val == ':' || nsvg__isspace(*val))) ++val; - - n = (int)(end - val); - if (n > 511) n = 511; - if (n) memcpy(value, val, n); - value[n] = 0; - - return nsvg__parseAttr(p, name, value); -} - -static void nsvg__parseStyle(NSVGparser* p, const char* str) -{ - const char* start; - const char* end; - - while (*str) { - // Left Trim - while(*str && nsvg__isspace(*str)) ++str; - start = str; - while(*str && *str != ';') ++str; - end = str; - - // Right Trim - while (end > start && (*end == ';' || nsvg__isspace(*end))) --end; - ++end; - - nsvg__parseNameValue(p, start, end); - if (*str) ++str; - } -} - -static void nsvg__parseAttribs(NSVGparser* p, const char** attr) -{ - int i; - for (i = 0; attr[i]; i += 2) - { - if (strcmp(attr[i], "style") == 0) - nsvg__parseStyle(p, attr[i + 1]); - else - nsvg__parseAttr(p, attr[i], attr[i + 1]); - } -} - -static int nsvg__getArgsPerElement(char cmd) -{ - switch (cmd) { - case 'v': - case 'V': - case 'h': - case 'H': - return 1; - case 'm': - case 'M': - case 'l': - case 'L': - case 't': - case 'T': - return 2; - case 'q': - case 'Q': - case 's': - case 'S': - return 4; - case 'c': - case 'C': - return 6; - case 'a': - case 'A': - return 7; - case 'z': - case 'Z': - return 0; - } - return -1; -} - -static void nsvg__pathMoveTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) -{ - if (rel) { - *cpx += args[0]; - *cpy += args[1]; - } else { - *cpx = args[0]; - *cpy = args[1]; - } - nsvg__moveTo(p, *cpx, *cpy); -} - -static void nsvg__pathLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) -{ - if (rel) { - *cpx += args[0]; - *cpy += args[1]; - } else { - *cpx = args[0]; - *cpy = args[1]; - } - nsvg__lineTo(p, *cpx, *cpy); -} - -static void nsvg__pathHLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) -{ - if (rel) - *cpx += args[0]; - else - *cpx = args[0]; - nsvg__lineTo(p, *cpx, *cpy); -} - -static void nsvg__pathVLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) -{ - if (rel) - *cpy += args[0]; - else - *cpy = args[0]; - nsvg__lineTo(p, *cpx, *cpy); -} - -static void nsvg__pathCubicBezTo(NSVGparser* p, float* cpx, float* cpy, - float* cpx2, float* cpy2, float* args, int rel) -{ - float x2, y2, cx1, cy1, cx2, cy2; - - if (rel) { - cx1 = *cpx + args[0]; - cy1 = *cpy + args[1]; - cx2 = *cpx + args[2]; - cy2 = *cpy + args[3]; - x2 = *cpx + args[4]; - y2 = *cpy + args[5]; - } else { - cx1 = args[0]; - cy1 = args[1]; - cx2 = args[2]; - cy2 = args[3]; - x2 = args[4]; - y2 = args[5]; - } - - nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); - - *cpx2 = cx2; - *cpy2 = cy2; - *cpx = x2; - *cpy = y2; -} - -static void nsvg__pathCubicBezShortTo(NSVGparser* p, float* cpx, float* cpy, - float* cpx2, float* cpy2, float* args, int rel) -{ - float x1, y1, x2, y2, cx1, cy1, cx2, cy2; - - x1 = *cpx; - y1 = *cpy; - if (rel) { - cx2 = *cpx + args[0]; - cy2 = *cpy + args[1]; - x2 = *cpx + args[2]; - y2 = *cpy + args[3]; - } else { - cx2 = args[0]; - cy2 = args[1]; - x2 = args[2]; - y2 = args[3]; - } - - cx1 = 2*x1 - *cpx2; - cy1 = 2*y1 - *cpy2; - - nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); - - *cpx2 = cx2; - *cpy2 = cy2; - *cpx = x2; - *cpy = y2; -} - -static void nsvg__pathQuadBezTo(NSVGparser* p, float* cpx, float* cpy, - float* cpx2, float* cpy2, float* args, int rel) -{ - float x1, y1, x2, y2, cx, cy; - float cx1, cy1, cx2, cy2; - - x1 = *cpx; - y1 = *cpy; - if (rel) { - cx = *cpx + args[0]; - cy = *cpy + args[1]; - x2 = *cpx + args[2]; - y2 = *cpy + args[3]; - } else { - cx = args[0]; - cy = args[1]; - x2 = args[2]; - y2 = args[3]; - } - - // Convert to cubic bezier - cx1 = x1 + 2.0f/3.0f*(cx - x1); - cy1 = y1 + 2.0f/3.0f*(cy - y1); - cx2 = x2 + 2.0f/3.0f*(cx - x2); - cy2 = y2 + 2.0f/3.0f*(cy - y2); - - nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); - - *cpx2 = cx; - *cpy2 = cy; - *cpx = x2; - *cpy = y2; -} - -static void nsvg__pathQuadBezShortTo(NSVGparser* p, float* cpx, float* cpy, - float* cpx2, float* cpy2, float* args, int rel) -{ - float x1, y1, x2, y2, cx, cy; - float cx1, cy1, cx2, cy2; - - x1 = *cpx; - y1 = *cpy; - if (rel) { - x2 = *cpx + args[0]; - y2 = *cpy + args[1]; - } else { - x2 = args[0]; - y2 = args[1]; - } - - cx = 2*x1 - *cpx2; - cy = 2*y1 - *cpy2; - - // Convert to cubix bezier - cx1 = x1 + 2.0f/3.0f*(cx - x1); - cy1 = y1 + 2.0f/3.0f*(cy - y1); - cx2 = x2 + 2.0f/3.0f*(cx - x2); - cy2 = y2 + 2.0f/3.0f*(cy - y2); - - nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); - - *cpx2 = cx; - *cpy2 = cy; - *cpx = x2; - *cpy = y2; -} - -static float nsvg__sqr(float x) { return x*x; } -static float nsvg__vmag(float x, float y) { return sqrtf(x*x + y*y); } - -static float nsvg__vecrat(float ux, float uy, float vx, float vy) -{ - return (ux*vx + uy*vy) / (nsvg__vmag(ux,uy) * nsvg__vmag(vx,vy)); -} - -static float nsvg__vecang(float ux, float uy, float vx, float vy) -{ - float r = nsvg__vecrat(ux,uy, vx,vy); - if (r < -1.0f) r = -1.0f; - if (r > 1.0f) r = 1.0f; - return ((ux*vy < uy*vx) ? -1.0f : 1.0f) * acosf(r); -} - -static void nsvg__pathArcTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) -{ - // Ported from canvg (https://code.google.com/p/canvg/) - float rx, ry, rotx; - float x1, y1, x2, y2, cx, cy, dx, dy, d; - float x1p, y1p, cxp, cyp, s, sa, sb; - float ux, uy, vx, vy, a1, da; - float x, y, tanx, tany, a, px = 0, py = 0, ptanx = 0, ptany = 0, t[6]; - float sinrx, cosrx; - int fa, fs; - int i, ndivs; - float hda, kappa; - - rx = fabsf(args[0]); // y radius - ry = fabsf(args[1]); // x radius - rotx = args[2] / 180.0f * NSVG_PI; // x rotation angle - fa = fabsf(args[3]) > 1e-6 ? 1 : 0; // Large arc - fs = fabsf(args[4]) > 1e-6 ? 1 : 0; // Sweep direction - x1 = *cpx; // start point - y1 = *cpy; - if (rel) { // end point - x2 = *cpx + args[5]; - y2 = *cpy + args[6]; - } else { - x2 = args[5]; - y2 = args[6]; - } - - dx = x1 - x2; - dy = y1 - y2; - d = sqrtf(dx*dx + dy*dy); - if (d < 1e-6f || rx < 1e-6f || ry < 1e-6f) { - // The arc degenerates to a line - nsvg__lineTo(p, x2, y2); - *cpx = x2; - *cpy = y2; - return; - } - - sinrx = sinf(rotx); - cosrx = cosf(rotx); - - // Convert to center point parameterization. - // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes - // 1) Compute x1', y1' - x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f; - y1p = -sinrx * dx / 2.0f + cosrx * dy / 2.0f; - d = nsvg__sqr(x1p)/nsvg__sqr(rx) + nsvg__sqr(y1p)/nsvg__sqr(ry); - if (d > 1) { - d = sqrtf(d); - rx *= d; - ry *= d; - } - // 2) Compute cx', cy' - s = 0.0f; - sa = nsvg__sqr(rx)*nsvg__sqr(ry) - nsvg__sqr(rx)*nsvg__sqr(y1p) - nsvg__sqr(ry)*nsvg__sqr(x1p); - sb = nsvg__sqr(rx)*nsvg__sqr(y1p) + nsvg__sqr(ry)*nsvg__sqr(x1p); - if (sa < 0.0f) sa = 0.0f; - if (sb > 0.0f) - s = sqrtf(sa / sb); - if (fa == fs) - s = -s; - cxp = s * rx * y1p / ry; - cyp = s * -ry * x1p / rx; - - // 3) Compute cx,cy from cx',cy' - cx = (x1 + x2)/2.0f + cosrx*cxp - sinrx*cyp; - cy = (y1 + y2)/2.0f + sinrx*cxp + cosrx*cyp; - - // 4) Calculate theta1, and delta theta. - ux = (x1p - cxp) / rx; - uy = (y1p - cyp) / ry; - vx = (-x1p - cxp) / rx; - vy = (-y1p - cyp) / ry; - a1 = nsvg__vecang(1.0f,0.0f, ux,uy); // Initial angle - da = nsvg__vecang(ux,uy, vx,vy); // Delta angle - -// if (vecrat(ux,uy,vx,vy) <= -1.0f) da = NSVG_PI; -// if (vecrat(ux,uy,vx,vy) >= 1.0f) da = 0; - - if (fs == 0 && da > 0) - da -= 2 * NSVG_PI; - else if (fs == 1 && da < 0) - da += 2 * NSVG_PI; - - // Approximate the arc using cubic spline segments. - t[0] = cosrx; t[1] = sinrx; - t[2] = -sinrx; t[3] = cosrx; - t[4] = cx; t[5] = cy; - - // Split arc into max 90 degree segments. - // The loop assumes an iteration per end point (including start and end), this +1. - ndivs = (int)(fabsf(da) / (NSVG_PI*0.5f) + 1.0f); - hda = (da / (float)ndivs) / 2.0f; - // Fix for ticket #179: division by 0: avoid cotangens around 0 (infinite) - if ((hda < 1e-3f) && (hda > -1e-3f)) - hda *= 0.5f; - else - hda = (1.0f - cosf(hda)) / sinf(hda); - kappa = fabsf(4.0f / 3.0f * hda); - if (da < 0.0f) - kappa = -kappa; - - for (i = 0; i <= ndivs; i++) { - a = a1 + da * ((float)i/(float)ndivs); - dx = cosf(a); - dy = sinf(a); - nsvg__xformPoint(&x, &y, dx*rx, dy*ry, t); // position - nsvg__xformVec(&tanx, &tany, -dy*rx * kappa, dx*ry * kappa, t); // tangent - if (i > 0) - nsvg__cubicBezTo(p, px+ptanx,py+ptany, x-tanx, y-tany, x, y); - px = x; - py = y; - ptanx = tanx; - ptany = tany; - } - - *cpx = x2; - *cpy = y2; -} - -static void nsvg__parsePath(NSVGparser* p, const char** attr) -{ - const char* s = NULL; - char cmd = '\0'; - float args[10]; - int nargs; - int rargs = 0; - char initPoint; - float cpx, cpy, cpx2, cpy2; - const char* tmp[4]; - char closedFlag; - int i; - char item[64]; - - for (i = 0; attr[i]; i += 2) { - if (strcmp(attr[i], "d") == 0) { - s = attr[i + 1]; - } else { - tmp[0] = attr[i]; - tmp[1] = attr[i + 1]; - tmp[2] = 0; - tmp[3] = 0; - nsvg__parseAttribs(p, tmp); - } - } - - if (s) { - nsvg__resetPath(p); - cpx = 0; cpy = 0; - cpx2 = 0; cpy2 = 0; - initPoint = 0; - closedFlag = 0; - nargs = 0; - - while (*s) { - s = nsvg__getNextPathItem(s, item); - if (!*item) break; - if (cmd != '\0' && nsvg__isCoordinate(item)) { - if (nargs < 10) - args[nargs++] = (float)nsvg__atof(item); - if (nargs >= rargs) { - switch (cmd) { - case 'm': - case 'M': - nsvg__pathMoveTo(p, &cpx, &cpy, args, cmd == 'm' ? 1 : 0); - // Moveto can be followed by multiple coordinate pairs, - // which should be treated as linetos. - cmd = (cmd == 'm') ? 'l' : 'L'; - rargs = nsvg__getArgsPerElement(cmd); - cpx2 = cpx; cpy2 = cpy; - initPoint = 1; - break; - case 'l': - case 'L': - nsvg__pathLineTo(p, &cpx, &cpy, args, cmd == 'l' ? 1 : 0); - cpx2 = cpx; cpy2 = cpy; - break; - case 'H': - case 'h': - nsvg__pathHLineTo(p, &cpx, &cpy, args, cmd == 'h' ? 1 : 0); - cpx2 = cpx; cpy2 = cpy; - break; - case 'V': - case 'v': - nsvg__pathVLineTo(p, &cpx, &cpy, args, cmd == 'v' ? 1 : 0); - cpx2 = cpx; cpy2 = cpy; - break; - case 'C': - case 'c': - nsvg__pathCubicBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'c' ? 1 : 0); - break; - case 'S': - case 's': - nsvg__pathCubicBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 's' ? 1 : 0); - break; - case 'Q': - case 'q': - nsvg__pathQuadBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'q' ? 1 : 0); - break; - case 'T': - case 't': - nsvg__pathQuadBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 't' ? 1 : 0); - break; - case 'A': - case 'a': - nsvg__pathArcTo(p, &cpx, &cpy, args, cmd == 'a' ? 1 : 0); - cpx2 = cpx; cpy2 = cpy; - break; - default: - if (nargs >= 2) { - cpx = args[nargs-2]; - cpy = args[nargs-1]; - cpx2 = cpx; cpy2 = cpy; - } - break; - } - nargs = 0; - } - } else { - cmd = item[0]; - if (cmd == 'M' || cmd == 'm') { - // Commit path. - if (p->npts > 0) - nsvg__addPath(p, closedFlag); - // Start new subpath. - nsvg__resetPath(p); - closedFlag = 0; - nargs = 0; - } else if (initPoint == 0) { - // Do not allow other commands until initial point has been set (moveTo called once). - cmd = '\0'; - } - if (cmd == 'Z' || cmd == 'z') { - closedFlag = 1; - // Commit path. - if (p->npts > 0) { - // Move current point to first point - cpx = p->pts[0]; - cpy = p->pts[1]; - cpx2 = cpx; cpy2 = cpy; - nsvg__addPath(p, closedFlag); - } - // Start new subpath. - nsvg__resetPath(p); - nsvg__moveTo(p, cpx, cpy); - closedFlag = 0; - nargs = 0; - } - rargs = nsvg__getArgsPerElement(cmd); - if (rargs == -1) { - // Command not recognized - cmd = '\0'; - rargs = 0; - } - } - } - // Commit path. - if (p->npts) - nsvg__addPath(p, closedFlag); - } - - nsvg__addShape(p); -} - -static void nsvg__parseRect(NSVGparser* p, const char** attr) -{ - float x = 0.0f; - float y = 0.0f; - float w = 0.0f; - float h = 0.0f; - float rx = -1.0f; // marks not set - float ry = -1.0f; - int i; - - for (i = 0; attr[i]; i += 2) { - if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { - if (strcmp(attr[i], "x") == 0) x = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); - if (strcmp(attr[i], "y") == 0) y = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); - if (strcmp(attr[i], "width") == 0) w = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p)); - if (strcmp(attr[i], "height") == 0) h = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p)); - if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p))); - if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p))); - } - } - - if (rx < 0.0f && ry > 0.0f) rx = ry; - if (ry < 0.0f && rx > 0.0f) ry = rx; - if (rx < 0.0f) rx = 0.0f; - if (ry < 0.0f) ry = 0.0f; - if (rx > w/2.0f) rx = w/2.0f; - if (ry > h/2.0f) ry = h/2.0f; - - if (w != 0.0f && h != 0.0f) { - nsvg__resetPath(p); - - if (rx < 0.00001f || ry < 0.0001f) { - nsvg__moveTo(p, x, y); - nsvg__lineTo(p, x+w, y); - nsvg__lineTo(p, x+w, y+h); - nsvg__lineTo(p, x, y+h); - } else { - // Rounded rectangle - nsvg__moveTo(p, x+rx, y); - nsvg__lineTo(p, x+w-rx, y); - nsvg__cubicBezTo(p, x+w-rx*(1-NSVG_KAPPA90), y, x+w, y+ry*(1-NSVG_KAPPA90), x+w, y+ry); - nsvg__lineTo(p, x+w, y+h-ry); - nsvg__cubicBezTo(p, x+w, y+h-ry*(1-NSVG_KAPPA90), x+w-rx*(1-NSVG_KAPPA90), y+h, x+w-rx, y+h); - nsvg__lineTo(p, x+rx, y+h); - nsvg__cubicBezTo(p, x+rx*(1-NSVG_KAPPA90), y+h, x, y+h-ry*(1-NSVG_KAPPA90), x, y+h-ry); - nsvg__lineTo(p, x, y+ry); - nsvg__cubicBezTo(p, x, y+ry*(1-NSVG_KAPPA90), x+rx*(1-NSVG_KAPPA90), y, x+rx, y); - } - - nsvg__addPath(p, 1); - - nsvg__addShape(p); - } -} - -static void nsvg__parseCircle(NSVGparser* p, const char** attr) -{ - float cx = 0.0f; - float cy = 0.0f; - float r = 0.0f; - int i; - - for (i = 0; attr[i]; i += 2) { - if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { - if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); - if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); - if (strcmp(attr[i], "r") == 0) r = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualLength(p))); - } - } - - if (r > 0.0f) { - nsvg__resetPath(p); - - nsvg__moveTo(p, cx+r, cy); - nsvg__cubicBezTo(p, cx+r, cy+r*NSVG_KAPPA90, cx+r*NSVG_KAPPA90, cy+r, cx, cy+r); - nsvg__cubicBezTo(p, cx-r*NSVG_KAPPA90, cy+r, cx-r, cy+r*NSVG_KAPPA90, cx-r, cy); - nsvg__cubicBezTo(p, cx-r, cy-r*NSVG_KAPPA90, cx-r*NSVG_KAPPA90, cy-r, cx, cy-r); - nsvg__cubicBezTo(p, cx+r*NSVG_KAPPA90, cy-r, cx+r, cy-r*NSVG_KAPPA90, cx+r, cy); - - nsvg__addPath(p, 1); - - nsvg__addShape(p); - } -} - -static void nsvg__parseEllipse(NSVGparser* p, const char** attr) -{ - float cx = 0.0f; - float cy = 0.0f; - float rx = 0.0f; - float ry = 0.0f; - int i; - - for (i = 0; attr[i]; i += 2) { - if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { - if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); - if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); - if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p))); - if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p))); - } - } - - if (rx > 0.0f && ry > 0.0f) { - - nsvg__resetPath(p); - - nsvg__moveTo(p, cx+rx, cy); - nsvg__cubicBezTo(p, cx+rx, cy+ry*NSVG_KAPPA90, cx+rx*NSVG_KAPPA90, cy+ry, cx, cy+ry); - nsvg__cubicBezTo(p, cx-rx*NSVG_KAPPA90, cy+ry, cx-rx, cy+ry*NSVG_KAPPA90, cx-rx, cy); - nsvg__cubicBezTo(p, cx-rx, cy-ry*NSVG_KAPPA90, cx-rx*NSVG_KAPPA90, cy-ry, cx, cy-ry); - nsvg__cubicBezTo(p, cx+rx*NSVG_KAPPA90, cy-ry, cx+rx, cy-ry*NSVG_KAPPA90, cx+rx, cy); - - nsvg__addPath(p, 1); - - nsvg__addShape(p); - } -} - -static void nsvg__parseLine(NSVGparser* p, const char** attr) -{ - float x1 = 0.0; - float y1 = 0.0; - float x2 = 0.0; - float y2 = 0.0; - int i; - - for (i = 0; attr[i]; i += 2) { - if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { - if (strcmp(attr[i], "x1") == 0) x1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); - if (strcmp(attr[i], "y1") == 0) y1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); - if (strcmp(attr[i], "x2") == 0) x2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); - if (strcmp(attr[i], "y2") == 0) y2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); - } - } - - nsvg__resetPath(p); - - nsvg__moveTo(p, x1, y1); - nsvg__lineTo(p, x2, y2); - - nsvg__addPath(p, 0); - - nsvg__addShape(p); -} - -static void nsvg__parsePoly(NSVGparser* p, const char** attr, int closeFlag) -{ - int i; - const char* s; - float args[2]; - int nargs, npts = 0; - char item[64]; - - nsvg__resetPath(p); - - for (i = 0; attr[i]; i += 2) { - if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { - if (strcmp(attr[i], "points") == 0) { - s = attr[i + 1]; - nargs = 0; - while (*s) { - s = nsvg__getNextPathItem(s, item); - args[nargs++] = (float)nsvg__atof(item); - if (nargs >= 2) { - if (npts == 0) - nsvg__moveTo(p, args[0], args[1]); - else - nsvg__lineTo(p, args[0], args[1]); - nargs = 0; - npts++; - } - } - } - } - } - - nsvg__addPath(p, (char)closeFlag); - - nsvg__addShape(p); -} - -static void nsvg__parseSVG(NSVGparser* p, const char** attr) -{ - int i; - for (i = 0; attr[i]; i += 2) { - if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { - if (strcmp(attr[i], "width") == 0) { - p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f); - } else if (strcmp(attr[i], "height") == 0) { - p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f); - } else if (strcmp(attr[i], "viewBox") == 0) { - const char *s = attr[i + 1]; - char buf[64]; - s = nsvg__parseNumber(s, buf, 64); - p->viewMinx = nsvg__atof(buf); - while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) s++; - if (!*s) return; - s = nsvg__parseNumber(s, buf, 64); - p->viewMiny = nsvg__atof(buf); - while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) s++; - if (!*s) return; - s = nsvg__parseNumber(s, buf, 64); - p->viewWidth = nsvg__atof(buf); - while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) s++; - if (!*s) return; - s = nsvg__parseNumber(s, buf, 64); - p->viewHeight = nsvg__atof(buf); - } else if (strcmp(attr[i], "preserveAspectRatio") == 0) { - if (strstr(attr[i + 1], "none") != 0) { - // No uniform scaling - p->alignType = NSVG_ALIGN_NONE; - } else { - // Parse X align - if (strstr(attr[i + 1], "xMin") != 0) - p->alignX = NSVG_ALIGN_MIN; - else if (strstr(attr[i + 1], "xMid") != 0) - p->alignX = NSVG_ALIGN_MID; - else if (strstr(attr[i + 1], "xMax") != 0) - p->alignX = NSVG_ALIGN_MAX; - // Parse X align - if (strstr(attr[i + 1], "yMin") != 0) - p->alignY = NSVG_ALIGN_MIN; - else if (strstr(attr[i + 1], "yMid") != 0) - p->alignY = NSVG_ALIGN_MID; - else if (strstr(attr[i + 1], "yMax") != 0) - p->alignY = NSVG_ALIGN_MAX; - // Parse meet/slice - p->alignType = NSVG_ALIGN_MEET; - if (strstr(attr[i + 1], "slice") != 0) - p->alignType = NSVG_ALIGN_SLICE; - } - } - } - } -} - -static void nsvg__parseGradient(NSVGparser* p, const char** attr, char type) -{ - int i; - NSVGgradientData* grad = (NSVGgradientData*)malloc(sizeof(NSVGgradientData)); - if (grad == NULL) return; - memset(grad, 0, sizeof(NSVGgradientData)); - grad->units = NSVG_OBJECT_SPACE; - grad->type = type; - if (grad->type == NSVG_PAINT_LINEAR_GRADIENT) { - grad->linear.x1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); - grad->linear.y1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); - grad->linear.x2 = nsvg__coord(100.0f, NSVG_UNITS_PERCENT); - grad->linear.y2 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); - } else if (grad->type == NSVG_PAINT_RADIAL_GRADIENT) { - grad->radial.cx = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); - grad->radial.cy = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); - grad->radial.r = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); - } - - nsvg__xformIdentity(grad->xform); - - for (i = 0; attr[i]; i += 2) { - if (strcmp(attr[i], "id") == 0) { - strncpy(grad->id, attr[i+1], 63); - grad->id[63] = '\0'; - } else if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { - if (strcmp(attr[i], "gradientUnits") == 0) { - if (strcmp(attr[i+1], "objectBoundingBox") == 0) - grad->units = NSVG_OBJECT_SPACE; - else - grad->units = NSVG_USER_SPACE; - } else if (strcmp(attr[i], "gradientTransform") == 0) { - nsvg__parseTransform(grad->xform, attr[i + 1]); - } else if (strcmp(attr[i], "cx") == 0) { - grad->radial.cx = nsvg__parseCoordinateRaw(attr[i + 1]); - } else if (strcmp(attr[i], "cy") == 0) { - grad->radial.cy = nsvg__parseCoordinateRaw(attr[i + 1]); - } else if (strcmp(attr[i], "r") == 0) { - grad->radial.r = nsvg__parseCoordinateRaw(attr[i + 1]); - } else if (strcmp(attr[i], "fx") == 0) { - grad->radial.fx = nsvg__parseCoordinateRaw(attr[i + 1]); - } else if (strcmp(attr[i], "fy") == 0) { - grad->radial.fy = nsvg__parseCoordinateRaw(attr[i + 1]); - } else if (strcmp(attr[i], "x1") == 0) { - grad->linear.x1 = nsvg__parseCoordinateRaw(attr[i + 1]); - } else if (strcmp(attr[i], "y1") == 0) { - grad->linear.y1 = nsvg__parseCoordinateRaw(attr[i + 1]); - } else if (strcmp(attr[i], "x2") == 0) { - grad->linear.x2 = nsvg__parseCoordinateRaw(attr[i + 1]); - } else if (strcmp(attr[i], "y2") == 0) { - grad->linear.y2 = nsvg__parseCoordinateRaw(attr[i + 1]); - } else if (strcmp(attr[i], "spreadMethod") == 0) { - if (strcmp(attr[i+1], "pad") == 0) - grad->spread = NSVG_SPREAD_PAD; - else if (strcmp(attr[i+1], "reflect") == 0) - grad->spread = NSVG_SPREAD_REFLECT; - else if (strcmp(attr[i+1], "repeat") == 0) - grad->spread = NSVG_SPREAD_REPEAT; - } else if (strcmp(attr[i], "xlink:href") == 0) { - const char *href = attr[i+1]; - strncpy(grad->ref, href+1, 62); - grad->ref[62] = '\0'; - } - } - } - - grad->next = p->gradients; - p->gradients = grad; -} - -static void nsvg__parseGradientStop(NSVGparser* p, const char** attr) -{ - NSVGattrib* curAttr = nsvg__getAttr(p); - NSVGgradientData* grad; - NSVGgradientStop* stop; - int i, idx; - - curAttr->stopOffset = 0; - curAttr->stopColor = 0; - curAttr->stopOpacity = 1.0f; - - for (i = 0; attr[i]; i += 2) { - nsvg__parseAttr(p, attr[i], attr[i + 1]); - } - - // Add stop to the last gradient. - grad = p->gradients; - if (grad == NULL) return; - - grad->nstops++; - grad->stops = (NSVGgradientStop*)realloc(grad->stops, sizeof(NSVGgradientStop)*grad->nstops); - if (grad->stops == NULL) return; - - // Insert - idx = grad->nstops-1; - for (i = 0; i < grad->nstops-1; i++) { - if (curAttr->stopOffset < grad->stops[i].offset) { - idx = i; - break; - } - } - if (idx != grad->nstops-1) { - for (i = grad->nstops-1; i > idx; i--) - grad->stops[i] = grad->stops[i-1]; - } - - stop = &grad->stops[idx]; - stop->color = curAttr->stopColor; - stop->color |= (unsigned int)(curAttr->stopOpacity*255) << 24; - stop->offset = curAttr->stopOffset; -} - -static void nsvg__startElement(void* ud, const char* el, const char** attr) -{ - NSVGparser* p = (NSVGparser*)ud; - - if (p->defsFlag) { - // Skip everything but gradients in defs - if (strcmp(el, "linearGradient") == 0) { - nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT); - } else if (strcmp(el, "radialGradient") == 0) { - nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT); - } else if (strcmp(el, "stop") == 0) { - nsvg__parseGradientStop(p, attr); - } - return; - } - - if (strcmp(el, "g") == 0) { - nsvg__pushAttr(p); - nsvg__parseAttribs(p, attr); - } else if (strcmp(el, "path") == 0) { - if (p->pathFlag) // Do not allow nested paths. - return; - nsvg__pushAttr(p); - nsvg__parsePath(p, attr); - nsvg__popAttr(p); - } else if (strcmp(el, "rect") == 0) { - nsvg__pushAttr(p); - nsvg__parseRect(p, attr); - nsvg__popAttr(p); - } else if (strcmp(el, "circle") == 0) { - nsvg__pushAttr(p); - nsvg__parseCircle(p, attr); - nsvg__popAttr(p); - } else if (strcmp(el, "ellipse") == 0) { - nsvg__pushAttr(p); - nsvg__parseEllipse(p, attr); - nsvg__popAttr(p); - } else if (strcmp(el, "line") == 0) { - nsvg__pushAttr(p); - nsvg__parseLine(p, attr); - nsvg__popAttr(p); - } else if (strcmp(el, "polyline") == 0) { - nsvg__pushAttr(p); - nsvg__parsePoly(p, attr, 0); - nsvg__popAttr(p); - } else if (strcmp(el, "polygon") == 0) { - nsvg__pushAttr(p); - nsvg__parsePoly(p, attr, 1); - nsvg__popAttr(p); - } else if (strcmp(el, "linearGradient") == 0) { - nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT); - } else if (strcmp(el, "radialGradient") == 0) { - nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT); - } else if (strcmp(el, "stop") == 0) { - nsvg__parseGradientStop(p, attr); - } else if (strcmp(el, "defs") == 0) { - p->defsFlag = 1; - } else if (strcmp(el, "svg") == 0) { - nsvg__parseSVG(p, attr); - } -} - -static void nsvg__endElement(void* ud, const char* el) -{ - NSVGparser* p = (NSVGparser*)ud; - - if (strcmp(el, "g") == 0) { - nsvg__popAttr(p); - } else if (strcmp(el, "path") == 0) { - p->pathFlag = 0; - } else if (strcmp(el, "defs") == 0) { - p->defsFlag = 0; - } -} - -static void nsvg__content(void* ud, const char* s) -{ - NSVG_NOTUSED(ud); - NSVG_NOTUSED(s); - // empty -} - -static void nsvg__imageBounds(NSVGparser* p, float* bounds) -{ - NSVGshape* shape; - shape = p->image->shapes; - if (shape == NULL) { - bounds[0] = bounds[1] = bounds[2] = bounds[3] = 0.0; - return; - } - bounds[0] = shape->bounds[0]; - bounds[1] = shape->bounds[1]; - bounds[2] = shape->bounds[2]; - bounds[3] = shape->bounds[3]; - for (shape = shape->next; shape != NULL; shape = shape->next) { - bounds[0] = nsvg__minf(bounds[0], shape->bounds[0]); - bounds[1] = nsvg__minf(bounds[1], shape->bounds[1]); - bounds[2] = nsvg__maxf(bounds[2], shape->bounds[2]); - bounds[3] = nsvg__maxf(bounds[3], shape->bounds[3]); - } -} - -static float nsvg__viewAlign(float content, float container, int type) -{ - if (type == NSVG_ALIGN_MIN) - return 0; - else if (type == NSVG_ALIGN_MAX) - return container - content; - // mid - return (container - content) * 0.5f; -} - -static void nsvg__scaleGradient(NSVGgradient* grad, float tx, float ty, float sx, float sy) -{ - float t[6]; - nsvg__xformSetTranslation(t, tx, ty); - nsvg__xformMultiply (grad->xform, t); - - nsvg__xformSetScale(t, sx, sy); - nsvg__xformMultiply (grad->xform, t); -} - -static void nsvg__scaleToViewbox(NSVGparser* p, const char* units) -{ - NSVGshape* shape; - NSVGpath* path; - float tx, ty, sx, sy, us, bounds[4], t[6], avgs; - int i; - float* pt; - - // Guess image size if not set completely. - nsvg__imageBounds(p, bounds); - - if (p->viewWidth == 0) { - if (p->image->width > 0) { - p->viewWidth = p->image->width; - } else { - p->viewMinx = bounds[0]; - p->viewWidth = bounds[2] - bounds[0]; - } - } - if (p->viewHeight == 0) { - if (p->image->height > 0) { - p->viewHeight = p->image->height; - } else { - p->viewMiny = bounds[1]; - p->viewHeight = bounds[3] - bounds[1]; - } - } - if (p->image->width == 0) - p->image->width = p->viewWidth; - if (p->image->height == 0) - p->image->height = p->viewHeight; - - tx = -p->viewMinx; - ty = -p->viewMiny; - sx = p->viewWidth > 0 ? p->image->width / p->viewWidth : 0; - sy = p->viewHeight > 0 ? p->image->height / p->viewHeight : 0; - // Unit scaling - us = 1.0f / nsvg__convertToPixels(p, nsvg__coord(1.0f, nsvg__parseUnits(units)), 0.0f, 1.0f); - - // Fix aspect ratio - if (p->alignType == NSVG_ALIGN_MEET) { - // fit whole image into viewbox - sx = sy = nsvg__minf(sx, sy); - tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx; - ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy; - } else if (p->alignType == NSVG_ALIGN_SLICE) { - // fill whole viewbox with image - sx = sy = nsvg__maxf(sx, sy); - tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx; - ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy; - } - - // Transform - sx *= us; - sy *= us; - avgs = (sx+sy) / 2.0f; - for (shape = p->image->shapes; shape != NULL; shape = shape->next) { - shape->bounds[0] = (shape->bounds[0] + tx) * sx; - shape->bounds[1] = (shape->bounds[1] + ty) * sy; - shape->bounds[2] = (shape->bounds[2] + tx) * sx; - shape->bounds[3] = (shape->bounds[3] + ty) * sy; - for (path = shape->paths; path != NULL; path = path->next) { - path->bounds[0] = (path->bounds[0] + tx) * sx; - path->bounds[1] = (path->bounds[1] + ty) * sy; - path->bounds[2] = (path->bounds[2] + tx) * sx; - path->bounds[3] = (path->bounds[3] + ty) * sy; - for (i =0; i < path->npts; i++) { - pt = &path->pts[i*2]; - pt[0] = (pt[0] + tx) * sx; - pt[1] = (pt[1] + ty) * sy; - } - } - - if (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT || shape->fill.type == NSVG_PAINT_RADIAL_GRADIENT) { - nsvg__scaleGradient(shape->fill.gradient, tx,ty, sx,sy); - memcpy(t, shape->fill.gradient->xform, sizeof(float)*6); - nsvg__xformInverse(shape->fill.gradient->xform, t); - } - if (shape->stroke.type == NSVG_PAINT_LINEAR_GRADIENT || shape->stroke.type == NSVG_PAINT_RADIAL_GRADIENT) { - nsvg__scaleGradient(shape->stroke.gradient, tx,ty, sx,sy); - memcpy(t, shape->stroke.gradient->xform, sizeof(float)*6); - nsvg__xformInverse(shape->stroke.gradient->xform, t); - } - - shape->strokeWidth *= avgs; - shape->strokeDashOffset *= avgs; - for (i = 0; i < shape->strokeDashCount; i++) - shape->strokeDashArray[i] *= avgs; - } -} - -NSVGimage* nsvgParse(char* input, const char* units, float dpi) -{ - NSVGparser* p; - NSVGimage* ret = 0; - - p = nsvg__createParser(); - if (p == NULL) { - return NULL; - } - p->dpi = dpi; - - nsvg__parseXML(input, nsvg__startElement, nsvg__endElement, nsvg__content, p); - - // Scale to viewBox - nsvg__scaleToViewbox(p, units); - - ret = p->image; - p->image = NULL; - - nsvg__deleteParser(p); - - return ret; -} - -NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi) -{ - FILE* fp = NULL; - size_t size; - char* data = NULL; - NSVGimage* image = NULL; - - fp = fopen(filename, "rb"); - if (!fp) goto error; - fseek(fp, 0, SEEK_END); - size = ftell(fp); - fseek(fp, 0, SEEK_SET); - data = (char*)malloc(size+1); - if (data == NULL) goto error; - if (fread(data, 1, size, fp) != size) goto error; - data[size] = '\0'; // Must be null terminated. - fclose(fp); - image = nsvgParse(data, units, dpi); - free(data); - - return image; - -error: - if (fp) fclose(fp); - if (data) free(data); - if (image) nsvgDelete(image); - return NULL; -} - -NSVGpath* nsvgDuplicatePath(NSVGpath* p) -{ - NSVGpath* res = NULL; - - if (p == NULL) - return NULL; - - res = (NSVGpath*)malloc(sizeof(NSVGpath)); - if (res == NULL) goto error; - memset(res, 0, sizeof(NSVGpath)); - - res->pts = (float*)malloc(p->npts*2*sizeof(float)); - if (res->pts == NULL) goto error; - memcpy(res->pts, p->pts, p->npts * sizeof(float) * 2); - res->npts = p->npts; - - memcpy(res->bounds, p->bounds, sizeof(p->bounds)); - - res->closed = p->closed; - - return res; - -error: - if (res != NULL) { - free(res->pts); - free(res); - } - return NULL; -} - -void nsvgDelete(NSVGimage* image) -{ - NSVGshape *snext, *shape; - if (image == NULL) return; - shape = image->shapes; - while (shape != NULL) { - snext = shape->next; - nsvg__deletePaths(shape->paths); - nsvg__deletePaint(&shape->fill); - nsvg__deletePaint(&shape->stroke); - free(shape); - shape = snext; - } - free(image); -} - -#endif diff --git a/thirdparty/nanosvg/nanosvgrast.h b/thirdparty/nanosvg/nanosvgrast.h deleted file mode 100644 index b740c316ca..0000000000 --- a/thirdparty/nanosvg/nanosvgrast.h +++ /dev/null @@ -1,1452 +0,0 @@ -/* - * Copyright (c) 2013-14 Mikko Mononen memon@inside.org - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * The polygon rasterization is heavily based on stb_truetype rasterizer - * by Sean Barrett - http://nothings.org/ - * - */ - -#ifndef NANOSVGRAST_H -#define NANOSVGRAST_H - -#ifndef NANOSVGRAST_CPLUSPLUS -#ifdef __cplusplus -extern "C" { -#endif -#endif - -typedef struct NSVGrasterizer NSVGrasterizer; - -/* Example Usage: - // Load SVG - NSVGimage* image; - image = nsvgParseFromFile("test.svg", "px", 96); - - // Create rasterizer (can be used to render multiple images). - struct NSVGrasterizer* rast = nsvgCreateRasterizer(); - // Allocate memory for image - unsigned char* img = malloc(w*h*4); - // Rasterize - nsvgRasterize(rast, image, 0,0,1, img, w, h, w*4); -*/ - -// Allocated rasterizer context. -NSVGrasterizer* nsvgCreateRasterizer(); - -// Rasterizes SVG image, returns RGBA image (non-premultiplied alpha) -// r - pointer to rasterizer context -// image - pointer to image to rasterize -// tx,ty - image offset (applied after scaling) -// scale - image scale -// dst - pointer to destination image data, 4 bytes per pixel (RGBA) -// w - width of the image to render -// h - height of the image to render -// stride - number of bytes per scaleline in the destination buffer -void nsvgRasterize(NSVGrasterizer* r, - NSVGimage* image, float tx, float ty, float scale, - unsigned char* dst, int w, int h, int stride); - -// Deletes rasterizer context. -void nsvgDeleteRasterizer(NSVGrasterizer*); - - -#ifndef NANOSVGRAST_CPLUSPLUS -#ifdef __cplusplus -} -#endif -#endif - -#endif // NANOSVGRAST_H - -#ifdef NANOSVGRAST_IMPLEMENTATION - -#include <math.h> - -#define NSVG__SUBSAMPLES 5 -#define NSVG__FIXSHIFT 10 -#define NSVG__FIX (1 << NSVG__FIXSHIFT) -#define NSVG__FIXMASK (NSVG__FIX-1) -#define NSVG__MEMPAGE_SIZE 1024 - -typedef struct NSVGedge { - float x0,y0, x1,y1; - int dir; - struct NSVGedge* next; -} NSVGedge; - -typedef struct NSVGpoint { - float x, y; - float dx, dy; - float len; - float dmx, dmy; - unsigned char flags; -} NSVGpoint; - -typedef struct NSVGactiveEdge { - int x,dx; - float ey; - int dir; - struct NSVGactiveEdge *next; -} NSVGactiveEdge; - -typedef struct NSVGmemPage { - unsigned char mem[NSVG__MEMPAGE_SIZE]; - int size; - struct NSVGmemPage* next; -} NSVGmemPage; - -typedef struct NSVGcachedPaint { - char type; - char spread; - float xform[6]; - unsigned int colors[256]; -} NSVGcachedPaint; - -struct NSVGrasterizer -{ - float px, py; - - float tessTol; - float distTol; - - NSVGedge* edges; - int nedges; - int cedges; - - NSVGpoint* points; - int npoints; - int cpoints; - - NSVGpoint* points2; - int npoints2; - int cpoints2; - - NSVGactiveEdge* freelist; - NSVGmemPage* pages; - NSVGmemPage* curpage; - - unsigned char* scanline; - int cscanline; - - unsigned char* bitmap; - int width, height, stride; -}; - -NSVGrasterizer* nsvgCreateRasterizer() -{ - NSVGrasterizer* r = (NSVGrasterizer*)malloc(sizeof(NSVGrasterizer)); - if (r == NULL) goto error; - memset(r, 0, sizeof(NSVGrasterizer)); - - r->tessTol = 0.25f; - r->distTol = 0.01f; - - return r; - -error: - nsvgDeleteRasterizer(r); - return NULL; -} - -void nsvgDeleteRasterizer(NSVGrasterizer* r) -{ - NSVGmemPage* p; - - if (r == NULL) return; - - p = r->pages; - while (p != NULL) { - NSVGmemPage* next = p->next; - free(p); - p = next; - } - - if (r->edges) free(r->edges); - if (r->points) free(r->points); - if (r->points2) free(r->points2); - if (r->scanline) free(r->scanline); - - free(r); -} - -static NSVGmemPage* nsvg__nextPage(NSVGrasterizer* r, NSVGmemPage* cur) -{ - NSVGmemPage *newp; - - // If using existing chain, return the next page in chain - if (cur != NULL && cur->next != NULL) { - return cur->next; - } - - // Alloc new page - newp = (NSVGmemPage*)malloc(sizeof(NSVGmemPage)); - if (newp == NULL) return NULL; - memset(newp, 0, sizeof(NSVGmemPage)); - - // Add to linked list - if (cur != NULL) - cur->next = newp; - else - r->pages = newp; - - return newp; -} - -static void nsvg__resetPool(NSVGrasterizer* r) -{ - NSVGmemPage* p = r->pages; - while (p != NULL) { - p->size = 0; - p = p->next; - } - r->curpage = r->pages; -} - -static unsigned char* nsvg__alloc(NSVGrasterizer* r, int size) -{ - unsigned char* buf; - if (size > NSVG__MEMPAGE_SIZE) return NULL; - if (r->curpage == NULL || r->curpage->size+size > NSVG__MEMPAGE_SIZE) { - r->curpage = nsvg__nextPage(r, r->curpage); - } - buf = &r->curpage->mem[r->curpage->size]; - r->curpage->size += size; - return buf; -} - -static int nsvg__ptEquals(float x1, float y1, float x2, float y2, float tol) -{ - float dx = x2 - x1; - float dy = y2 - y1; - return dx*dx + dy*dy < tol*tol; -} - -static void nsvg__addPathPoint(NSVGrasterizer* r, float x, float y, int flags) -{ - NSVGpoint* pt; - - if (r->npoints > 0) { - pt = &r->points[r->npoints-1]; - if (nsvg__ptEquals(pt->x,pt->y, x,y, r->distTol)) { - pt->flags = (unsigned char)(pt->flags | flags); - return; - } - } - - if (r->npoints+1 > r->cpoints) { - r->cpoints = r->cpoints > 0 ? r->cpoints * 2 : 64; - r->points = (NSVGpoint*)realloc(r->points, sizeof(NSVGpoint) * r->cpoints); - if (r->points == NULL) return; - } - - pt = &r->points[r->npoints]; - pt->x = x; - pt->y = y; - pt->flags = (unsigned char)flags; - r->npoints++; -} - -static void nsvg__appendPathPoint(NSVGrasterizer* r, NSVGpoint pt) -{ - if (r->npoints+1 > r->cpoints) { - r->cpoints = r->cpoints > 0 ? r->cpoints * 2 : 64; - r->points = (NSVGpoint*)realloc(r->points, sizeof(NSVGpoint) * r->cpoints); - if (r->points == NULL) return; - } - r->points[r->npoints] = pt; - r->npoints++; -} - -static void nsvg__duplicatePoints(NSVGrasterizer* r) -{ - if (r->npoints > r->cpoints2) { - r->cpoints2 = r->npoints; - r->points2 = (NSVGpoint*)realloc(r->points2, sizeof(NSVGpoint) * r->cpoints2); - if (r->points2 == NULL) return; - } - - memcpy(r->points2, r->points, sizeof(NSVGpoint) * r->npoints); - r->npoints2 = r->npoints; -} - -static void nsvg__addEdge(NSVGrasterizer* r, float x0, float y0, float x1, float y1) -{ - NSVGedge* e; - - // Skip horizontal edges - if (y0 == y1) - return; - - if (r->nedges+1 > r->cedges) { - r->cedges = r->cedges > 0 ? r->cedges * 2 : 64; - r->edges = (NSVGedge*)realloc(r->edges, sizeof(NSVGedge) * r->cedges); - if (r->edges == NULL) return; - } - - e = &r->edges[r->nedges]; - r->nedges++; - - if (y0 < y1) { - e->x0 = x0; - e->y0 = y0; - e->x1 = x1; - e->y1 = y1; - e->dir = 1; - } else { - e->x0 = x1; - e->y0 = y1; - e->x1 = x0; - e->y1 = y0; - e->dir = -1; - } -} - -static float nsvg__normalize(float *x, float* y) -{ - float d = sqrtf((*x)*(*x) + (*y)*(*y)); - if (d > 1e-6f) { - float id = 1.0f / d; - *x *= id; - *y *= id; - } - return d; -} - -static float nsvg__absf(float x) { return x < 0 ? -x : x; } - -static void nsvg__flattenCubicBez(NSVGrasterizer* r, - float x1, float y1, float x2, float y2, - float x3, float y3, float x4, float y4, - int level, int type) -{ - float x12,y12,x23,y23,x34,y34,x123,y123,x234,y234,x1234,y1234; - float dx,dy,d2,d3; - - if (level > 10) return; - - x12 = (x1+x2)*0.5f; - y12 = (y1+y2)*0.5f; - x23 = (x2+x3)*0.5f; - y23 = (y2+y3)*0.5f; - x34 = (x3+x4)*0.5f; - y34 = (y3+y4)*0.5f; - x123 = (x12+x23)*0.5f; - y123 = (y12+y23)*0.5f; - - dx = x4 - x1; - dy = y4 - y1; - d2 = nsvg__absf(((x2 - x4) * dy - (y2 - y4) * dx)); - d3 = nsvg__absf(((x3 - x4) * dy - (y3 - y4) * dx)); - - if ((d2 + d3)*(d2 + d3) < r->tessTol * (dx*dx + dy*dy)) { - nsvg__addPathPoint(r, x4, y4, type); - return; - } - - x234 = (x23+x34)*0.5f; - y234 = (y23+y34)*0.5f; - x1234 = (x123+x234)*0.5f; - y1234 = (y123+y234)*0.5f; - - nsvg__flattenCubicBez(r, x1,y1, x12,y12, x123,y123, x1234,y1234, level+1, 0); - nsvg__flattenCubicBez(r, x1234,y1234, x234,y234, x34,y34, x4,y4, level+1, type); -} - -static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scale) -{ - int i, j; - NSVGpath* path; - - for (path = shape->paths; path != NULL; path = path->next) { - r->npoints = 0; - // Flatten path - nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0); - for (i = 0; i < path->npts-1; i += 3) { - float* p = &path->pts[i*2]; - nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, 0); - } - // Close path - nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0); - // Build edges - for (i = 0, j = r->npoints-1; i < r->npoints; j = i++) - nsvg__addEdge(r, r->points[j].x, r->points[j].y, r->points[i].x, r->points[i].y); - } -} - -enum NSVGpointFlags -{ - NSVG_PT_CORNER = 0x01, - NSVG_PT_BEVEL = 0x02, - NSVG_PT_LEFT = 0x04 -}; - -static void nsvg__initClosed(NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth) -{ - float w = lineWidth * 0.5f; - float dx = p1->x - p0->x; - float dy = p1->y - p0->y; - float len = nsvg__normalize(&dx, &dy); - float px = p0->x + dx*len*0.5f, py = p0->y + dy*len*0.5f; - float dlx = dy, dly = -dx; - float lx = px - dlx*w, ly = py - dly*w; - float rx = px + dlx*w, ry = py + dly*w; - left->x = lx; left->y = ly; - right->x = rx; right->y = ry; -} - -static void nsvg__buttCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int connect) -{ - float w = lineWidth * 0.5f; - float px = p->x, py = p->y; - float dlx = dy, dly = -dx; - float lx = px - dlx*w, ly = py - dly*w; - float rx = px + dlx*w, ry = py + dly*w; - - nsvg__addEdge(r, lx, ly, rx, ry); - - if (connect) { - nsvg__addEdge(r, left->x, left->y, lx, ly); - nsvg__addEdge(r, rx, ry, right->x, right->y); - } - left->x = lx; left->y = ly; - right->x = rx; right->y = ry; -} - -static void nsvg__squareCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int connect) -{ - float w = lineWidth * 0.5f; - float px = p->x - dx*w, py = p->y - dy*w; - float dlx = dy, dly = -dx; - float lx = px - dlx*w, ly = py - dly*w; - float rx = px + dlx*w, ry = py + dly*w; - - nsvg__addEdge(r, lx, ly, rx, ry); - - if (connect) { - nsvg__addEdge(r, left->x, left->y, lx, ly); - nsvg__addEdge(r, rx, ry, right->x, right->y); - } - left->x = lx; left->y = ly; - right->x = rx; right->y = ry; -} - -#ifndef NSVG_PI -#define NSVG_PI (3.14159265358979323846264338327f) -#endif - -static void nsvg__roundCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int ncap, int connect) -{ - int i; - float w = lineWidth * 0.5f; - float px = p->x, py = p->y; - float dlx = dy, dly = -dx; - float lx = 0, ly = 0, rx = 0, ry = 0, prevx = 0, prevy = 0; - - for (i = 0; i < ncap; i++) { - float a = (float)i/(float)(ncap-1)*NSVG_PI; - float ax = cosf(a) * w, ay = sinf(a) * w; - float x = px - dlx*ax - dx*ay; - float y = py - dly*ax - dy*ay; - - if (i > 0) - nsvg__addEdge(r, prevx, prevy, x, y); - - prevx = x; - prevy = y; - - if (i == 0) { - lx = x; ly = y; - } else if (i == ncap-1) { - rx = x; ry = y; - } - } - - if (connect) { - nsvg__addEdge(r, left->x, left->y, lx, ly); - nsvg__addEdge(r, rx, ry, right->x, right->y); - } - - left->x = lx; left->y = ly; - right->x = rx; right->y = ry; -} - -static void nsvg__bevelJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth) -{ - float w = lineWidth * 0.5f; - float dlx0 = p0->dy, dly0 = -p0->dx; - float dlx1 = p1->dy, dly1 = -p1->dx; - float lx0 = p1->x - (dlx0 * w), ly0 = p1->y - (dly0 * w); - float rx0 = p1->x + (dlx0 * w), ry0 = p1->y + (dly0 * w); - float lx1 = p1->x - (dlx1 * w), ly1 = p1->y - (dly1 * w); - float rx1 = p1->x + (dlx1 * w), ry1 = p1->y + (dly1 * w); - - nsvg__addEdge(r, lx0, ly0, left->x, left->y); - nsvg__addEdge(r, lx1, ly1, lx0, ly0); - - nsvg__addEdge(r, right->x, right->y, rx0, ry0); - nsvg__addEdge(r, rx0, ry0, rx1, ry1); - - left->x = lx1; left->y = ly1; - right->x = rx1; right->y = ry1; -} - -static void nsvg__miterJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth) -{ - float w = lineWidth * 0.5f; - float dlx0 = p0->dy, dly0 = -p0->dx; - float dlx1 = p1->dy, dly1 = -p1->dx; - float lx0, rx0, lx1, rx1; - float ly0, ry0, ly1, ry1; - - if (p1->flags & NSVG_PT_LEFT) { - lx0 = lx1 = p1->x - p1->dmx * w; - ly0 = ly1 = p1->y - p1->dmy * w; - nsvg__addEdge(r, lx1, ly1, left->x, left->y); - - rx0 = p1->x + (dlx0 * w); - ry0 = p1->y + (dly0 * w); - rx1 = p1->x + (dlx1 * w); - ry1 = p1->y + (dly1 * w); - nsvg__addEdge(r, right->x, right->y, rx0, ry0); - nsvg__addEdge(r, rx0, ry0, rx1, ry1); - } else { - lx0 = p1->x - (dlx0 * w); - ly0 = p1->y - (dly0 * w); - lx1 = p1->x - (dlx1 * w); - ly1 = p1->y - (dly1 * w); - nsvg__addEdge(r, lx0, ly0, left->x, left->y); - nsvg__addEdge(r, lx1, ly1, lx0, ly0); - - rx0 = rx1 = p1->x + p1->dmx * w; - ry0 = ry1 = p1->y + p1->dmy * w; - nsvg__addEdge(r, right->x, right->y, rx1, ry1); - } - - left->x = lx1; left->y = ly1; - right->x = rx1; right->y = ry1; -} - -static void nsvg__roundJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth, int ncap) -{ - int i, n; - float w = lineWidth * 0.5f; - float dlx0 = p0->dy, dly0 = -p0->dx; - float dlx1 = p1->dy, dly1 = -p1->dx; - float a0 = atan2f(dly0, dlx0); - float a1 = atan2f(dly1, dlx1); - float da = a1 - a0; - float lx, ly, rx, ry; - - if (da < NSVG_PI) da += NSVG_PI*2; - if (da > NSVG_PI) da -= NSVG_PI*2; - - n = (int)ceilf((nsvg__absf(da) / NSVG_PI) * (float)ncap); - if (n < 2) n = 2; - if (n > ncap) n = ncap; - - lx = left->x; - ly = left->y; - rx = right->x; - ry = right->y; - - for (i = 0; i < n; i++) { - float u = (float)i/(float)(n-1); - float a = a0 + u*da; - float ax = cosf(a) * w, ay = sinf(a) * w; - float lx1 = p1->x - ax, ly1 = p1->y - ay; - float rx1 = p1->x + ax, ry1 = p1->y + ay; - - nsvg__addEdge(r, lx1, ly1, lx, ly); - nsvg__addEdge(r, rx, ry, rx1, ry1); - - lx = lx1; ly = ly1; - rx = rx1; ry = ry1; - } - - left->x = lx; left->y = ly; - right->x = rx; right->y = ry; -} - -static void nsvg__straightJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p1, float lineWidth) -{ - float w = lineWidth * 0.5f; - float lx = p1->x - (p1->dmx * w), ly = p1->y - (p1->dmy * w); - float rx = p1->x + (p1->dmx * w), ry = p1->y + (p1->dmy * w); - - nsvg__addEdge(r, lx, ly, left->x, left->y); - nsvg__addEdge(r, right->x, right->y, rx, ry); - - left->x = lx; left->y = ly; - right->x = rx; right->y = ry; -} - -static int nsvg__curveDivs(float r, float arc, float tol) -{ - float da = acosf(r / (r + tol)) * 2.0f; - int divs = (int)ceilf(arc / da); - if (divs < 2) divs = 2; - return divs; -} - -static void nsvg__expandStroke(NSVGrasterizer* r, NSVGpoint* points, int npoints, int closed, int lineJoin, int lineCap, float lineWidth) -{ - int ncap = nsvg__curveDivs(lineWidth*0.5f, NSVG_PI, r->tessTol); // Calculate divisions per half circle. - NSVGpoint left = {0,0,0,0,0,0,0,0}, right = {0,0,0,0,0,0,0,0}, firstLeft = {0,0,0,0,0,0,0,0}, firstRight = {0,0,0,0,0,0,0,0}; - NSVGpoint* p0, *p1; - int j, s, e; - - // Build stroke edges - if (closed) { - // Looping - p0 = &points[npoints-1]; - p1 = &points[0]; - s = 0; - e = npoints; - } else { - // Add cap - p0 = &points[0]; - p1 = &points[1]; - s = 1; - e = npoints-1; - } - - if (closed) { - nsvg__initClosed(&left, &right, p0, p1, lineWidth); - firstLeft = left; - firstRight = right; - } else { - // Add cap - float dx = p1->x - p0->x; - float dy = p1->y - p0->y; - nsvg__normalize(&dx, &dy); - if (lineCap == NSVG_CAP_BUTT) - nsvg__buttCap(r, &left, &right, p0, dx, dy, lineWidth, 0); - else if (lineCap == NSVG_CAP_SQUARE) - nsvg__squareCap(r, &left, &right, p0, dx, dy, lineWidth, 0); - else if (lineCap == NSVG_CAP_ROUND) - nsvg__roundCap(r, &left, &right, p0, dx, dy, lineWidth, ncap, 0); - } - - for (j = s; j < e; ++j) { - if (p1->flags & NSVG_PT_CORNER) { - if (lineJoin == NSVG_JOIN_ROUND) - nsvg__roundJoin(r, &left, &right, p0, p1, lineWidth, ncap); - else if (lineJoin == NSVG_JOIN_BEVEL || (p1->flags & NSVG_PT_BEVEL)) - nsvg__bevelJoin(r, &left, &right, p0, p1, lineWidth); - else - nsvg__miterJoin(r, &left, &right, p0, p1, lineWidth); - } else { - nsvg__straightJoin(r, &left, &right, p1, lineWidth); - } - p0 = p1++; - } - - if (closed) { - // Loop it - nsvg__addEdge(r, firstLeft.x, firstLeft.y, left.x, left.y); - nsvg__addEdge(r, right.x, right.y, firstRight.x, firstRight.y); - } else { - // Add cap - float dx = p1->x - p0->x; - float dy = p1->y - p0->y; - nsvg__normalize(&dx, &dy); - if (lineCap == NSVG_CAP_BUTT) - nsvg__buttCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1); - else if (lineCap == NSVG_CAP_SQUARE) - nsvg__squareCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1); - else if (lineCap == NSVG_CAP_ROUND) - nsvg__roundCap(r, &right, &left, p1, -dx, -dy, lineWidth, ncap, 1); - } -} - -static void nsvg__prepareStroke(NSVGrasterizer* r, float miterLimit, int lineJoin) -{ - int i, j; - NSVGpoint* p0, *p1; - - p0 = &r->points[r->npoints-1]; - p1 = &r->points[0]; - for (i = 0; i < r->npoints; i++) { - // Calculate segment direction and length - p0->dx = p1->x - p0->x; - p0->dy = p1->y - p0->y; - p0->len = nsvg__normalize(&p0->dx, &p0->dy); - // Advance - p0 = p1++; - } - - // calculate joins - p0 = &r->points[r->npoints-1]; - p1 = &r->points[0]; - for (j = 0; j < r->npoints; j++) { - float dlx0, dly0, dlx1, dly1, dmr2, cross; - dlx0 = p0->dy; - dly0 = -p0->dx; - dlx1 = p1->dy; - dly1 = -p1->dx; - // Calculate extrusions - p1->dmx = (dlx0 + dlx1) * 0.5f; - p1->dmy = (dly0 + dly1) * 0.5f; - dmr2 = p1->dmx*p1->dmx + p1->dmy*p1->dmy; - if (dmr2 > 0.000001f) { - float s2 = 1.0f / dmr2; - if (s2 > 600.0f) { - s2 = 600.0f; - } - p1->dmx *= s2; - p1->dmy *= s2; - } - - // Clear flags, but keep the corner. - p1->flags = (p1->flags & NSVG_PT_CORNER) ? NSVG_PT_CORNER : 0; - - // Keep track of left turns. - cross = p1->dx * p0->dy - p0->dx * p1->dy; - if (cross > 0.0f) - p1->flags |= NSVG_PT_LEFT; - - // Check to see if the corner needs to be beveled. - if (p1->flags & NSVG_PT_CORNER) { - if ((dmr2 * miterLimit*miterLimit) < 1.0f || lineJoin == NSVG_JOIN_BEVEL || lineJoin == NSVG_JOIN_ROUND) { - p1->flags |= NSVG_PT_BEVEL; - } - } - - p0 = p1++; - } -} - -static void nsvg__flattenShapeStroke(NSVGrasterizer* r, NSVGshape* shape, float scale) -{ - int i, j, closed; - NSVGpath* path; - NSVGpoint* p0, *p1; - float miterLimit = shape->miterLimit; - int lineJoin = shape->strokeLineJoin; - int lineCap = shape->strokeLineCap; - float lineWidth = shape->strokeWidth * scale; - - for (path = shape->paths; path != NULL; path = path->next) { - // Flatten path - r->npoints = 0; - nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, NSVG_PT_CORNER); - for (i = 0; i < path->npts-1; i += 3) { - float* p = &path->pts[i*2]; - nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, NSVG_PT_CORNER); - } - if (r->npoints < 2) - continue; - - closed = path->closed; - - // If the first and last points are the same, remove the last, mark as closed path. - p0 = &r->points[r->npoints-1]; - p1 = &r->points[0]; - if (nsvg__ptEquals(p0->x,p0->y, p1->x,p1->y, r->distTol)) { - r->npoints--; - p0 = &r->points[r->npoints-1]; - closed = 1; - } - - if (shape->strokeDashCount > 0) { - int idash = 0, dashState = 1; - float totalDist = 0, dashLen, allDashLen, dashOffset; - NSVGpoint cur; - - if (closed) - nsvg__appendPathPoint(r, r->points[0]); - - // Duplicate points -> points2. - nsvg__duplicatePoints(r); - - r->npoints = 0; - cur = r->points2[0]; - nsvg__appendPathPoint(r, cur); - - // Figure out dash offset. - allDashLen = 0; - for (j = 0; j < shape->strokeDashCount; j++) - allDashLen += shape->strokeDashArray[j]; - if (shape->strokeDashCount & 1) - allDashLen *= 2.0f; - // Find location inside pattern - dashOffset = fmodf(shape->strokeDashOffset, allDashLen); - if (dashOffset < 0.0f) - dashOffset += allDashLen; - - while (dashOffset > shape->strokeDashArray[idash]) { - dashOffset -= shape->strokeDashArray[idash]; - idash = (idash + 1) % shape->strokeDashCount; - } - dashLen = (shape->strokeDashArray[idash] - dashOffset) * scale; - - for (j = 1; j < r->npoints2; ) { - float dx = r->points2[j].x - cur.x; - float dy = r->points2[j].y - cur.y; - float dist = sqrtf(dx*dx + dy*dy); - - if ((totalDist + dist) > dashLen) { - // Calculate intermediate point - float d = (dashLen - totalDist) / dist; - float x = cur.x + dx * d; - float y = cur.y + dy * d; - nsvg__addPathPoint(r, x, y, NSVG_PT_CORNER); - - // Stroke - if (r->npoints > 1 && dashState) { - nsvg__prepareStroke(r, miterLimit, lineJoin); - nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth); - } - // Advance dash pattern - dashState = !dashState; - idash = (idash+1) % shape->strokeDashCount; - dashLen = shape->strokeDashArray[idash] * scale; - // Restart - cur.x = x; - cur.y = y; - cur.flags = NSVG_PT_CORNER; - totalDist = 0.0f; - r->npoints = 0; - nsvg__appendPathPoint(r, cur); - } else { - totalDist += dist; - cur = r->points2[j]; - nsvg__appendPathPoint(r, cur); - j++; - } - } - // Stroke any leftover path - if (r->npoints > 1 && dashState) - nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth); - } else { - nsvg__prepareStroke(r, miterLimit, lineJoin); - nsvg__expandStroke(r, r->points, r->npoints, closed, lineJoin, lineCap, lineWidth); - } - } -} - -static int nsvg__cmpEdge(const void *p, const void *q) -{ - const NSVGedge* a = (const NSVGedge*)p; - const NSVGedge* b = (const NSVGedge*)q; - - if (a->y0 < b->y0) return -1; - if (a->y0 > b->y0) return 1; - return 0; -} - - -static NSVGactiveEdge* nsvg__addActive(NSVGrasterizer* r, NSVGedge* e, float startPoint) -{ - NSVGactiveEdge* z; - - if (r->freelist != NULL) { - // Restore from freelist. - z = r->freelist; - r->freelist = z->next; - } else { - // Alloc new edge. - z = (NSVGactiveEdge*)nsvg__alloc(r, sizeof(NSVGactiveEdge)); - if (z == NULL) return NULL; - } - - float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); -// STBTT_assert(e->y0 <= start_point); - // round dx down to avoid going too far - if (dxdy < 0) - z->dx = (int)(-floorf(NSVG__FIX * -dxdy)); - else - z->dx = (int)floorf(NSVG__FIX * dxdy); - z->x = (int)floorf(NSVG__FIX * (e->x0 + dxdy * (startPoint - e->y0))); -// z->x -= off_x * FIX; - z->ey = e->y1; - z->next = 0; - z->dir = e->dir; - - return z; -} - -static void nsvg__freeActive(NSVGrasterizer* r, NSVGactiveEdge* z) -{ - z->next = r->freelist; - r->freelist = z; -} - -static void nsvg__fillScanline(unsigned char* scanline, int len, int x0, int x1, int maxWeight, int* xmin, int* xmax) -{ - int i = x0 >> NSVG__FIXSHIFT; - int j = x1 >> NSVG__FIXSHIFT; - if (i < *xmin) *xmin = i; - if (j > *xmax) *xmax = j; - if (i < len && j >= 0) { - if (i == j) { - // x0,x1 are the same pixel, so compute combined coverage - scanline[i] = (unsigned char)(scanline[i] + ((x1 - x0) * maxWeight >> NSVG__FIXSHIFT)); - } else { - if (i >= 0) // add antialiasing for x0 - scanline[i] = (unsigned char)(scanline[i] + (((NSVG__FIX - (x0 & NSVG__FIXMASK)) * maxWeight) >> NSVG__FIXSHIFT)); - else - i = -1; // clip - - if (j < len) // add antialiasing for x1 - scanline[j] = (unsigned char)(scanline[j] + (((x1 & NSVG__FIXMASK) * maxWeight) >> NSVG__FIXSHIFT)); - else - j = len; // clip - - for (++i; i < j; ++i) // fill pixels between x0 and x1 - scanline[i] = (unsigned char)(scanline[i] + maxWeight); - } - } -} - -// note: this routine clips fills that extend off the edges... ideally this -// wouldn't happen, but it could happen if the truetype glyph bounding boxes -// are wrong, or if the user supplies a too-small bitmap -static void nsvg__fillActiveEdges(unsigned char* scanline, int len, NSVGactiveEdge* e, int maxWeight, int* xmin, int* xmax, char fillRule) -{ - // non-zero winding fill - int x0 = 0, w = 0; - - if (fillRule == NSVG_FILLRULE_NONZERO) { - // Non-zero - while (e != NULL) { - if (w == 0) { - // if we're currently at zero, we need to record the edge start point - x0 = e->x; w += e->dir; - } else { - int x1 = e->x; w += e->dir; - // if we went to zero, we need to draw - if (w == 0) - nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax); - } - e = e->next; - } - } else if (fillRule == NSVG_FILLRULE_EVENODD) { - // Even-odd - while (e != NULL) { - if (w == 0) { - // if we're currently at zero, we need to record the edge start point - x0 = e->x; w = 1; - } else { - int x1 = e->x; w = 0; - nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax); - } - e = e->next; - } - } -} - -static float nsvg__clampf(float a, float mn, float mx) { return a < mn ? mn : (a > mx ? mx : a); } - -static unsigned int nsvg__RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) -{ - return (r) | (g << 8) | (b << 16) | (a << 24); -} - -static unsigned int nsvg__lerpRGBA(unsigned int c0, unsigned int c1, float u) -{ - int iu = (int)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f); - int r = (((c0) & 0xff)*(256-iu) + (((c1) & 0xff)*iu)) >> 8; - int g = (((c0>>8) & 0xff)*(256-iu) + (((c1>>8) & 0xff)*iu)) >> 8; - int b = (((c0>>16) & 0xff)*(256-iu) + (((c1>>16) & 0xff)*iu)) >> 8; - int a = (((c0>>24) & 0xff)*(256-iu) + (((c1>>24) & 0xff)*iu)) >> 8; - return nsvg__RGBA((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a); -} - -static unsigned int nsvg__applyOpacity(unsigned int c, float u) -{ - int iu = (int)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f); - int r = (c) & 0xff; - int g = (c>>8) & 0xff; - int b = (c>>16) & 0xff; - int a = (((c>>24) & 0xff)*iu) >> 8; - return nsvg__RGBA((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a); -} - -static inline int nsvg__div255(int x) -{ - return ((x+1) * 257) >> 16; -} - -static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* cover, int x, int y, - float tx, float ty, float scale, NSVGcachedPaint* cache) -{ - - if (cache->type == NSVG_PAINT_COLOR) { - int i, cr, cg, cb, ca; - cr = cache->colors[0] & 0xff; - cg = (cache->colors[0] >> 8) & 0xff; - cb = (cache->colors[0] >> 16) & 0xff; - ca = (cache->colors[0] >> 24) & 0xff; - - for (i = 0; i < count; i++) { - int r,g,b; - int a = nsvg__div255((int)cover[0] * ca); - int ia = 255 - a; - // Premultiply - r = nsvg__div255(cr * a); - g = nsvg__div255(cg * a); - b = nsvg__div255(cb * a); - - // Blend over - r += nsvg__div255(ia * (int)dst[0]); - g += nsvg__div255(ia * (int)dst[1]); - b += nsvg__div255(ia * (int)dst[2]); - a += nsvg__div255(ia * (int)dst[3]); - - dst[0] = (unsigned char)r; - dst[1] = (unsigned char)g; - dst[2] = (unsigned char)b; - dst[3] = (unsigned char)a; - - cover++; - dst += 4; - } - } else if (cache->type == NSVG_PAINT_LINEAR_GRADIENT) { - // TODO: spread modes. - // TODO: plenty of opportunities to optimize. - float fx, fy, dx, gy; - float* t = cache->xform; - int i, cr, cg, cb, ca; - unsigned int c; - - fx = ((float)x - tx) / scale; - fy = ((float)y - ty) / scale; - dx = 1.0f / scale; - - for (i = 0; i < count; i++) { - int r,g,b,a,ia; - gy = fx*t[1] + fy*t[3] + t[5]; - c = cache->colors[(int)nsvg__clampf(gy*255.0f, 0, 255.0f)]; - cr = (c) & 0xff; - cg = (c >> 8) & 0xff; - cb = (c >> 16) & 0xff; - ca = (c >> 24) & 0xff; - - a = nsvg__div255((int)cover[0] * ca); - ia = 255 - a; - - // Premultiply - r = nsvg__div255(cr * a); - g = nsvg__div255(cg * a); - b = nsvg__div255(cb * a); - - // Blend over - r += nsvg__div255(ia * (int)dst[0]); - g += nsvg__div255(ia * (int)dst[1]); - b += nsvg__div255(ia * (int)dst[2]); - a += nsvg__div255(ia * (int)dst[3]); - - dst[0] = (unsigned char)r; - dst[1] = (unsigned char)g; - dst[2] = (unsigned char)b; - dst[3] = (unsigned char)a; - - cover++; - dst += 4; - fx += dx; - } - } else if (cache->type == NSVG_PAINT_RADIAL_GRADIENT) { - // TODO: spread modes. - // TODO: plenty of opportunities to optimize. - // TODO: focus (fx,fy) - float fx, fy, dx, gx, gy, gd; - float* t = cache->xform; - int i, cr, cg, cb, ca; - unsigned int c; - - fx = ((float)x - tx) / scale; - fy = ((float)y - ty) / scale; - dx = 1.0f / scale; - - for (i = 0; i < count; i++) { - int r,g,b,a,ia; - gx = fx*t[0] + fy*t[2] + t[4]; - gy = fx*t[1] + fy*t[3] + t[5]; - gd = sqrtf(gx*gx + gy*gy); - c = cache->colors[(int)nsvg__clampf(gd*255.0f, 0, 255.0f)]; - cr = (c) & 0xff; - cg = (c >> 8) & 0xff; - cb = (c >> 16) & 0xff; - ca = (c >> 24) & 0xff; - - a = nsvg__div255((int)cover[0] * ca); - ia = 255 - a; - - // Premultiply - r = nsvg__div255(cr * a); - g = nsvg__div255(cg * a); - b = nsvg__div255(cb * a); - - // Blend over - r += nsvg__div255(ia * (int)dst[0]); - g += nsvg__div255(ia * (int)dst[1]); - b += nsvg__div255(ia * (int)dst[2]); - a += nsvg__div255(ia * (int)dst[3]); - - dst[0] = (unsigned char)r; - dst[1] = (unsigned char)g; - dst[2] = (unsigned char)b; - dst[3] = (unsigned char)a; - - cover++; - dst += 4; - fx += dx; - } - } -} - -static void nsvg__rasterizeSortedEdges(NSVGrasterizer *r, float tx, float ty, float scale, NSVGcachedPaint* cache, char fillRule) -{ - NSVGactiveEdge *active = NULL; - int y, s; - int e = 0; - int maxWeight = (255 / NSVG__SUBSAMPLES); // weight per vertical scanline - int xmin, xmax; - - for (y = 0; y < r->height; y++) { - memset(r->scanline, 0, r->width); - xmin = r->width; - xmax = 0; - for (s = 0; s < NSVG__SUBSAMPLES; ++s) { - // find center of pixel for this scanline - float scany = (float)(y*NSVG__SUBSAMPLES + s) + 0.5f; - NSVGactiveEdge **step = &active; - - // update all active edges; - // remove all active edges that terminate before the center of this scanline - while (*step) { - NSVGactiveEdge *z = *step; - if (z->ey <= scany) { - *step = z->next; // delete from list -// NSVG__assert(z->valid); - nsvg__freeActive(r, z); - } else { - z->x += z->dx; // advance to position for current scanline - step = &((*step)->next); // advance through list - } - } - - // resort the list if needed - for (;;) { - int changed = 0; - step = &active; - while (*step && (*step)->next) { - if ((*step)->x > (*step)->next->x) { - NSVGactiveEdge* t = *step; - NSVGactiveEdge* q = t->next; - t->next = q->next; - q->next = t; - *step = q; - changed = 1; - } - step = &(*step)->next; - } - if (!changed) break; - } - - // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline - while (e < r->nedges && r->edges[e].y0 <= scany) { - if (r->edges[e].y1 > scany) { - NSVGactiveEdge* z = nsvg__addActive(r, &r->edges[e], scany); - if (z == NULL) break; - // find insertion point - if (active == NULL) { - active = z; - } else if (z->x < active->x) { - // insert at front - z->next = active; - active = z; - } else { - // find thing to insert AFTER - NSVGactiveEdge* p = active; - while (p->next && p->next->x < z->x) - p = p->next; - // at this point, p->next->x is NOT < z->x - z->next = p->next; - p->next = z; - } - } - e++; - } - - // now process all active edges in non-zero fashion - if (active != NULL) - nsvg__fillActiveEdges(r->scanline, r->width, active, maxWeight, &xmin, &xmax, fillRule); - } - // Blit - if (xmin < 0) xmin = 0; - if (xmax > r->width-1) xmax = r->width-1; - if (xmin <= xmax) { - nsvg__scanlineSolid(&r->bitmap[y * r->stride] + xmin*4, xmax-xmin+1, &r->scanline[xmin], xmin, y, tx,ty, scale, cache); - } - } - -} - -static void nsvg__unpremultiplyAlpha(unsigned char* image, int w, int h, int stride) -{ - int x,y; - - // Unpremultiply - for (y = 0; y < h; y++) { - unsigned char *row = &image[y*stride]; - for (x = 0; x < w; x++) { - int r = row[0], g = row[1], b = row[2], a = row[3]; - if (a != 0) { - row[0] = (unsigned char)(r*255/a); - row[1] = (unsigned char)(g*255/a); - row[2] = (unsigned char)(b*255/a); - } - row += 4; - } - } - - // Defringe - for (y = 0; y < h; y++) { - unsigned char *row = &image[y*stride]; - for (x = 0; x < w; x++) { - int r = 0, g = 0, b = 0, a = row[3], n = 0; - if (a == 0) { - if (x-1 > 0 && row[-1] != 0) { - r += row[-4]; - g += row[-3]; - b += row[-2]; - n++; - } - if (x+1 < w && row[7] != 0) { - r += row[4]; - g += row[5]; - b += row[6]; - n++; - } - if (y-1 > 0 && row[-stride+3] != 0) { - r += row[-stride]; - g += row[-stride+1]; - b += row[-stride+2]; - n++; - } - if (y+1 < h && row[stride+3] != 0) { - r += row[stride]; - g += row[stride+1]; - b += row[stride+2]; - n++; - } - if (n > 0) { - row[0] = (unsigned char)(r/n); - row[1] = (unsigned char)(g/n); - row[2] = (unsigned char)(b/n); - } - } - row += 4; - } - } -} - - -static void nsvg__initPaint(NSVGcachedPaint* cache, NSVGpaint* paint, float opacity) -{ - int i, j; - NSVGgradient* grad; - - cache->type = paint->type; - - if (paint->type == NSVG_PAINT_COLOR) { - cache->colors[0] = nsvg__applyOpacity(paint->color, opacity); - return; - } - - grad = paint->gradient; - - cache->spread = grad->spread; - memcpy(cache->xform, grad->xform, sizeof(float)*6); - - if (grad->nstops == 0) { - for (i = 0; i < 256; i++) - cache->colors[i] = 0; - } if (grad->nstops == 1) { - for (i = 0; i < 256; i++) - cache->colors[i] = nsvg__applyOpacity(grad->stops[i].color, opacity); - } else { - unsigned int ca, cb = 0; - float ua, ub, du, u; - int ia, ib, count; - - ca = nsvg__applyOpacity(grad->stops[0].color, opacity); - ua = nsvg__clampf(grad->stops[0].offset, 0, 1); - ub = nsvg__clampf(grad->stops[grad->nstops-1].offset, ua, 1); - ia = (int)(ua * 255.0f); - ib = (int)(ub * 255.0f); - for (i = 0; i < ia; i++) { - cache->colors[i] = ca; - } - - for (i = 0; i < grad->nstops-1; i++) { - ca = nsvg__applyOpacity(grad->stops[i].color, opacity); - cb = nsvg__applyOpacity(grad->stops[i+1].color, opacity); - ua = nsvg__clampf(grad->stops[i].offset, 0, 1); - ub = nsvg__clampf(grad->stops[i+1].offset, 0, 1); - ia = (int)(ua * 255.0f); - ib = (int)(ub * 255.0f); - count = ib - ia; - if (count <= 0) continue; - u = 0; - du = 1.0f / (float)count; - for (j = 0; j < count; j++) { - cache->colors[ia+j] = nsvg__lerpRGBA(ca,cb,u); - u += du; - } - } - - for (i = ib; i < 256; i++) - cache->colors[i] = cb; - } - -} - -/* -static void dumpEdges(NSVGrasterizer* r, const char* name) -{ - float xmin = 0, xmax = 0, ymin = 0, ymax = 0; - NSVGedge *e = NULL; - int i; - if (r->nedges == 0) return; - FILE* fp = fopen(name, "w"); - if (fp == NULL) return; - - xmin = xmax = r->edges[0].x0; - ymin = ymax = r->edges[0].y0; - for (i = 0; i < r->nedges; i++) { - e = &r->edges[i]; - xmin = nsvg__minf(xmin, e->x0); - xmin = nsvg__minf(xmin, e->x1); - xmax = nsvg__maxf(xmax, e->x0); - xmax = nsvg__maxf(xmax, e->x1); - ymin = nsvg__minf(ymin, e->y0); - ymin = nsvg__minf(ymin, e->y1); - ymax = nsvg__maxf(ymax, e->y0); - ymax = nsvg__maxf(ymax, e->y1); - } - - fprintf(fp, "<svg viewBox=\"%f %f %f %f\" xmlns=\"http://www.w3.org/2000/svg\">", xmin, ymin, (xmax - xmin), (ymax - ymin)); - - for (i = 0; i < r->nedges; i++) { - e = &r->edges[i]; - fprintf(fp ,"<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" style=\"stroke:#000;\" />", e->x0,e->y0, e->x1,e->y1); - } - - for (i = 0; i < r->npoints; i++) { - if (i+1 < r->npoints) - fprintf(fp ,"<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" style=\"stroke:#f00;\" />", r->points[i].x, r->points[i].y, r->points[i+1].x, r->points[i+1].y); - fprintf(fp ,"<circle cx=\"%f\" cy=\"%f\" r=\"1\" style=\"fill:%s;\" />", r->points[i].x, r->points[i].y, r->points[i].flags == 0 ? "#f00" : "#0f0"); - } - - fprintf(fp, "</svg>"); - fclose(fp); -} -*/ - -void nsvgRasterize(NSVGrasterizer* r, - NSVGimage* image, float tx, float ty, float scale, - unsigned char* dst, int w, int h, int stride) -{ - NSVGshape *shape = NULL; - NSVGedge *e = NULL; - NSVGcachedPaint cache; - int i; - - r->bitmap = dst; - r->width = w; - r->height = h; - r->stride = stride; - - if (w > r->cscanline) { - r->cscanline = w; - r->scanline = (unsigned char*)realloc(r->scanline, w); - if (r->scanline == NULL) return; - } - - for (i = 0; i < h; i++) - memset(&dst[i*stride], 0, w*4); - - for (shape = image->shapes; shape != NULL; shape = shape->next) { - if (!(shape->flags & NSVG_FLAGS_VISIBLE)) - continue; - - if (shape->fill.type != NSVG_PAINT_NONE) { - nsvg__resetPool(r); - r->freelist = NULL; - r->nedges = 0; - - nsvg__flattenShape(r, shape, scale); - - // Scale and translate edges - for (i = 0; i < r->nedges; i++) { - e = &r->edges[i]; - e->x0 = tx + e->x0; - e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES; - e->x1 = tx + e->x1; - e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES; - } - - // Rasterize edges - qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge); - - // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule - nsvg__initPaint(&cache, &shape->fill, shape->opacity); - - nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, shape->fillRule); - } - if (shape->stroke.type != NSVG_PAINT_NONE && (shape->strokeWidth * scale) > 0.01f) { - nsvg__resetPool(r); - r->freelist = NULL; - r->nedges = 0; - - nsvg__flattenShapeStroke(r, shape, scale); - -// dumpEdges(r, "edge.svg"); - - // Scale and translate edges - for (i = 0; i < r->nedges; i++) { - e = &r->edges[i]; - e->x0 = tx + e->x0; - e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES; - e->x1 = tx + e->x1; - e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES; - } - - // Rasterize edges - qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge); - - // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule - nsvg__initPaint(&cache, &shape->stroke, shape->opacity); - - nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, NSVG_FILLRULE_NONZERO); - } - } - - nsvg__unpremultiplyAlpha(dst, w, h, stride); - - r->bitmap = NULL; - r->width = 0; - r->height = 0; - r->stride = 0; -} - -#endif diff --git a/thirdparty/thorvg/AUTHORS b/thirdparty/thorvg/AUTHORS new file mode 100644 index 0000000000..66057232b6 --- /dev/null +++ b/thirdparty/thorvg/AUTHORS @@ -0,0 +1,15 @@ +Hermet Park <chuneon.park@samsung.com> +Prudhvi Raj Vasireddi <prudhvi.raj@samsung.com> +Junsu Choi <jsuya.choi@samsung.com> +Pranay Samanta <pranay.ks@samsung.com> +Mateusz Palkowski <m.palkowski@samsung.com> +Subhransu Mohanty <sub.mohanty@samsung.com> +Mira Grudzinska <m.grudzinska@samsung.com> +Michal Szczecinski <m.szczecinsk@partner.samsung.com> +Shinwoo Kim <cinoo.kim@samsung.com> +Piotr Kalota <p.kalota@samsung.com> +Vincent Torri <vincent.torri@gmail.com> +Pankaj Kumar <pankaj.m1@samsung.com> +Patryk Kaczmarek <patryk.k@partner.samsung.com> +Michal Maciola <m.maciola@samsung.com> +Peter Vullings <peter@projectitis.com> diff --git a/thirdparty/thorvg/LICENSE b/thirdparty/thorvg/LICENSE new file mode 100644 index 0000000000..b096b0888e --- /dev/null +++ b/thirdparty/thorvg/LICENSE @@ -0,0 +1,7 @@ +Copyright (c) 2020 - 2021 notice for the ThorVG Project (see AUTHORS) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/thirdparty/thorvg/inc/config.h b/thirdparty/thorvg/inc/config.h new file mode 100644 index 0000000000..04a450b1bb --- /dev/null +++ b/thirdparty/thorvg/inc/config.h @@ -0,0 +1,17 @@ +#ifndef THORVG_CONFIG_H +#define THORVG_CONFIG_H + +#define THORVG_SW_RASTER_SUPPORT 1 + +#define THORVG_SVG_LOADER_SUPPORT 1 + +#define THORVG_PNG_LOADER_SUPPORT 1 + +#define THORVG_TVG_LOADER_SUPPORT 1 + +#define THORVG_TVG_SAVER_SUPPORT 1 + +#define THORVG_JPG_LOADER_SUPPORT 1 + +#define THORVG_VERSION_STRING "0.7.0" +#endif diff --git a/thirdparty/thorvg/inc/thorvg.h b/thirdparty/thorvg/inc/thorvg.h new file mode 100644 index 0000000000..e542d36555 --- /dev/null +++ b/thirdparty/thorvg/inc/thorvg.h @@ -0,0 +1,1589 @@ +/*! + * @file thorvg.h + * + * The main APIs enabling the TVG initialization, preparation of the canvas and provisioning of its content: + * - drawing shapes such as line, curve, arc, rectangle, circle or user-defined + * - drawing pictures - SVG, PNG, JPG, RAW + * - solid or gradient filling + * - continuous and dashed stroking + * - clipping and masking + * and finally drawing the canvas and TVG termination. + */ + + +#ifndef _THORVG_H_ +#define _THORVG_H_ + +#include <memory> +#include <string> + +#ifdef TVG_BUILD + #if defined(_MSC_VER) && !defined(__clang__) + #define TVG_EXPORT __declspec(dllexport) + #define TVG_DEPRECATED __declspec(deprecated) + #else + #define TVG_EXPORT __attribute__ ((visibility ("default"))) + #define TVG_DEPRECATED __attribute__ ((__deprecated__)) + #endif +#else + #define TVG_EXPORT + #define TVG_DEPRECATED +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define _TVG_DECLARE_PRIVATE(A) \ +protected: \ + struct Impl; \ + Impl* pImpl; \ + A(const A&) = delete; \ + const A& operator=(const A&) = delete; \ + A() + +#define _TVG_DISABLE_CTOR(A) \ + A() = delete; \ + ~A() = delete + +#define _TVG_DECLARE_ACCESSOR() \ + friend Canvas; \ + friend Scene; \ + friend Picture; \ + friend Accessor; \ + friend IteratorAccessor + + +namespace tvg +{ + +class RenderMethod; +class IteratorAccessor; +class Scene; +class Picture; +class Canvas; +class Accessor; + +/** + * @defgroup ThorVG ThorVG + * @brief ThorVG classes and enumerations providing C++ APIs. + */ + +/**@{*/ + +/** + * @brief Enumeration specifying the result from the APIs. + */ +enum class TVG_EXPORT Result +{ + Success = 0, ///< The value returned in case of a correct request execution. + InvalidArguments, ///< The value returned in the event of a problem with the arguments given to the API - e.g. empty paths or null pointers. + InsufficientCondition, ///< The value returned in case the request cannot be processed - e.g. asking for properties of an object, which does not exist. + FailedAllocation, ///< The value returned in case of unsuccessful memory allocation. + MemoryCorruption, ///< The value returned in the event of bad memory handling - e.g. failing in pointer releasing or casting + NonSupport, ///< The value returned in case of choosing unsupported options. + Unknown ///< The value returned in all other cases. +}; + +/** + * @brief Enumeration specifying the values of the path commands accepted by TVG. + * + * Not to be confused with the path commands from the svg path element (like M, L, Q, H and many others). + * TVG interprets all of them and translates to the ones from the PathCommand values. + */ +enum class TVG_EXPORT PathCommand +{ + Close = 0, ///< Ends the current sub-path and connects it with its initial point. This command doesn't expect any points. + MoveTo, ///< Sets a new initial point of the sub-path and a new current point. This command expects 1 point: the starting position. + LineTo, ///< Draws a line from the current point to the given point and sets a new value of the current point. This command expects 1 point: the end-position of the line. + CubicTo ///< Draws a cubic Bezier curve from the current point to the given point using two given control points and sets a new value of the current point. This command expects 3 points: the 1st control-point, the 2nd control-point, the end-point of the curve. +}; + +/** + * @brief Enumeration determining the ending type of a stroke in the open sub-paths. + */ +enum class TVG_EXPORT StrokeCap +{ + Square = 0, ///< The stroke is extended in both end-points of a sub-path by a rectangle, with the width equal to the stroke width and the length equal to the half of the stroke width. For zero length sub-paths the square is rendered with the size of the stroke width. + Round, ///< The stroke is extended in both end-points of a sub-path by a half circle, with a radius equal to the half of a stroke width. For zero length sub-paths a full circle is rendered. + Butt ///< The stroke ends exactly at each of the two end-points of a sub-path. For zero length sub-paths no stroke is rendered. +}; + +/** + * @brief Enumeration determining the style used at the corners of joined stroked path segments. + */ +enum class TVG_EXPORT StrokeJoin +{ + Bevel = 0, ///< The outer corner of the joined path segments is bevelled at the join point. The triangular region of the corner is enclosed by a straight line between the outer corners of each stroke. + Round, ///< The outer corner of the joined path segments is rounded. The circular region is centered at the join point. + Miter ///< The outer corner of the joined path segments is spiked. The spike is created by extension beyond the join point of the outer edges of the stroke until they intersect. In case the extension goes beyond the limit, the join style is converted to the Bevel style. +}; + +/** + * @brief Enumeration specifying how to fill the area outside the gradient bounds. + */ +enum class TVG_EXPORT FillSpread +{ + Pad = 0, ///< The remaining area is filled with the closest stop color. + Reflect, ///< The gradient pattern is reflected outside the gradient area until the expected region is filled. + Repeat ///< The gradient pattern is repeated continuously beyond the gradient area until the expected region is filled. +}; + +/** + * @brief Enumeration specifying the algorithm used to establish which parts of the shape are treated as the inside of the shape. + */ +enum class TVG_EXPORT FillRule +{ + Winding = 0, ///< A line from the point to a location outside the shape is drawn. The intersections of the line with the path segment of the shape are counted. Starting from zero, if the path segment of the shape crosses the line clockwise, one is added, otherwise one is subtracted. If the resulting sum is non zero, the point is inside the shape. + EvenOdd ///< A line from the point to a location outside the shape is drawn and its intersections with the path segments of the shape are counted. If the number of intersections is an odd number, the point is inside the shape. +}; + +/** + * @brief Enumeration indicating the method used in the composition of two objects - the target and the source. + */ +enum class TVG_EXPORT CompositeMethod +{ + None = 0, ///< No composition is applied. + ClipPath, ///< The intersection of the source and the target is determined and only the resulting pixels from the source are rendered. + AlphaMask, ///< The pixels of the source and the target are alpha blended. As a result, only the part of the source, which intersects with the target is visible. + InvAlphaMask ///< The pixels of the source and the complement to the target's pixels are alpha blended. As a result, only the part of the source which is not covered by the target is visible. +}; + +/** + * @brief Enumeration specifying the engine type used for the graphics backend. For multiple backends bitwise operation is allowed. + */ +enum class TVG_EXPORT CanvasEngine +{ + Sw = (1 << 1), ///< CPU rasterizer. + Gl = (1 << 2) ///< OpenGL rasterizer. +}; + + +/** + * @brief A data structure representing a point in two-dimensional space. + */ +struct Point +{ + float x, y; +}; + + +/** + * @brief A data structure representing a three-dimensional matrix. + * + * The elements e11, e12, e21 and e22 represent the rotation matrix, including the scaling factor. + * The elements e13 and e23 determine the translation of the object along the x and y-axis, respectively. + * The elements e31 and e32 are set to 0, e33 is set to 1. + */ +struct Matrix +{ + float e11, e12, e13; + float e21, e22, e23; + float e31, e32, e33; +}; + + +/** + * @class Paint + * + * @brief An abstract class for managing graphical elements. + * + * A graphical element in TVG is any object composed into a Canvas. + * Paint represents such a graphical object and its behaviors such as duplication, transformation and composition. + * TVG recommends the user to regard a paint as a set of volatile commands. They can prepare a Paint and then request a Canvas to run them. + */ +class TVG_EXPORT Paint +{ +public: + virtual ~Paint(); + + /** + * @brief Sets the angle by which the object is rotated. + * + * The angle in measured clockwise from the horizontal axis. + * The rotational axis passes through the point on the object with zero coordinates. + * + * @param[in] degree The value of the angle in degrees. + * + * @return Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result rotate(float degree) noexcept; + + /** + * @brief Sets the scale value of the object. + * + * @param[in] factor The value of the scaling factor. The default value is 1. + * + * @return Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result scale(float factor) noexcept; + + /** + * @brief Sets the values by which the object is moved in a two-dimensional space. + * + * The origin of the coordinate system is in the upper left corner of the canvas. + * The horizontal and vertical axes point to the right and down, respectively. + * + * @param[in] x The value of the horizontal shift. + * @param[in] y The value of the vertical shift. + * + * @return Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result translate(float x, float y) noexcept; + + /** + * @brief Sets the matrix of the affine transformation for the object. + * + * The augmented matrix of the transformation is expected to be given. + * + * @param[in] m The 3x3 augmented matrix. + * + * @return Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result transform(const Matrix& m) noexcept; + + /** + * @brief Gets the matrix of the affine transformation of the object. + * + * The values of the matrix can be set by the transform() API, as well by the translate(), + * scale() and rotate(). In case no transformation was applied, the identity matrix is returned. + * + * @retval The augmented transformation matrix. + * + * @since 0.4 + */ + Matrix transform() noexcept; + + /** + * @brief Sets the opacity of the object. + * + * @param[in] o The opacity value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. + * + * @return Result::Success when succeed. + * + * @note Setting the opacity with this API may require multiple render pass for composition. It is recommended to avoid changing the opacity if possible. + */ + Result opacity(uint8_t o) noexcept; + + /** + * @brief Sets the composition target object and the composition method. + * + * @param[in] target The paint of the target object. + * @param[in] method The method used to composite the source object with the target. + * + * @return Result::Success when succeed, Result::InvalidArguments otherwise. + */ + Result composite(std::unique_ptr<Paint> target, CompositeMethod method) noexcept; + + /** + * @brief Gets the bounding box of the paint object before any transformation. + * + * @param[out] x The x coordinate of the upper left corner of the object. + * @param[out] y The y coordinate of the upper left corner of the object. + * @param[out] w The width of the object. + * @param[out] h The height of the object. + * + * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * + * @note The bounding box doesn't indicate the final rendered region. It's the smallest rectangle that encloses the object. + * @see Paint::bounds(float* x, float* y, float* w, float* h, bool transformed); + */ + TVG_DEPRECATED Result bounds(float* x, float* y, float* w, float* h) const noexcept; + + /** + * @brief Gets the axis-aligned bounding box of the paint object. + * + * In case @p transform is @c true, all object's transformations are applied first, and then the bounding box is established. Otherwise, the bounding box is determined before any transformations. + * + * @param[out] x The x coordinate of the upper left corner of the object. + * @param[out] y The y coordinate of the upper left corner of the object. + * @param[out] w The width of the object. + * @param[out] h The height of the object. + * @param[in] transformed If @c true, the paint's transformations are taken into account, otherwise they aren't. + * + * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * + * @note The bounding box doesn't indicate the actual drawing region. It's the smallest rectangle that encloses the object. + */ + Result bounds(float* x, float* y, float* w, float* h, bool transformed) const noexcept; + + /** + * @brief Duplicates the object. + * + * Creates a new object and sets its all properties as in the original object. + * + * @return The created object when succeed, @c nullptr otherwise. + */ + Paint* duplicate() const noexcept; + + /** + * @brief Gets the opacity value of the object. + * + * @return The opacity value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. + */ + uint8_t opacity() const noexcept; + + /** + * @brief Gets the composition target object and the composition method. + * + * @param[out] target The paint of the target object. + * + * @return The method used to composite the source object with the target. + * + * @since 0.5 + */ + CompositeMethod composite(const Paint** target) const noexcept; + + /** + * @brief Return the unique id value of the paint instance. + * + * This method can be called for checking the current concrete instance type. + * + * @return The type id of the Paint instance. + * + * @BETA_API + */ + uint32_t identifier() const noexcept; + + _TVG_DECLARE_ACCESSOR(); + _TVG_DECLARE_PRIVATE(Paint); +}; + + +/** + * @class Fill + * + * @brief An abstract class representing the gradient fill of the Shape object. + * + * It contains the information about the gradient colors and their arrangement + * inside the gradient bounds. The gradients bounds are defined in the LinearGradient + * or RadialGradient class, depending on the type of the gradient to be used. + * It specifies the gradient behavior in case the area defined by the gradient bounds + * is smaller than the area to be filled. + */ +class TVG_EXPORT Fill +{ +public: + /** + * @brief A data structure storing the information about the color and its relative position inside the gradient bounds. + */ + struct ColorStop + { + float offset; /**< The relative position of the color. */ + uint8_t r; /**< The red color channel value in the range [0 ~ 255]. */ + uint8_t g; /**< The green color channel value in the range [0 ~ 255]. */ + uint8_t b; /**< The blue color channel value in the range [0 ~ 255]. */ + uint8_t a; /**< The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. */ + }; + + virtual ~Fill(); + + /** + * @brief Sets the parameters of the colors of the gradient and their position. + * + * @param[in] colorStops An array of ColorStop data structure. + * @param[in] cnt The count of the @p colorStops array equal to the colors number used in the gradient. + * + * @return Result::Success when succeed. + */ + Result colorStops(const ColorStop* colorStops, uint32_t cnt) noexcept; + + /** + * @brief Sets the FillSpread value, which specifies how to fill the area outside the gradient bounds. + * + * @param[in] s The FillSpread value. + * + * @return Result::Success when succeed. + */ + Result spread(FillSpread s) noexcept; + + /** + * @brief Sets the matrix of the affine transformation for the gradient fill. + * + * The augmented matrix of the transformation is expected to be given. + * + * @param[in] m The 3x3 augmented matrix. + * + * @return Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result transform(const Matrix& m) noexcept; + + /** + * @brief Gets the parameters of the colors of the gradient, their position and number. + * + * @param[out] colorStops A pointer to the memory location, where the array of the gradient's ColorStop is stored. + * + * @return The number of colors used in the gradient. This value corresponds to the length of the @p colorStops array. + */ + uint32_t colorStops(const ColorStop** colorStops) const noexcept; + + /** + * @brief Gets the FillSpread value of the fill. + * + * @return The FillSpread value of this Fill. + */ + FillSpread spread() const noexcept; + + /** + * @brief Gets the matrix of the affine transformation of the gradient fill. + * + * In case no transformation was applied, the identity matrix is returned. + * + * @retval The augmented transformation matrix. + */ + Matrix transform() const noexcept; + + /** + * @brief Creates a copy of the Fill object. + * + * Return a newly created Fill object with the properties copied from the original. + * + * @return A copied Fill object when succeed, @c nullptr otherwise. + */ + Fill* duplicate() const noexcept; + + /** + * @brief Return the unique id value of the Fill instance. + * + * This method can be called for checking the current concrete instance type. + * + * @return The type id of the Fill instance. + * + * @BETA_API + */ + uint32_t identifier() const noexcept; + + _TVG_DECLARE_PRIVATE(Fill); +}; + + +/** + * @class Canvas + * + * @brief An abstract class for drawing graphical elements. + * + * A canvas is an entity responsible for drawing the target. It sets up the drawing engine and the buffer, which can be drawn on the screen. It also manages given Paint objects. + * + * @note A Canvas behavior depends on the raster engine though the final content of the buffer is expected to be identical. + * @warning The Paint objects belonging to one Canvas can't be shared among multiple Canvases. + */ +class TVG_EXPORT Canvas +{ +public: + Canvas(RenderMethod*); + virtual ~Canvas(); + + /** + * @brief Sets the size of the container, where all the paints pushed into the Canvas are stored. + * + * If the number of objects pushed into the Canvas is known in advance, calling the function + * prevents multiple memory reallocation, thus improving the performance. + * + * @param[in] n The number of objects for which the memory is to be reserved. + * + * @return Result::Success when succeed. + */ + Result reserve(uint32_t n) noexcept; + + /** + * @brief Passes drawing elements to the Canvas using Paint objects. + * + * Only pushed paints in the canvas will be drawing targets. + * They are retained by the canvas until you call Canvas::clear(). + * If you know the number of the pushed objects in advance, please call Canvas::reserve(). + * + * @param[in] paint A Paint object to be drawn. + * + * @retval Result::Success When succeed. + * @retval Result::MemoryCorruption In case a @c nullptr is passed as the argument. + * @retval Result::InsufficientCondition An internal error. + * + * @note The rendering order of the paints is the same as the order as they were pushed into the canvas. Consider sorting the paints before pushing them if you intend to use layering. + * @see Canvas::reserve() + * @see Canvas::clear() + */ + virtual Result push(std::unique_ptr<Paint> paint) noexcept; + + /** + * @brief Sets the total number of the paints pushed into the canvas to be zero. + * Depending on the value of the @p free argument, the paints are freed or not. + * + * @param[in] free If @c true, the memory occupied by paints is deallocated, otherwise it is not. + * + * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * + * @warning If you don't free the paints they become dangled. They are supposed to be reused, otherwise you are responsible for their lives. Thus please use the @p free argument only when you know how it works, otherwise it's not recommended. + */ + virtual Result clear(bool free = true) noexcept; + + /** + * @brief Request the canvas to update the paint objects. + * + * If a @c nullptr is passed all paint objects retained by the Canvas are updated, + * otherwise only the paint to which the given @p paint points. + * + * @param[in] paint A pointer to the Paint object or @c nullptr. + * + * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * + * @note The Update behavior can be asynchronous if the assigned thread number is greater than zero. + */ + virtual Result update(Paint* paint = nullptr) noexcept; + + /** + * @brief Requests the canvas to draw the Paint objects. + * + * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * + * @note Drawing can be asynchronous if the assigned thread number is greater than zero. To guarantee the drawing is done, call sync() afterwards. + * @see Canvas::sync() + */ + virtual Result draw() noexcept; + + /** + * @brief Guarantees that drawing task is finished. + * + * The Canvas rendering can be performed asynchronously. To make sure that rendering is finished, + * the sync() must be called after the draw() regardless of threading. + * + * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * @see Canvas::draw() + */ + virtual Result sync() noexcept; + + _TVG_DECLARE_PRIVATE(Canvas); +}; + + +/** + * @class LinearGradient + * + * @brief A class representing the linear gradient fill of the Shape object. + * + * Besides the APIs inherited from the Fill class, it enables setting and getting the linear gradient bounds. + * The behavior outside the gradient bounds depends on the value specified in the spread API. + */ +class TVG_EXPORT LinearGradient final : public Fill +{ +public: + ~LinearGradient(); + + /** + * @brief Sets the linear gradient bounds. + * + * The bounds of the linear gradient are defined as a surface constrained by two parallel lines crossing + * the given points (@p x1, @p y1) and (@p x2, @p y2), respectively. Both lines are perpendicular to the line linking + * (@p x1, @p y1) and (@p x2, @p y2). + * + * @param[in] x1 The horizontal coordinate of the first point used to determine the gradient bounds. + * @param[in] y1 The vertical coordinate of the first point used to determine the gradient bounds. + * @param[in] x2 The horizontal coordinate of the second point used to determine the gradient bounds. + * @param[in] y2 The vertical coordinate of the second point used to determine the gradient bounds. + * + * @return Result::Success when succeed. + * + * @note In case the first and the second points are equal, an object filled with such a gradient fill is not rendered. + */ + Result linear(float x1, float y1, float x2, float y2) noexcept; + + /** + * @brief Gets the linear gradient bounds. + * + * The bounds of the linear gradient are defined as a surface constrained by two parallel lines crossing + * the given points (@p x1, @p y1) and (@p x2, @p y2), respectively. Both lines are perpendicular to the line linking + * (@p x1, @p y1) and (@p x2, @p y2). + * + * @param[out] x1 The horizontal coordinate of the first point used to determine the gradient bounds. + * @param[out] y1 The vertical coordinate of the first point used to determine the gradient bounds. + * @param[out] x2 The horizontal coordinate of the second point used to determine the gradient bounds. + * @param[out] y2 The vertical coordinate of the second point used to determine the gradient bounds. + * + * @return Result::Success when succeed. + */ + Result linear(float* x1, float* y1, float* x2, float* y2) const noexcept; + + /** + * @brief Creates a new LinearGradient object. + * + * @return A new LinearGradient object. + */ + static std::unique_ptr<LinearGradient> gen() noexcept; + + /** + * @brief Return the unique id value of this class. + * + * This method can be referred for identifying the LinearGradient class type. + * + * @return The type id of the LinearGradient class. + * + * @BETA_API + */ + static uint32_t identifier() noexcept; + + _TVG_DECLARE_PRIVATE(LinearGradient); +}; + + +/** + * @class RadialGradient + * + * @brief A class representing the radial gradient fill of the Shape object. + * + */ +class TVG_EXPORT RadialGradient final : public Fill +{ +public: + ~RadialGradient(); + + /** + * @brief Sets the radial gradient bounds. + * + * The radial gradient bounds are defined as a circle centered in a given point (@p cx, @p cy) of a given radius. + * + * @param[in] cx The horizontal coordinate of the center of the bounding circle. + * @param[in] cy The vertical coordinate of the center of the bounding circle. + * @param[in] radius The radius of the bounding circle. + * + * @return Result::Success when succeed, Result::InvalidArguments in case the @p radius value is zero or less. + */ + Result radial(float cx, float cy, float radius) noexcept; + + /** + * @brief Gets the radial gradient bounds. + * + * The radial gradient bounds are defined as a circle centered in a given point (@p cx, @p cy) of a given radius. + * + * @param[out] cx The horizontal coordinate of the center of the bounding circle. + * @param[out] cy The vertical coordinate of the center of the bounding circle. + * @param[out] radius The radius of the bounding circle. + * + * @return Result::Success when succeed. + */ + Result radial(float* cx, float* cy, float* radius) const noexcept; + + /** + * @brief Creates a new RadialGradient object. + * + * @return A new RadialGradient object. + */ + static std::unique_ptr<RadialGradient> gen() noexcept; + + /** + * @brief Return the unique id value of this class. + * + * This method can be referred for identifying the RadialGradient class type. + * + * @return The type id of the RadialGradient class. + * + * @BETA_API + */ + static uint32_t identifier() noexcept; + + _TVG_DECLARE_PRIVATE(RadialGradient); +}; + + +/** + * @class Shape + * + * @brief A class representing two-dimensional figures and their properties. + * + * A shape has three major properties: shape outline, stroking, filling. The outline in the Shape is retained as the path. + * Path can be composed by accumulating primitive commands such as moveTo(), lineTo(), cubicTo(), or complete shape interfaces such as appendRect(), appendCircle(), etc. + * Path can consists of sub-paths. One sub-path is determined by a close command. + * + * The stroke of Shape is an optional property in case the Shape needs to be represented with/without the outline borders. + * It's efficient since the shape path and the stroking path can be shared with each other. It's also convenient when controlling both in one context. + */ +class TVG_EXPORT Shape final : public Paint +{ +public: + ~Shape(); + + /** + * @brief Resets the properties of the shape path. + * + * The color, the fill and the stroke properties are retained. + * + * @return Result::Success when succeed. + * + * @note The memory, where the path data is stored, is not deallocated at this stage for caching effect. + */ + Result reset() noexcept; + + /** + * @brief Sets the initial point of the sub-path. + * + * The value of the current point is set to the given point. + * + * @param[in] x The horizontal coordinate of the initial point of the sub-path. + * @param[in] y The vertical coordinate of the initial point of the sub-path. + * + * @return Result::Success when succeed. + */ + Result moveTo(float x, float y) noexcept; + + /** + * @brief Adds a new point to the sub-path, which results in drawing a line from the current point to the given end-point. + * + * The value of the current point is set to the given end-point. + * + * @param[in] x The horizontal coordinate of the end-point of the line. + * @param[in] y The vertical coordinate of the end-point of the line. + * + * @return Result::Success when succeed. + * + * @note In case this is the first command in the path, it corresponds to the moveTo() call. + */ + Result lineTo(float x, float y) noexcept; + + /** + * @brief Adds new points to the sub-path, which results in drawing a cubic Bezier curve starting + * at the current point and ending at the given end-point (@p x, @p y) using the control points (@p cx1, @p cy1) and (@p cx2, @p cy2). + * + * The value of the current point is set to the given end-point. + * + * @param[in] cx1 The horizontal coordinate of the 1st control point. + * @param[in] cy1 The vertical coordinate of the 1st control point. + * @param[in] cx2 The horizontal coordinate of the 2nd control point. + * @param[in] cy2 The vertical coordinate of the 2nd control point. + * @param[in] x The horizontal coordinate of the end-point of the curve. + * @param[in] y The vertical coordinate of the end-point of the curve. + * + * @return Result::Success when succeed. + * + * @note In case this is the first command in the path, no data from the path are rendered. + */ + Result cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) noexcept; + + /** + * @brief Closes the current sub-path by drawing a line from the current point to the initial point of the sub-path. + * + * The value of the current point is set to the initial point of the closed sub-path. + * + * @return Result::Success when succeed. + * + * @note In case the sub-path does not contain any points, this function has no effect. + */ + Result close() noexcept; + + /** + * @brief Appends a rectangle to the path. + * + * The rectangle with rounded corners can be achieved by setting non-zero values to @p rx and @p ry arguments. + * The @p rx and @p ry values specify the radii of the ellipse defining the rounding of the corners. + * + * The position of the rectangle is specified by the coordinates of its upper left corner - @p x and @p y arguments. + * + * The rectangle is treated as a new sub-path - it is not connected with the previous sub-path. + * + * The value of the current point is set to (@p x + @p rx, @p y) - in case @p rx is greater + * than @p w/2 the current point is set to (@p x + @p w/2, @p y) + * + * @param[in] x The horizontal coordinate of the upper left corner of the rectangle. + * @param[in] y The vertical coordinate of the upper left corner of the rectangle. + * @param[in] w The width of the rectangle. + * @param[in] h The height of the rectangle. + * @param[in] rx The x-axis radius of the ellipse defining the rounded corners of the rectangle. + * @param[in] ry The y-axis radius of the ellipse defining the rounded corners of the rectangle. + * + * @return Result::Success when succeed. + * + * @note For @p rx and @p ry greater than or equal to the half of @p w and the half of @p h, respectively, the shape become an ellipse. + */ + Result appendRect(float x, float y, float w, float h, float rx, float ry) noexcept; + + /** + * @brief Appends an ellipse to the path. + * + * The position of the ellipse is specified by the coordinates of its center - @p cx and @p cy arguments. + * + * The ellipse is treated as a new sub-path - it is not connected with the previous sub-path. + * + * The value of the current point is set to (@p cx, @p cy - @p ry). + * + * @param[in] cx The horizontal coordinate of the center of the ellipse. + * @param[in] cy The vertical coordinate of the center of the ellipse. + * @param[in] rx The x-axis radius of the ellipse. + * @param[in] ry The y-axis radius of the ellipse. + * + * @return Result::Success when succeed. + */ + Result appendCircle(float cx, float cy, float rx, float ry) noexcept; + + /** + * @brief Appends a circular arc to the path. + * + * The arc is treated as a new sub-path - it is not connected with the previous sub-path. + * The current point value is set to the end-point of the arc in case @p pie is @c false, and to the center of the arc otherwise. + * + * @param[in] cx The horizontal coordinate of the center of the arc. + * @param[in] cy The vertical coordinate of the center of the arc. + * @param[in] radius The radius of the arc. + * @param[in] startAngle The start angle of the arc given in degrees, measured counter-clockwise from the horizontal line. + * @param[in] sweep The central angle of the arc given in degrees, measured counter-clockwise from @p startAngle. + * @param[in] pie Specifies whether to draw radii from the arc's center to both of its end-point - drawn if @c true. + * + * @return Result::Success when succeed. + * + * @note Setting @p sweep value greater than 360 degrees, is equivalent to calling appendCircle(cx, cy, radius, radius). + */ + Result appendArc(float cx, float cy, float radius, float startAngle, float sweep, bool pie) noexcept; + + /** + * @brief Appends a given sub-path to the path. + * + * The current point value is set to the last point from the sub-path. + * For each command from the @p cmds array, an appropriate number of points in @p pts array should be specified. + * If the number of points in the @p pts array is different than the number required by the @p cmds array, the shape with this sub-path will not be displayed on the screen. + * + * @param[in] cmds The array of the commands in the sub-path. + * @param[in] cmdCnt The number of the sub-path's commands. + * @param[in] pts The array of the two-dimensional points. + * @param[in] ptsCnt The number of the points in the @p pts array. + * + * @return Result::Success when succeed, Result::InvalidArguments otherwise. + * + * @note The interface is designed for optimal path setting if the caller has a completed path commands already. + */ + Result appendPath(const PathCommand* cmds, uint32_t cmdCnt, const Point* pts, uint32_t ptsCnt) noexcept; + + /** + * @brief Sets the stroke width for all of the figures from the path. + * + * @param[in] width The width of the stroke. The default value is 0. + * + * @return Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result stroke(float width) noexcept; + + /** + * @brief Sets the color of the stroke for all of the figures from the path. + * + * @param[in] r The red color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] g The green color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] b The blue color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. The default value is 0. + * + * @return Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result stroke(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept; + + /** + * @brief Sets the gradient fill of the stroke for all of the figures from the path. + * + * @param[in] f The gradient fill. + * + * @retval Result::Success When succeed. + * @retval Result::FailedAllocation An internal error with a memory allocation for an object to be filled. + * @retval Result::MemoryCorruption In case a @c nullptr is passed as the argument. + */ + Result stroke(std::unique_ptr<Fill> f) noexcept; + + /** + * @brief Sets the dash pattern of the stroke. + * + * @param[in] dashPattern The array of consecutive pair values of the dash length and the gap length. + * @param[in] cnt The length of the @p dashPattern array. + * + * @retval Result::Success When succeed. + * @retval Result::FailedAllocation An internal error with a memory allocation for an object to be dashed. + * @retval Result::InvalidArguments In case @p dashPattern is @c nullptr and @p cnt > 0, @p cnt is zero, any of the dash pattern values is zero or less. + * + * @note To reset the stroke dash pattern, pass @c nullptr to @p dashPattern and zero to @p cnt. + * @warning @p cnt must be greater than 1 if the dash pattern is valid. + */ + Result stroke(const float* dashPattern, uint32_t cnt) noexcept; + + /** + * @brief Sets the cap style of the stroke in the open sub-paths. + * + * @param[in] cap The cap style value. The default value is @c StrokeCap::Square. + * + * @return Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result stroke(StrokeCap cap) noexcept; + + /** + * @brief Sets the join style for stroked path segments. + * + * The join style is used for joining the two line segment while stroking the path. + * + * @param[in] join The join style value. The default value is @c StrokeJoin::Bevel. + * + * @return Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result stroke(StrokeJoin join) noexcept; + + /** + * @brief Sets the solid color for all of the figures from the path. + * + * The parts of the shape defined as inner are colored. + * + * @param[in] r The red color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] g The green color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] b The blue color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. The default value is 0. + * + * @return Result::Success when succeed. + * + * @note Either a solid color or a gradient fill is applied, depending on what was set as last. + */ + Result fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept; + + /** + * @brief Sets the gradient fill for all of the figures from the path. + * + * The parts of the shape defined as inner are filled. + * + * @param[in] f The unique pointer to the gradient fill. + * + * @return Result::Success when succeed, Result::MemoryCorruption otherwise. + * + * @note Either a solid color or a gradient fill is applied, depending on what was set as last. + */ + Result fill(std::unique_ptr<Fill> f) noexcept; + + /** + * @brief Sets the fill rule for the Shape object. + * + * @param[in] r The fill rule value. The default value is @c FillRule::Winding. + * + * @return Result::Success when succeed. + */ + Result fill(FillRule r) noexcept; + + /** + * @brief Gets the commands data of the path. + * + * @param[out] cmds The pointer to the array of the commands from the path. + * + * @return The length of the @p cmds array when succeed, zero otherwise. + */ + uint32_t pathCommands(const PathCommand** cmds) const noexcept; + + /** + * @brief Gets the points values of the path. + * + * @param[out] pts The pointer to the array of the two-dimensional points from the path. + * + * @return The length of the @p pts array when succeed, zero otherwise. + */ + uint32_t pathCoords(const Point** pts) const noexcept; + + /** + * @brief Gets the pointer to the gradient fill of the shape. + * + * @return The pointer to the gradient fill of the stroke when succeed, @c nullptr in case no fill was set. + */ + const Fill* fill() const noexcept; + + /** + * @brief Gets the solid color of the shape. + * + * @param[out] r The red color channel value in the range [0 ~ 255]. + * @param[out] g The green color channel value in the range [0 ~ 255]. + * @param[out] b The blue color channel value in the range [0 ~ 255]. + * @param[out] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. + * + * @return Result::Success when succeed. + */ + Result fillColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const noexcept; + + /** + * @brief Gets the fill rule value. + * + * @return The fill rule value of the shape. + */ + FillRule fillRule() const noexcept; + + /** + * @brief Gets the stroke width. + * + * @return The stroke width value when succeed, zero if no stroke was set. + */ + float strokeWidth() const noexcept; + + /** + * @brief Gets the color of the shape's stroke. + * + * @param[out] r The red color channel value in the range [0 ~ 255]. + * @param[out] g The green color channel value in the range [0 ~ 255]. + * @param[out] b The blue color channel value in the range [0 ~ 255]. + * @param[out] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. + * + * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + */ + Result strokeColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const noexcept; + + /** + * @brief Gets the pointer to the gradient fill of the stroke. + * + * @return The pointer to the gradient fill of the stroke when succeed, @c nullptr otherwise. + */ + const Fill* strokeFill() const noexcept; + + /** + * @brief Gets the dash pattern of the stroke. + * + * @param[out] dashPattern The pointer to the memory, where the dash pattern array is stored. + * + * @return The length of the @p dashPattern array. + */ + uint32_t strokeDash(const float** dashPattern) const noexcept; + + /** + * @brief Gets the cap style used for stroking the path. + * + * @return The cap style value of the stroke. + */ + StrokeCap strokeCap() const noexcept; + + /** + * @brief Gets the join style value used for stroking the path. + * + * @return The join style value of the stroke. + */ + StrokeJoin strokeJoin() const noexcept; + + /** + * @brief Creates a new Shape object. + * + * @return A new Shape object. + */ + static std::unique_ptr<Shape> gen() noexcept; + + /** + * @brief Return the unique id value of this class. + * + * This method can be referred for identifying the Shape class type. + * + * @return The type id of the Shape class. + * + * @BETA_API + */ + static uint32_t identifier() noexcept; + + _TVG_DECLARE_PRIVATE(Shape); +}; + + +/** + * @class Picture + * + * @brief A class representing an image read in one of the supported formats: raw, svg, png, jpg and etc. + * Besides the methods inherited from the Paint, it provides methods to load & draw images on the canvas. + * + * @note Supported formats are depended on the available TVG loaders. + */ +class TVG_EXPORT Picture final : public Paint +{ +public: + ~Picture(); + + /** + * @brief Loads a picture data directly from a file. + * + * @param[in] path A path to the picture file. + * + * @retval Result::Success When succeed. + * @retval Result::InvalidArguments In case the @p path is invalid. + * @retval Result::NonSupport When trying to load a file with an unknown extension. + * @retval Result::Unknown If an error occurs at a later stage. + * + * @note The Load behavior can be asynchronous if the assigned thread number is greater than zero. + * @see Initializer::init() + */ + Result load(const std::string& path) noexcept; + + /** + * @brief Loads a picture data from a memory block of a given size. + * + * @param[in] data A pointer to a memory location where the content of the picture file is stored. + * @param[in] size The size in bytes of the memory occupied by the @p data. + * @param[in] copy Decides whether the data should be copied into the engine local buffer. + * + * @retval Result::Success When succeed. + * @retval Result::InvalidArguments In case no data are provided or the @p size is zero or less. + * @retval Result::NonSupport When trying to load a file with an unknown extension. + * @retval Result::Unknown If an error occurs at a later stage. + * + * @warning: you have responsibility to release the @p data memory if the @p copy is true + * @deprecated Use load(const char* data, uint32_t size, const std::string& mimeType, bool copy) instead. + * @see Result load(const char* data, uint32_t size, const std::string& mimeType, bool copy = false) noexcept + */ + TVG_DEPRECATED Result load(const char* data, uint32_t size, bool copy = false) noexcept; + + /** + * @brief Loads a picture data from a memory block of a given size. + * + * @param[in] data A pointer to a memory location where the content of the picture file is stored. + * @param[in] size The size in bytes of the memory occupied by the @p data. + * @param[in] mimeType Mimetype or extension of data such as "jpg", "jpeg", "svg", "svg+xml", "png", etc. In case an empty string or an unknown type is provided, the loaders will be tried one by one. + * @param[in] copy If @c true the data are copied into the engine local buffer, otherwise they are not. + * + * @retval Result::Success When succeed. + * @retval Result::InvalidArguments In case no data are provided or the @p size is zero or less. + * @retval Result::NonSupport When trying to load a file with an unknown extension. + * @retval Result::Unknown If an error occurs at a later stage. + * + * @warning: It's the user responsibility to release the @p data memory if the @p copy is @c true. + * + * @since 0.5 + */ + Result load(const char* data, uint32_t size, const std::string& mimeType, bool copy = false) noexcept; + + /** + * @brief Resizes the picture content to the given width and height. + * + * The picture content is resized while keeping the default size aspect ratio. + * The scaling factor is established for each of dimensions and the smaller value is applied to both of them. + * + * @param[in] w A new width of the image in pixels. + * @param[in] h A new height of the image in pixels. + * + * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + */ + Result size(float w, float h) noexcept; + + /** + * @brief Gets the size of the image. + * + * @param[out] w The width of the image in pixels. + * @param[out] h The height of the image in pixels. + * + * @return Result::Success when succeed. + */ + Result size(float* w, float* h) const noexcept; + + /** + * @brief Gets the pixels information of the picture. + * + * @note The data must be pre-multiplied by the alpha channels. + * + * @warning Please do not use it, this API is not official one. It could be modified in the next version. + * + * @BETA_API + */ + const uint32_t* data(uint32_t* w, uint32_t* h) const noexcept; + + /** + * @brief Loads a raw data from a memory block with a given size. + * + * @warning Please do not use it, this API is not official one. It could be modified in the next version. + * + * @BETA_API + */ + Result load(uint32_t* data, uint32_t w, uint32_t h, bool copy) noexcept; + + /** + * @brief Gets the position and the size of the loaded SVG picture. + * + * @warning Please do not use it, this API is not official one. It could be modified in the next version. + * + * @BETA_API + */ + Result viewbox(float* x, float* y, float* w, float* h) const noexcept; + + /** + * @brief Creates a new Picture object. + * + * @return A new Picture object. + */ + static std::unique_ptr<Picture> gen() noexcept; + + /** + * @brief Return the unique id value of this class. + * + * This method can be referred for identifying the Picture class type. + * + * @return The type id of the Picture class. + * + * @BETA_API + */ + static uint32_t identifier() noexcept; + + _TVG_DECLARE_PRIVATE(Picture); +}; + + +/** + * @class Scene + * + * @brief A class to composite children paints. + * + * As the traditional graphics rendering method, TVG also enables scene-graph mechanism. + * This feature supports an array function for managing the multiple paints as one group paint. + * + * As a group, the scene can be transformed, made translucent and composited with other target paints, + * its children will be affected by the scene world. + */ +class TVG_EXPORT Scene final : public Paint +{ +public: + ~Scene(); + + /** + * @brief Passes drawing elements to the Scene using Paint objects. + * + * Only the paints pushed into the scene will be the drawn targets. + * The paints are retained by the scene until Scene::clear() is called. + * If you know the number of the pushed objects in advance, please call Scene::reserve(). + * + * @param[in] paint A Paint object to be drawn. + * + * @return Result::Success when succeed, Result::MemoryCorruption otherwise. + * + * @note The rendering order of the paints is the same as the order as they were pushed. Consider sorting the paints before pushing them if you intend to use layering. + * @see Scene::reserve() + */ + Result push(std::unique_ptr<Paint> paint) noexcept; + + /** + * @brief Sets the size of the container, where all the paints pushed into the Scene are stored. + * + * If the number of objects pushed into the scene is known in advance, calling the function + * prevents multiple memory reallocation, thus improving the performance. + * + * @param[in] size The number of objects for which the memory is to be reserved. + * + * @return Result::Success when succeed, Result::FailedAllocation otherwise. + */ + Result reserve(uint32_t size) noexcept; + + /** + * @brief Sets the total number of the paints pushed into the scene to be zero. + * Depending on the value of the @p free argument, the paints are freed or not. + * + * @param[in] free If @c true, the memory occupied by paints is deallocated, otherwise it is not. + * + * @return Result::Success when succeed + * + * @warning If you don't free the paints they become dangled. They are supposed to be reused, otherwise you are responsible for their lives. Thus please use the @p free argument only when you know how it works, otherwise it's not recommended. + * + * @since 0.2 + */ + Result clear(bool free = true) noexcept; + + /** + * @brief Creates a new Scene object. + * + * @return A new Scene object. + */ + static std::unique_ptr<Scene> gen() noexcept; + + /** + * @brief Return the unique id value of this class. + * + * This method can be referred for identifying the Scene class type. + * + * @return The type id of the Scene class. + * + * @BETA_API + */ + static uint32_t identifier() noexcept; + + _TVG_DECLARE_PRIVATE(Scene); +}; + + +/** + * @class SwCanvas + * + * @brief A class for the rendering graphical elements with a software raster engine. + */ +class TVG_EXPORT SwCanvas final : public Canvas +{ +public: + ~SwCanvas(); + + /** + * @brief Enumeration specifying the methods of combining the 8-bit color channels into 32-bit color. + */ + enum Colorspace + { + ABGR8888 = 0, ///< The channels are joined in the order: alpha, blue, green, red. Colors are alpha-premultiplied. + ARGB8888, ///< The channels are joined in the order: alpha, red, green, blue. Colors are alpha-premultiplied. + ABGR8888_STRAIGHT, ///< @BETA_API The channels are joined in the order: alpha, blue, green, red. Colors are un-alpha-premultiplied. + ARGB8888_STRAIGHT, ///< @BETA_API The channels are joined in the order: alpha, red, green, blue. Colors are un-alpha-premultiplied. + }; + + /** + * @brief Enumeration specifying the methods of Memory Pool behavior policy. + * @since 0.4 + */ + enum MempoolPolicy + { + Default = 0, ///< Default behavior that ThorVG is designed to. + Shareable, ///< Memory Pool is shared among the SwCanvases. + Individual ///< Allocate designated memory pool that is only used by current instance. + }; + + /** + * @brief Sets the target buffer for the rasterization. + * + * The buffer of a desirable size should be allocated and owned by the caller. + * + * @param[in] buffer A pointer to a memory block of the size @p stride x @p h, where the raster data are stored. + * @param[in] stride The stride of the raster image - greater than or equal to @p w. + * @param[in] w The width of the raster image. + * @param[in] h The height of the raster image. + * @param[in] cs The value specifying the way the 32-bits colors should be read/written. + * + * @retval Result::Success When succeed. + * @retval Result::MemoryCorruption When casting in the internal function implementation failed. + * @retval Result::InvalidArguments In case no valid pointer is provided or the width, or the height or the stride is zero. + * @retval Result::NonSupport In case the software engine is not supported. + * + * @warning Do not access @p buffer during Canvas::draw() - Canvas::sync(). It should not be accessed while TVG is writing on it. + */ + Result target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, Colorspace cs) noexcept; + + /** + * @brief Set sw engine memory pool behavior policy. + * + * Basically ThorVG draws a lot of shapes, it allocates/deallocates a few chunk of memory + * while processing rendering. It internally uses one shared memory pool + * which can be reused among the canvases in order to avoid memory overhead. + * + * Thus ThorVG suggests using a memory pool policy to satisfy user demands, + * if it needs to guarantee the thread-safety of the internal data access. + * + * @param[in] policy The method specifying the Memory Pool behavior. The default value is @c MempoolPolicy::Default. + * + * @retval Result::Success When succeed. + * @retval Result::InsufficientCondition If the canvas contains some paints already. + * @retval Result::NonSupport In case the software engine is not supported. + * + * @note When @c policy is set as @c MempoolPolicy::Individual, the current instance of canvas uses its own individual + * memory data, which is not shared with others. This is necessary when the canvas is accessed on a worker-thread. + * + * @warning It's not allowed after pushing any paints. + * + * @since 0.4 + */ + Result mempool(MempoolPolicy policy) noexcept; + + /** + * @brief Creates a new SwCanvas object. + * @return A new SwCanvas object. + */ + static std::unique_ptr<SwCanvas> gen() noexcept; + + _TVG_DECLARE_PRIVATE(SwCanvas); +}; + + +/** + * @class GlCanvas + * + * @brief A class for the rendering graphic elements with a GL raster engine. + * + * @warning Please do not use it. This class is not fully supported yet. + * + * @BETA_API + */ +class TVG_EXPORT GlCanvas final : public Canvas +{ +public: + ~GlCanvas(); + + /** + * @brief Sets the target buffer for the rasterization. + * + * @warning Please do not use it, this API is not official one. It could be modified in the next version. + * + * @BETA_API + */ + Result target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h) noexcept; + + /** + * @brief Creates a new GlCanvas object. + * + * @return A new GlCanvas object. + * + * @BETA_API + */ + static std::unique_ptr<GlCanvas> gen() noexcept; + + _TVG_DECLARE_PRIVATE(GlCanvas); +}; + + +/** + * @class Initializer + * + * @brief A class that enables initialization and termination of the TVG engines. + */ +class TVG_EXPORT Initializer final +{ +public: + /** + * @brief Initializes TVG engines. + * + * TVG requires the running-engine environment. + * TVG runs its own task-scheduler for parallelizing rendering tasks efficiently. + * You can indicate the number of threads, the count of which is designated @p threads. + * In the initialization step, TVG will generate/spawn the threads as set by @p threads count. + * + * @param[in] engine The engine types to initialize. This is relative to the Canvas types, in which it will be used. For multiple backends bitwise operation is allowed. + * @param[in] threads The number of additional threads. Zero indicates only the main thread is to be used. + * + * @retval Result::Success When succeed. + * @retval Result::FailedAllocation An internal error possibly with memory allocation. + * @retval Result::InvalidArguments If unknown engine type chosen. + * @retval Result::NonSupport In case the engine type is not supported on the system. + * @retval Result::Unknown Others. + * + * @note The Initializer keeps track of the number of times it was called. Threads count is fixed at the first init() call. + * @see Initializer::term() + */ + static Result init(CanvasEngine engine, uint32_t threads) noexcept; + + /** + * @brief Terminates TVG engines. + * + * @param[in] engine The engine types to terminate. This is relative to the Canvas types, in which it will be used. For multiple backends bitwise operation is allowed + * + * @retval Result::Success When succeed. + * @retval Result::InsufficientCondition In case there is nothing to be terminated. + * @retval Result::InvalidArguments If unknown engine type chosen. + * @retval Result::NonSupport In case the engine type is not supported on the system. + * @retval Result::Unknown Others. + * + * @note Initializer does own reference counting for multiple calls. + * @see Initializer::init() + */ + static Result term(CanvasEngine engine) noexcept; + + _TVG_DISABLE_CTOR(Initializer); +}; + + +/** + * @class Saver + * + * @brief A class for exporting a paint object into a specified file, from which to recover the paint data later. + * + * ThorVG provides a feature for exporting & importing paint data. The Saver role is to export the paint data to a file. + * It's useful when you need to save the composed scene or image from a paint object and recreate it later. + * + * The file format is decided by the extension name(i.e. "*.tvg") while the supported formats depend on the TVG packaging environment. + * If it doesn't support the file format, the save() method returns the @c Result::NonSuppport result. + * + * Once you export a paint to the file successfully, you can recreate it using the Picture class. + * + * @see Picture::load() + * + * @since 0.5 + */ +class TVG_EXPORT Saver final +{ +public: + ~Saver(); + + /** + * @brief Exports the given @p paint data to the given @p path + * + * If the saver module supports any compression mechanism, it will optimize the data size. + * This might affect the encoding/decoding time in some cases. You can turn off the compression + * if you wish to optimize for speed. + * + * @param[in] paint The paint to be saved with all its associated properties. + * @param[in] path A path to the file, in which the paint data is to be saved. + * @param[in] compress If @c true then compress data if possible. + * + * @retval Result::Success When succeed. + * @retval Result::InsufficientCondition If currently saving other resources. + * @retval Result::NonSupport When trying to save a file with an unknown extension or in an unsupported format. + * @retval Result::MemoryCorruption An internal error. + * @retval Result::Unknown In case an empty paint is to be saved. + * + * @note Saving can be asynchronous if the assigned thread number is greater than zero. To guarantee the saving is done, call sync() afterwards. + * @see Saver::sync() + * + * @since 0.5 + */ + Result save(std::unique_ptr<Paint> paint, const std::string& path, bool compress = true) noexcept; + + /** + * @brief Guarantees that the saving task is finished. + * + * The behavior of the Saver works on a sync/async basis, depending on the threading setting of the Initializer. + * Thus, if you wish to have a benefit of it, you must call sync() after the save() in the proper delayed time. + * Otherwise, you can call sync() immediately. + * + * @retval Result::Success when succeed. + * @retval Result::InsufficientCondition otherwise. + * + * @note The asynchronous tasking is dependent on the Saver module implementation. + * @see Saver::save() + * + * @since 0.5 + */ + Result sync() noexcept; + + /** + * @brief Creates a new Saver object. + * + * @return A new Saver object. + * + * @since 0.5 + */ + static std::unique_ptr<Saver> gen() noexcept; + + _TVG_DECLARE_PRIVATE(Saver); +}; + + +/** + * @class Accessor + * + * @brief The Accessor is a utility class to debug the Scene structure by traversing the scene-tree. + * + * The Accessor helps you search specific nodes to read the property information, figure out the structure of the scene tree and its size. + * + * @warning We strongly warn you not to change the paints of a scene unless you really know the design-structure. + * + * @BETA_API + */ +class TVG_EXPORT Accessor final +{ +public: + ~Accessor(); + + /** + * @brief Access the Picture scene stree nodes. + * + * @param[in] picture The picture node to traverse the internal scene-tree. + * @param[in] func The callback function calling for every paint nodes of the Picture. + * + * @return Return the given @p picture instance. + * + * @note The bitmap based picture might not have the scene-tree. + * + * @BETA_API + */ + std::unique_ptr<Picture> access(std::unique_ptr<Picture> picture, bool(*func)(const Paint* paint)) noexcept; + + /** + * @brief Creates a new Accessor object. + * + * @return A new Accessor object. + * + * @BETA_API + */ + static std::unique_ptr<Accessor> gen() noexcept; + + _TVG_DECLARE_PRIVATE(Accessor); +}; + +/** @}*/ + +} //namespace + +#ifdef __cplusplus +} +#endif + +#endif //_THORVG_H_ diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwCommon.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwCommon.h new file mode 100644 index 0000000000..e0ffc1fb97 --- /dev/null +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwCommon.h @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_SW_COMMON_H_ +#define _TVG_SW_COMMON_H_ + +#include "tvgCommon.h" +#include "tvgRender.h" + +#if 0 +#include <sys/time.h> +static double timeStamp() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return (tv.tv_sec + tv.tv_usec / 1000000.0); +} +#endif + +#define SW_CURVE_TYPE_POINT 0 +#define SW_CURVE_TYPE_CUBIC 1 +#define SW_ANGLE_PI (180L << 16) +#define SW_ANGLE_2PI (SW_ANGLE_PI << 1) +#define SW_ANGLE_PI2 (SW_ANGLE_PI >> 1) +#define SW_ANGLE_PI4 (SW_ANGLE_PI >> 2) + +using SwCoord = signed long; +using SwFixed = signed long long; + +struct SwPoint +{ + SwCoord x, y; + + SwPoint& operator+=(const SwPoint& rhs) + { + x += rhs.x; + y += rhs.y; + return *this; + } + + SwPoint operator+(const SwPoint& rhs) const + { + return {x + rhs.x, y + rhs.y}; + } + + SwPoint operator-(const SwPoint& rhs) const + { + return {x - rhs.x, y - rhs.y}; + } + + bool operator==(const SwPoint& rhs) const + { + return (x == rhs.x && y == rhs.y); + } + + bool operator!=(const SwPoint& rhs) const + { + return (x != rhs.x || y != rhs.y); + } + + bool zero() const + { + if (x == 0 && y == 0) return true; + else return false; + } + + bool small() const + { + //2 is epsilon... + if (abs(x) < 2 && abs(y) < 2) return true; + else return false; + } + +}; + +struct SwSize +{ + SwCoord w, h; +}; + +struct SwOutline +{ + SwPoint* pts; //the outline's points + uint16_t ptsCnt; //number of points in the glyph + uint16_t reservedPtsCnt; + uint16_t* cntrs; //the contour end points + uint16_t cntrsCnt; //number of contours in glyph + uint16_t reservedCntrsCnt; + uint8_t* types; //curve type + bool* closed; //opened or closed path? + FillRule fillRule; +}; + +struct SwSpan +{ + uint16_t x, y; + uint16_t len; + uint8_t coverage; +}; + +struct SwRleData +{ + SwSpan *spans; + uint32_t alloc; + uint32_t size; +}; + +struct SwBBox +{ + SwPoint min, max; + + void reset() + { + min.x = min.y = max.x = max.y = 0; + } +}; + +struct SwFill +{ + struct SwLinear { + float dx, dy; + float len; + float offset; + }; + + struct SwRadial { + float a11, a12, shiftX; + float a21, a22, shiftY; + float detSecDeriv; + float a; + }; + + union { + SwLinear linear; + SwRadial radial; + }; + + uint32_t* ctable; + FillSpread spread; + + bool translucent; +}; + +struct SwStrokeBorder +{ + uint32_t ptsCnt; + uint32_t maxPts; + SwPoint* pts; + uint8_t* tags; + int32_t start; //index of current sub-path start point + bool movable; //true: for ends of lineto borders +}; + +struct SwStroke +{ + SwFixed angleIn; + SwFixed angleOut; + SwPoint center; + SwFixed lineLength; + SwFixed subPathAngle; + SwPoint ptStartSubPath; + SwFixed subPathLineLength; + SwFixed width; + + StrokeCap cap; + StrokeJoin join; + StrokeJoin joinSaved; + SwFill* fill = nullptr; + + SwStrokeBorder borders[2]; + + float sx, sy; + + bool firstPt; + bool closedSubPath; + bool handleWideStrokes; +}; + +struct SwDashStroke +{ + SwOutline* outline; + float curLen; + int32_t curIdx; + Point ptStart; + Point ptCur; + float* pattern; + uint32_t cnt; + bool curOpGap; +}; + +struct SwShape +{ + SwOutline* outline = nullptr; + SwStroke* stroke = nullptr; + SwFill* fill = nullptr; + SwRleData* rle = nullptr; + SwRleData* strokeRle = nullptr; + SwBBox bbox; //Keep it boundary without stroke region. Using for optimal filling. + + bool fastTrack = false; //Fast Track: axis-aligned rectangle without any clips? +}; + +struct SwImage +{ + SwOutline* outline = nullptr; + SwRleData* rle = nullptr; + uint32_t* data = nullptr; + uint32_t w, h, stride; + int32_t ox = 0; //offset x + int32_t oy = 0; //offset y + float scale; + + bool direct = false; //draw image directly (with offset) + bool scaled = false; //draw scaled image +}; + +struct SwBlender +{ + uint32_t (*join)(uint8_t r, uint8_t g, uint8_t b, uint8_t a); +}; + +struct SwCompositor; + +struct SwSurface : Surface +{ + SwBlender blender; //mandatory + SwCompositor* compositor = nullptr; //compositor (optional) +}; + +struct SwCompositor : Compositor +{ + SwSurface* recoverSfc; //Recover surface when composition is started + SwCompositor* recoverCmp; //Recover compositor when composition is done + SwImage image; + SwBBox bbox; + bool valid; +}; + +struct SwMpool +{ + SwOutline* outline; + SwOutline* strokeOutline; + unsigned allocSize; +}; + +static inline SwCoord TO_SWCOORD(float val) +{ + return SwCoord(val * 64.0f); +} + +static inline uint32_t ALPHA_BLEND(uint32_t c, uint32_t a) +{ + return (((((c >> 8) & 0x00ff00ff) * a + 0x00ff00ff) & 0xff00ff00) + + ((((c & 0x00ff00ff) * a + 0x00ff00ff) >> 8) & 0x00ff00ff)); +} + +static inline uint32_t INTERPOLATE(uint32_t a, uint32_t c0, uint32_t c1) +{ + return (((((((c0 >> 8) & 0xff00ff) - ((c1 >> 8) & 0xff00ff)) * a) + (c1 & 0xff00ff00)) & 0xff00ff00) + ((((((c0 & 0xff00ff) - (c1 & 0xff00ff)) * a) >> 8) + (c1 & 0xff00ff)) & 0xff00ff)); +} + +static inline SwCoord HALF_STROKE(float width) +{ + return TO_SWCOORD(width * 0.5f); +} + +int64_t mathMultiply(int64_t a, int64_t b); +int64_t mathDivide(int64_t a, int64_t b); +int64_t mathMulDiv(int64_t a, int64_t b, int64_t c); +void mathRotate(SwPoint& pt, SwFixed angle); +SwFixed mathTan(SwFixed angle); +SwFixed mathAtan(const SwPoint& pt); +SwFixed mathCos(SwFixed angle); +SwFixed mathSin(SwFixed angle); +void mathSplitCubic(SwPoint* base); +SwFixed mathDiff(SwFixed angle1, SwFixed angle2); +SwFixed mathLength(const SwPoint& pt); +bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut); +SwFixed mathMean(SwFixed angle1, SwFixed angle2); +SwPoint mathTransform(const Point* to, const Matrix* transform); +bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack); +bool mathClipBBox(const SwBBox& clipper, SwBBox& clipee); + +void shapeReset(SwShape* shape); +bool shapePrepare(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite); +bool shapePrepared(const SwShape* shape); +bool shapeGenRle(SwShape* shape, const Shape* sdata, bool antiAlias); +void shapeDelOutline(SwShape* shape, SwMpool* mpool, uint32_t tid); +void shapeResetStroke(SwShape* shape, const Shape* sdata, const Matrix* transform); +bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid); +void shapeFree(SwShape* shape); +void shapeDelStroke(SwShape* shape); +bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable); +bool shapeGenStrokeFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable); +void shapeResetFill(SwShape* shape); +void shapeResetStrokeFill(SwShape* shape); +void shapeDelFill(SwShape* shape); +void shapeDelStrokeFill(SwShape* shape); + +void strokeReset(SwStroke* stroke, const Shape* shape, const Matrix* transform); +bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline); +SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid); +void strokeFree(SwStroke* stroke); + +bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid); +bool imageGenRle(SwImage* image, const SwBBox& renderRegion, bool antiAlias); +void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid); +void imageReset(SwImage* image); +void imageFree(SwImage* image); + +bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable); +void fillReset(SwFill* fill); +void fillFree(SwFill* fill); +void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len); +void fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len); + +SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& renderRegion, bool antiAlias); +void rleFree(SwRleData* rle); +void rleReset(SwRleData* rle); +void rleClipPath(SwRleData *rle, const SwRleData *clip); +void rleClipRect(SwRleData *rle, const SwBBox* clip); + +SwMpool* mpoolInit(uint32_t threads); +bool mpoolTerm(SwMpool* mpool); +bool mpoolClear(SwMpool* mpool); +SwOutline* mpoolReqOutline(SwMpool* mpool, unsigned idx); +void mpoolRetOutline(SwMpool* mpool, unsigned idx); +SwOutline* mpoolReqStrokeOutline(SwMpool* mpool, unsigned idx); +void mpoolRetStrokeOutline(SwMpool* mpool, unsigned idx); + +bool rasterCompositor(SwSurface* surface); +bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id); +bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); +bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, const SwBBox& bbox, uint32_t opacity); +bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); +bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id); +bool rasterClear(SwSurface* surface); +void rasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len); +void rasterUnpremultiply(SwSurface* surface); + +#endif /* _TVG_SW_COMMON_H_ */ diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwFill.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwFill.cpp new file mode 100644 index 0000000000..0bf051c17f --- /dev/null +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwFill.cpp @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "tvgMath.h" +#include "tvgSwCommon.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +#define GRADIENT_STOP_SIZE 1024 +#define FIXPT_BITS 8 +#define FIXPT_SIZE (1<<FIXPT_BITS) + + +static bool _updateColorTable(SwFill* fill, const Fill* fdata, const SwSurface* surface, uint32_t opacity) +{ + if (!fill->ctable) { + fill->ctable = static_cast<uint32_t*>(malloc(GRADIENT_STOP_SIZE * sizeof(uint32_t))); + if (!fill->ctable) return false; + } + + const Fill::ColorStop* colors; + auto cnt = fdata->colorStops(&colors); + if (cnt == 0 || !colors) return false; + + auto pColors = colors; + + auto a = (pColors->a * opacity) / 255; + if (a < 255) fill->translucent = true; + + auto r = pColors->r; + auto g = pColors->g; + auto b = pColors->b; + auto rgba = surface->blender.join(r, g, b, a); + + auto inc = 1.0f / static_cast<float>(GRADIENT_STOP_SIZE); + auto pos = 1.5f * inc; + uint32_t i = 0; + + fill->ctable[i++] = ALPHA_BLEND(rgba | 0xff000000, a); + + while (pos <= pColors->offset) { + fill->ctable[i] = fill->ctable[i - 1]; + ++i; + pos += inc; + } + + for (uint32_t j = 0; j < cnt - 1; ++j) { + auto curr = colors + j; + auto next = curr + 1; + auto delta = 1.0f / (next->offset - curr->offset); + auto a2 = (next->a * opacity) / 255; + if (!fill->translucent && a2 < 255) fill->translucent = true; + + auto rgba2 = surface->blender.join(next->r, next->g, next->b, a2); + + while (pos < next->offset && i < GRADIENT_STOP_SIZE) { + auto t = (pos - curr->offset) * delta; + auto dist = static_cast<int32_t>(255 * t); + auto dist2 = 255 - dist; + + auto color = INTERPOLATE(dist2, rgba, rgba2); + fill->ctable[i] = ALPHA_BLEND((color | 0xff000000), (color >> 24)); + + ++i; + pos += inc; + } + rgba = rgba2; + a = a2; + } + rgba = ALPHA_BLEND((rgba | 0xff000000), a); + + for (; i < GRADIENT_STOP_SIZE; ++i) + fill->ctable[i] = rgba; + + //Make sure the last color stop is represented at the end of the table + fill->ctable[GRADIENT_STOP_SIZE - 1] = rgba; + + return true; +} + + +bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* transform) +{ + float x1, x2, y1, y2; + if (linear->linear(&x1, &y1, &x2, &y2) != Result::Success) return false; + + fill->linear.dx = x2 - x1; + fill->linear.dy = y2 - y1; + fill->linear.len = fill->linear.dx * fill->linear.dx + fill->linear.dy * fill->linear.dy; + + if (fill->linear.len < FLT_EPSILON) return true; + + fill->linear.dx /= fill->linear.len; + fill->linear.dy /= fill->linear.len; + fill->linear.offset = -fill->linear.dx * x1 - fill->linear.dy * y1; + + auto gradTransform = linear->transform(); + bool isTransformation = !mathIdentity((const Matrix*)(&gradTransform)); + + if (isTransformation) { + if (transform) gradTransform = mathMultiply(transform, &gradTransform); + } else if (transform) { + gradTransform = *transform; + isTransformation = true; + } + + if (isTransformation) { + Matrix invTransform; + if (!mathInverse(&gradTransform, &invTransform)) return false; + + fill->linear.offset += fill->linear.dx * invTransform.e13 + fill->linear.dy * invTransform.e23; + + auto dx = fill->linear.dx; + fill->linear.dx = dx * invTransform.e11 + fill->linear.dy * invTransform.e21; + fill->linear.dy = dx * invTransform.e12 + fill->linear.dy * invTransform.e22; + + fill->linear.len = fill->linear.dx * fill->linear.dx + fill->linear.dy * fill->linear.dy; + if (fill->linear.len < FLT_EPSILON) return true; + } + + return true; +} + + +bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* transform) +{ + float radius, cx, cy; + if (radial->radial(&cx, &cy, &radius) != Result::Success) return false; + if (radius < FLT_EPSILON) return true; + + float invR = 1.0f / radius; + fill->radial.shiftX = -cx; + fill->radial.shiftY = -cy; + fill->radial.a = radius; + + auto gradTransform = radial->transform(); + bool isTransformation = !mathIdentity((const Matrix*)(&gradTransform)); + + if (isTransformation) { + if (transform) gradTransform = mathMultiply(transform, &gradTransform); + } else if (transform) { + gradTransform = *transform; + isTransformation = true; + } + + if (isTransformation) { + Matrix invTransform; + if (!mathInverse(&gradTransform, &invTransform)) return false; + + fill->radial.a11 = invTransform.e11 * invR; + fill->radial.a12 = invTransform.e12 * invR; + fill->radial.shiftX += invTransform.e13; + fill->radial.a21 = invTransform.e21 * invR; + fill->radial.a22 = invTransform.e22 * invR; + fill->radial.shiftY += invTransform.e23; + fill->radial.detSecDeriv = 2.0f * fill->radial.a11 * fill->radial.a11 + 2 * fill->radial.a21 * fill->radial.a21; + + fill->radial.a *= sqrt(pow(invTransform.e11, 2) + pow(invTransform.e21, 2)); + } else { + fill->radial.a11 = fill->radial.a22 = invR; + fill->radial.a12 = fill->radial.a21 = 0.0f; + fill->radial.detSecDeriv = 2.0f * invR * invR; + } + fill->radial.shiftX *= invR; + fill->radial.shiftY *= invR; + + return true; +} + + +static inline uint32_t _clamp(const SwFill* fill, int32_t pos) +{ + switch (fill->spread) { + case FillSpread::Pad: { + if (pos >= GRADIENT_STOP_SIZE) pos = GRADIENT_STOP_SIZE - 1; + else if (pos < 0) pos = 0; + break; + } + case FillSpread::Repeat: { + pos = pos % GRADIENT_STOP_SIZE; + if (pos < 0) pos = GRADIENT_STOP_SIZE + pos; + break; + } + case FillSpread::Reflect: { + auto limit = GRADIENT_STOP_SIZE * 2; + pos = pos % limit; + if (pos < 0) pos = limit + pos; + if (pos >= GRADIENT_STOP_SIZE) pos = (limit - pos - 1); + break; + } + } + return pos; +} + + +static inline uint32_t _fixedPixel(const SwFill* fill, int32_t pos) +{ + int32_t i = (pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS; + return fill->ctable[_clamp(fill, i)]; +} + + +static inline uint32_t _pixel(const SwFill* fill, float pos) +{ + auto i = static_cast<int32_t>(pos * (GRADIENT_STOP_SIZE - 1) + 0.5f); + return fill->ctable[_clamp(fill, i)]; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +void fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len) +{ + auto rx = (x + 0.5f) * fill->radial.a11 + (y + 0.5f) * fill->radial.a12 + fill->radial.shiftX; + auto ry = (x + 0.5f) * fill->radial.a21 + (y + 0.5f) * fill->radial.a22 + fill->radial.shiftY; + + // detSecondDerivative = d(detFirstDerivative)/dx = d( d(det)/dx )/dx + auto detSecondDerivative = fill->radial.detSecDeriv; + // detFirstDerivative = d(det)/dx + auto detFirstDerivative = 2.0f * (fill->radial.a11 * rx + fill->radial.a21 * ry) + 0.5f * detSecondDerivative; + auto det = rx * rx + ry * ry; + + for (uint32_t i = 0 ; i < len ; ++i) { + *dst = _pixel(fill, sqrtf(det)); + ++dst; + det += detFirstDerivative; + detFirstDerivative += detSecondDerivative; + } +} + + +void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len) +{ + //Rotation + float rx = x + 0.5f; + float ry = y + 0.5f; + float t = (fill->linear.dx * rx + fill->linear.dy * ry + fill->linear.offset) * (GRADIENT_STOP_SIZE - 1); + float inc = (fill->linear.dx) * (GRADIENT_STOP_SIZE - 1); + + if (mathZero(inc)) { + auto color = _fixedPixel(fill, static_cast<int32_t>(t * FIXPT_SIZE)); + rasterRGBA32(dst, color, 0, len); + return; + } + + auto vMax = static_cast<float>(INT32_MAX >> (FIXPT_BITS + 1)); + auto vMin = -vMax; + auto v = t + (inc * len); + + //we can use fixed point math + if (v < vMax && v > vMin) { + auto t2 = static_cast<int32_t>(t * FIXPT_SIZE); + auto inc2 = static_cast<int32_t>(inc * FIXPT_SIZE); + for (uint32_t j = 0; j < len; ++j) { + *dst = _fixedPixel(fill, t2); + ++dst; + t2 += inc2; + } + //we have to fallback to float math + } else { + uint32_t counter = 0; + while (counter++ < len) { + *dst = _pixel(fill, t / GRADIENT_STOP_SIZE); + ++dst; + t += inc; + } + } +} + + +bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable) +{ + if (!fill) return false; + + fill->spread = fdata->spread(); + + if (ctable) { + if (!_updateColorTable(fill, fdata, surface, opacity)) return false; + } + + if (fdata->identifier() == TVG_CLASS_ID_LINEAR) { + return _prepareLinear(fill, static_cast<const LinearGradient*>(fdata), transform); + } else if (fdata->identifier() == TVG_CLASS_ID_RADIAL) { + return _prepareRadial(fill, static_cast<const RadialGradient*>(fdata), transform); + } + + //LOG: What type of gradient?! + + return false; +} + + +void fillReset(SwFill* fill) +{ + if (fill->ctable) { + free(fill->ctable); + fill->ctable = nullptr; + } + fill->translucent = false; +} + + +void fillFree(SwFill* fill) +{ + if (!fill) return; + + if (fill->ctable) free(fill->ctable); + + free(fill); +} diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp new file mode 100644 index 0000000000..fe22fce017 --- /dev/null +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "tvgMath.h" +#include "tvgSwCommon.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static inline bool _onlyShifted(const Matrix* m) +{ + if (mathEqual(m->e11, 1.0f) && mathEqual(m->e22, 1.0f) && mathZero(m->e12) && mathZero(m->e21)) return true; + return false; +} + + +static bool _genOutline(SwImage* image, const Matrix* transform, SwMpool* mpool, unsigned tid) +{ + image->outline = mpoolReqOutline(mpool, tid); + auto outline = image->outline; + + if (outline->reservedPtsCnt < 5) { + outline->reservedPtsCnt = 5; + outline->pts = static_cast<SwPoint*>(realloc(outline->pts, outline->reservedPtsCnt * sizeof(SwPoint))); + outline->types = static_cast<uint8_t*>(realloc(outline->types, outline->reservedPtsCnt * sizeof(uint8_t))); + } + + if (outline->reservedCntrsCnt < 1) { + outline->reservedCntrsCnt = 1; + outline->cntrs = static_cast<uint16_t*>(realloc(outline->cntrs, outline->reservedCntrsCnt * sizeof(uint16_t))); + outline->closed = static_cast<bool*>(realloc(outline->closed, outline->reservedCntrsCnt * sizeof(bool))); + outline->closed[0] = true; + } + + auto w = static_cast<float>(image->w); + auto h = static_cast<float>(image->h); + + Point to[4] = {{0 ,0}, {w, 0}, {w, h}, {0, h}}; + for (int i = 0; i < 4; i++) { + outline->pts[outline->ptsCnt] = mathTransform(&to[i], transform); + outline->types[outline->ptsCnt] = SW_CURVE_TYPE_POINT; + ++outline->ptsCnt; + } + + outline->pts[outline->ptsCnt] = outline->pts[0]; + outline->types[outline->ptsCnt] = SW_CURVE_TYPE_POINT; + ++outline->ptsCnt; + + outline->cntrs[outline->cntrsCnt] = outline->ptsCnt - 1; + ++outline->cntrsCnt; + + image->outline = outline; + + return true; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid) +{ + image->direct = _onlyShifted(transform); + + //Fast track: Non-transformed image but just shifted. + if (image->direct) { + image->ox = -static_cast<uint32_t>(round(transform->e13)); + image->oy = -static_cast<uint32_t>(round(transform->e23)); + //Figure out the scale factor by transform matrix + } else { + auto scaleX = sqrtf((transform->e11 * transform->e11) + (transform->e21 * transform->e21)); + auto scaleY = sqrtf((transform->e22 * transform->e22) + (transform->e12 * transform->e12)); + image->scale = (fabsf(scaleX - scaleY) > 0.01f) ? 1.0f : scaleX; + + if (mathZero(transform->e12) && mathZero(transform->e21)) image->scaled = true; + else image->scaled = false; + } + + if (!_genOutline(image, transform, mpool, tid)) return false; + return mathUpdateOutlineBBox(image->outline, clipRegion, renderRegion, image->direct); +} + + +bool imageGenRle(SwImage* image, const SwBBox& renderRegion, bool antiAlias) +{ + if ((image->rle = rleRender(image->rle, image->outline, renderRegion, antiAlias))) return true; + + return false; +} + + +void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid) +{ + mpoolRetOutline(mpool, tid); + image->outline = nullptr; +} + + +void imageReset(SwImage* image) +{ + rleReset(image->rle); +} + + +void imageFree(SwImage* image) +{ + rleFree(image->rle); +} diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwMath.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwMath.cpp new file mode 100644 index 0000000000..7a3529bd69 --- /dev/null +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwMath.cpp @@ -0,0 +1,502 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include <math.h> +#include "tvgSwCommon.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +//clz: count leading zero’s +#if defined(_MSC_VER) && !defined(__clang__) + #include <intrin.h> + static uint32_t __inline _clz(uint32_t value) + { + unsigned long leadingZero = 0; + if (_BitScanReverse(&leadingZero, value)) return 31 - leadingZero; + else return 32; + } +#else + #define _clz(x) __builtin_clz((x)) +#endif + + +constexpr SwFixed CORDIC_FACTOR = 0xDBD95B16UL; //the Cordic shrink factor 0.858785336480436 * 2^32 + +//this table was generated for SW_FT_PI = 180L << 16, i.e. degrees +constexpr static auto ATAN_MAX = 23; +constexpr static SwFixed ATAN_TBL[] = { + 1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 29335L, + 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L, + 57L, 29L, 14L, 7L, 4L, 2L, 1L}; + +static inline SwCoord SATURATE(const SwCoord x) +{ + return (x >> (sizeof(SwCoord) * 8 - 1)); +} + + +static inline SwFixed PAD_ROUND(const SwFixed x, int32_t n) +{ + return (((x) + ((n)/2)) & ~((n)-1)); +} + + +static SwCoord _downscale(SwFixed x) +{ + //multiply a give value by the CORDIC shrink factor + auto s = abs(x); + int64_t t = (s * static_cast<int64_t>(CORDIC_FACTOR)) + 0x100000000UL; + s = static_cast<SwFixed>(t >> 32); + if (x < 0) s = -s; + return s; +} + + +static int32_t _normalize(SwPoint& pt) +{ + /* the highest bit in overflow-safe vector components + MSB of 0.858785336480436 * sqrt(0.5) * 2^30 */ + constexpr auto SAFE_MSB = 29; + + auto v = pt; + + //High order bit(MSB) + int32_t shift = 31 - _clz(abs(v.x) | abs(v.y)); + + if (shift <= SAFE_MSB) { + shift = SAFE_MSB - shift; + pt.x = static_cast<SwCoord>((unsigned long)v.x << shift); + pt.y = static_cast<SwCoord>((unsigned long)v.y << shift); + } else { + shift -= SAFE_MSB; + pt.x = v.x >> shift; + pt.y = v.y >> shift; + shift = -shift; + } + return shift; +} + + +static void _polarize(SwPoint& pt) +{ + auto v = pt; + SwFixed theta; + + //Get the vector into [-PI/4, PI/4] sector + if (v.y > v.x) { + if (v.y > -v.x) { + auto tmp = v.y; + v.y = -v.x; + v.x = tmp; + theta = SW_ANGLE_PI2; + } else { + theta = v.y > 0 ? SW_ANGLE_PI : -SW_ANGLE_PI; + v.x = -v.x; + v.y = -v.y; + } + } else { + if (v.y < -v.x) { + theta = -SW_ANGLE_PI2; + auto tmp = -v.y; + v.y = v.x; + v.x = tmp; + } else { + theta = 0; + } + } + + auto atan = ATAN_TBL; + uint32_t i; + SwFixed j; + + //Pseudorotations. with right shifts + for (i = 1, j = 1; i < ATAN_MAX; j <<= 1, ++i) { + if (v.y > 0) { + auto tmp = v.x + ((v.y + j) >> i); + v.y = v.y - ((v.x + j) >> i); + v.x = tmp; + theta += *atan++; + } else { + auto tmp = v.x - ((v.y + j) >> i); + v.y = v.y + ((v.x + j) >> i); + v.x = tmp; + theta -= *atan++; + } + } + + //round theta + if (theta >= 0) theta = PAD_ROUND(theta, 32); + else theta = -PAD_ROUND(-theta, 32); + + pt.x = v.x; + pt.y = theta; +} + + +static void _rotate(SwPoint& pt, SwFixed theta) +{ + SwFixed x = pt.x; + SwFixed y = pt.y; + + //Rotate inside [-PI/4, PI/4] sector + while (theta < -SW_ANGLE_PI4) { + auto tmp = y; + y = -x; + x = tmp; + theta += SW_ANGLE_PI2; + } + + while (theta > SW_ANGLE_PI4) { + auto tmp = -y; + y = x; + x = tmp; + theta -= SW_ANGLE_PI2; + } + + auto atan = ATAN_TBL; + uint32_t i; + SwFixed j; + + for (i = 1, j = 1; i < ATAN_MAX; j <<= 1, ++i) { + if (theta < 0) { + auto tmp = x + ((y + j) >> i); + y = y - ((x + j) >> i); + x = tmp; + theta += *atan++; + } else { + auto tmp = x - ((y + j) >> i); + y = y + ((x + j) >> i); + x = tmp; + theta -= *atan++; + } + } + + pt.x = static_cast<SwCoord>(x); + pt.y = static_cast<SwCoord>(y); +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +SwFixed mathMean(SwFixed angle1, SwFixed angle2) +{ + return angle1 + mathDiff(angle1, angle2) / 2; +} + + +bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut) +{ + auto d1 = base[2] - base[3]; + auto d2 = base[1] - base[2]; + auto d3 = base[0] - base[1]; + + if (d1.small()) { + if (d2.small()) { + if (d3.small()) { + //basically a point. + //do nothing to retain original direction + } else { + angleIn = angleMid = angleOut = mathAtan(d3); + } + } else { + if (d3.small()) { + angleIn = angleMid = angleOut = mathAtan(d2); + } else { + angleIn = angleMid = mathAtan(d2); + angleOut = mathAtan(d3); + } + } + } else { + if (d2.small()) { + if (d3.small()) { + angleIn = angleMid = angleOut = mathAtan(d1); + } else { + angleIn = mathAtan(d1); + angleOut = mathAtan(d3); + angleMid = mathMean(angleIn, angleOut); + } + } else { + if (d3.small()) { + angleIn = mathAtan(d1); + angleMid = angleOut = mathAtan(d2); + } else { + angleIn = mathAtan(d1); + angleMid = mathAtan(d2); + angleOut = mathAtan(d3); + } + } + } + + auto theta1 = abs(mathDiff(angleIn, angleMid)); + auto theta2 = abs(mathDiff(angleMid, angleOut)); + + if ((theta1 < (SW_ANGLE_PI / 8)) && (theta2 < (SW_ANGLE_PI / 8))) return true; + return false; +} + + +int64_t mathMultiply(int64_t a, int64_t b) +{ + int32_t s = 1; + + //move sign + if (a < 0) { + a = -a; + s = -s; + } + if (b < 0) { + b = -b; + s = -s; + } + int64_t c = (a * b + 0x8000L) >> 16; + return (s > 0) ? c : -c; +} + + +int64_t mathDivide(int64_t a, int64_t b) +{ + int32_t s = 1; + + //move sign + if (a < 0) { + a = -a; + s = -s; + } + if (b < 0) { + b = -b; + s = -s; + } + int64_t q = b > 0 ? ((a << 16) + (b >> 1)) / b : 0x7FFFFFFFL; + return (s < 0 ? -q : q); +} + + +int64_t mathMulDiv(int64_t a, int64_t b, int64_t c) +{ + int32_t s = 1; + + //move sign + if (a < 0) { + a = -a; + s = -s; + } + if (b < 0) { + b = -b; + s = -s; + } + if (c < 0) { + c = -c; + s = -s; + } + int64_t d = c > 0 ? (a * b + (c >> 1)) / c : 0x7FFFFFFFL; + + return (s > 0 ? d : -d); +} + + +void mathRotate(SwPoint& pt, SwFixed angle) +{ + if (angle == 0 || (pt.x == 0 && pt.y == 0)) return; + + auto v = pt; + auto shift = _normalize(v); + + auto theta = angle; + _rotate(v, theta); + + v.x = _downscale(v.x); + v.y = _downscale(v.y); + + if (shift > 0) { + auto half = static_cast<int32_t>(1L << (shift - 1)); + pt.x = (v.x + half + SATURATE(v.x)) >> shift; + pt.y = (v.y + half + SATURATE(v.y)) >> shift; + } else { + shift = -shift; + pt.x = static_cast<SwCoord>((unsigned long)v.x << shift); + pt.y = static_cast<SwCoord>((unsigned long)v.y << shift); + } +} + +SwFixed mathTan(SwFixed angle) +{ + SwPoint v = {CORDIC_FACTOR >> 8, 0}; + _rotate(v, angle); + return mathDivide(v.y, v.x); +} + + +SwFixed mathAtan(const SwPoint& pt) +{ + if (pt.x == 0 && pt.y == 0) return 0; + + auto v = pt; + _normalize(v); + _polarize(v); + + return v.y; +} + + +SwFixed mathSin(SwFixed angle) +{ + return mathCos(SW_ANGLE_PI2 - angle); +} + + +SwFixed mathCos(SwFixed angle) +{ + SwPoint v = {CORDIC_FACTOR >> 8, 0}; + _rotate(v, angle); + return (v.x + 0x80L) >> 8; +} + + +SwFixed mathLength(const SwPoint& pt) +{ + auto v = pt; + + //trivial case + if (v.x == 0) return abs(v.y); + if (v.y == 0) return abs(v.x); + + //general case + auto shift = _normalize(v); + _polarize(v); + v.x = _downscale(v.x); + + if (shift > 0) return (v.x + (static_cast<SwFixed>(1) << (shift -1))) >> shift; + return static_cast<SwFixed>((uint32_t)v.x << -shift); +} + + +void mathSplitCubic(SwPoint* base) +{ + SwCoord a, b, c, d; + + base[6].x = base[3].x; + c = base[1].x; + d = base[2].x; + base[1].x = a = (base[0].x + c) / 2; + base[5].x = b = (base[3].x + d) / 2; + c = (c + d) / 2; + base[2].x = a = (a + c) / 2; + base[4].x = b = (b + c) / 2; + base[3].x = (a + b) / 2; + + base[6].y = base[3].y; + c = base[1].y; + d = base[2].y; + base[1].y = a = (base[0].y + c) / 2; + base[5].y = b = (base[3].y + d) / 2; + c = (c + d) / 2; + base[2].y = a = (a + c) / 2; + base[4].y = b = (b + c) / 2; + base[3].y = (a + b) / 2; +} + + +SwFixed mathDiff(SwFixed angle1, SwFixed angle2) +{ + auto delta = angle2 - angle1; + + delta %= SW_ANGLE_2PI; + if (delta < 0) delta += SW_ANGLE_2PI; + if (delta > SW_ANGLE_PI) delta -= SW_ANGLE_2PI; + + return delta; +} + + +SwPoint mathTransform(const Point* to, const Matrix* transform) +{ + if (!transform) return {TO_SWCOORD(to->x), TO_SWCOORD(to->y)}; + + auto tx = to->x * transform->e11 + to->y * transform->e12 + transform->e13; + auto ty = to->x * transform->e21 + to->y * transform->e22 + transform->e23; + + return {TO_SWCOORD(tx), TO_SWCOORD(ty)}; +} + + +bool mathClipBBox(const SwBBox& clipper, SwBBox& clipee) +{ + clipee.max.x = (clipee.max.x < clipper.max.x) ? clipee.max.x : clipper.max.x; + clipee.max.y = (clipee.max.y < clipper.max.y) ? clipee.max.y : clipper.max.y; + clipee.min.x = (clipee.min.x > clipper.min.x) ? clipee.min.x : clipper.min.x; + clipee.min.y = (clipee.min.y > clipper.min.y) ? clipee.min.y : clipper.min.y; + + //Check valid region + if (clipee.max.x - clipee.min.x < 1 && clipee.max.y - clipee.min.y < 1) return false; + + //Check boundary + if (clipee.min.x >= clipper.max.x || clipee.min.y >= clipper.max.y || + clipee.max.x <= clipper.min.x || clipee.max.y <= clipper.min.y) return false; + + return true; +} + + +bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack) +{ + if (!outline) return false; + + auto pt = outline->pts; + + if (outline->ptsCnt == 0 || outline->cntrsCnt <= 0) { + renderRegion.reset(); + return false; + } + + auto xMin = pt->x; + auto xMax = pt->x; + auto yMin = pt->y; + auto yMax = pt->y; + + ++pt; + + for (uint32_t i = 1; i < outline->ptsCnt; ++i, ++pt) { + if (xMin > pt->x) xMin = pt->x; + if (xMax < pt->x) xMax = pt->x; + if (yMin > pt->y) yMin = pt->y; + if (yMax < pt->y) yMax = pt->y; + } + //Since no antialiasing is applied in the Fast Track case, + //the rasterization region has to be rearranged. + //https://github.com/Samsung/thorvg/issues/916 + if (fastTrack) { + renderRegion.min.x = static_cast<SwCoord>(round(xMin / 64.0f)); + renderRegion.max.x = static_cast<SwCoord>(round(xMax / 64.0f)); + renderRegion.min.y = static_cast<SwCoord>(round(yMin / 64.0f)); + renderRegion.max.y = static_cast<SwCoord>(round(yMax / 64.0f)); + } else { + renderRegion.min.x = xMin >> 6; + renderRegion.max.x = (xMax + 63) >> 6; + renderRegion.min.y = yMin >> 6; + renderRegion.max.y = (yMax + 63) >> 6; + } + return mathClipBBox(clipRegion, renderRegion); +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwMemPool.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwMemPool.cpp new file mode 100644 index 0000000000..a44be85bbb --- /dev/null +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwMemPool.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "tvgSwCommon.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +SwOutline* mpoolReqOutline(SwMpool* mpool, unsigned idx) +{ + return &mpool->outline[idx]; +} + + +void mpoolRetOutline(SwMpool* mpool, unsigned idx) +{ + mpool->outline[idx].cntrsCnt = 0; + mpool->outline[idx].ptsCnt = 0; +} + + +SwOutline* mpoolReqStrokeOutline(SwMpool* mpool, unsigned idx) +{ + return &mpool->strokeOutline[idx]; +} + + +void mpoolRetStrokeOutline(SwMpool* mpool, unsigned idx) +{ + mpool->strokeOutline[idx].cntrsCnt = 0; + mpool->strokeOutline[idx].ptsCnt = 0; +} + + +SwMpool* mpoolInit(unsigned threads) +{ + if (threads == 0) threads = 1; + + auto mpool = static_cast<SwMpool*>(calloc(sizeof(SwMpool), 1)); + mpool->outline = static_cast<SwOutline*>(calloc(1, sizeof(SwOutline) * threads)); + if (!mpool->outline) goto err; + + mpool->strokeOutline = static_cast<SwOutline*>(calloc(1, sizeof(SwOutline) * threads)); + if (!mpool->strokeOutline) goto err; + + mpool->allocSize = threads; + + return mpool; + +err: + if (mpool->outline) { + free(mpool->outline); + mpool->outline = nullptr; + } + + if (mpool->strokeOutline) { + free(mpool->strokeOutline); + mpool->strokeOutline = nullptr; + } + free(mpool); + return nullptr; +} + + +bool mpoolClear(SwMpool* mpool) +{ + SwOutline* p; + + for (unsigned i = 0; i < mpool->allocSize; ++i) { + + //Outline + p = &mpool->outline[i]; + + free(p->cntrs); + p->cntrs = nullptr; + + free(p->pts); + p->pts = nullptr; + + free(p->types); + p->types = nullptr; + + free(p->closed); + p->closed = nullptr; + + p->cntrsCnt = p->reservedCntrsCnt = 0; + p->ptsCnt = p->reservedPtsCnt = 0; + + //StrokeOutline + p = &mpool->strokeOutline[i]; + + free(p->cntrs); + p->cntrs = nullptr; + + free(p->pts); + p->pts = nullptr; + + free(p->types); + p->types = nullptr; + + free(p->closed); + p->closed = nullptr; + + p->cntrsCnt = p->reservedCntrsCnt = 0; + p->ptsCnt = p->reservedPtsCnt = 0; + } + + return true; +} + + +bool mpoolTerm(SwMpool* mpool) +{ + if (!mpool) return false; + + mpoolClear(mpool); + + if (mpool->outline) { + free(mpool->outline); + mpool->outline = nullptr; + } + + if (mpool->strokeOutline) { + free(mpool->strokeOutline); + mpool->strokeOutline = nullptr; + } + + free(mpool); + + return true; +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp new file mode 100644 index 0000000000..deebed16ee --- /dev/null +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp @@ -0,0 +1,1497 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "tvgMath.h" +#include "tvgRender.h" +#include "tvgSwCommon.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ +constexpr auto DOWN_SCALE_TOLERANCE = 0.5f; + + +static inline uint32_t _multiplyAlpha(uint32_t c, uint32_t a) +{ + return ((c * a + 0xff) >> 8); +} + + +static inline uint32_t _alpha(uint32_t c) +{ + return (c >> 24); +} + + +static inline uint32_t _ialpha(uint32_t c) +{ + return (~c >> 24); +} + + +static inline uint32_t _abgrJoin(uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + return (a << 24 | b << 16 | g << 8 | r); +} + + +static inline uint32_t _argbJoin(uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + return (a << 24 | r << 16 | g << 8 | b); +} + + +#include "tvgSwRasterTexmap.h" +#include "tvgSwRasterC.h" +#include "tvgSwRasterAvx.h" +#include "tvgSwRasterNeon.h" + + +static inline bool _compositing(const SwSurface* surface) +{ + if (!surface->compositor || surface->compositor->method == CompositeMethod::None) return false; + return true; +} + + +static inline uint32_t _halfScale(float scale) +{ + auto halfScale = static_cast<uint32_t>(0.5f / scale); + if (halfScale == 0) halfScale = 1; + return halfScale; +} + +//Bilinear Interpolation +static uint32_t _interpUpScaler(const uint32_t *img, uint32_t w, uint32_t h, float sx, float sy) +{ + auto rx = (uint32_t)(sx); + auto ry = (uint32_t)(sy); + auto rx2 = rx + 1; + if (rx2 >= w) rx2 = w - 1; + auto ry2 = ry + 1; + if (ry2 >= h) ry2 = h - 1; + + auto dx = static_cast<uint32_t>((sx - rx) * 255.0f); + auto dy = static_cast<uint32_t>((sy - ry) * 255.0f); + + auto c1 = img[rx + ry * w]; + auto c2 = img[rx2 + ry * w]; + auto c3 = img[rx2 + ry2 * w]; + auto c4 = img[rx + ry2 * w]; + + return INTERPOLATE(dy, INTERPOLATE(dx, c3, c4), INTERPOLATE(dx, c2, c1)); +} + + +//2n x 2n Mean Kernel +static uint32_t _interpDownScaler(const uint32_t *img, uint32_t stride, uint32_t w, uint32_t h, uint32_t rx, uint32_t ry, uint32_t n) +{ + uint32_t c[4] = {0, 0, 0, 0}; + auto n2 = n * n; + auto src = img + rx - n + (ry - n) * stride; + + for (auto y = ry - n; y < ry + n; ++y) { + if (y >= h) continue; + auto p = src; + for (auto x = rx - n; x < rx + n; ++x, ++p) { + if (x >= w) continue; + c[0] += *p >> 24; + c[1] += (*p >> 16) & 0xff; + c[2] += (*p >> 8) & 0xff; + c[3] += *p & 0xff; + } + src += stride; + } + for (auto i = 0; i < 4; ++i) { + c[i] = (c[i] >> 2) / n2; + } + return (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]; +} + + +/************************************************************************/ +/* Rect */ +/************************************************************************/ + +static bool _rasterMaskedRect(SwSurface* surface, const SwBBox& region, uint32_t color, uint32_t (*blendMethod)(uint32_t)) +{ + TVGLOG("SW_ENGINE", "Masked Rect"); + + auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto w = static_cast<uint32_t>(region.max.x - region.min.x); + auto h = static_cast<uint32_t>(region.max.y - region.min.y); + + auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; //compositor buffer + + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + auto cmp = &cbuffer[y * surface->stride]; + for (uint32_t x = 0; x < w; ++x, ++dst, ++cmp) { + auto tmp = ALPHA_BLEND(color, blendMethod(*cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } + return true; +} + + +static bool _rasterSolidRect(SwSurface* surface, const SwBBox& region, uint32_t color) +{ + auto buffer = surface->buffer + (region.min.y * surface->stride); + auto w = static_cast<uint32_t>(region.max.x - region.min.x); + auto h = static_cast<uint32_t>(region.max.y - region.min.y); + + for (uint32_t y = 0; y < h; ++y) { + rasterRGBA32(buffer + y * surface->stride, color, region.min.x, w); + } + return true; +} + + +static bool _rasterRect(SwSurface* surface, const SwBBox& region, uint32_t color, uint8_t opacity) +{ + if (_compositing(surface)) { + if (surface->compositor->method == CompositeMethod::AlphaMask) { + return _rasterMaskedRect(surface, region, color, _alpha); + } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { + return _rasterMaskedRect(surface, region, color, _ialpha); + } + } else { + if (opacity == 255) { + return _rasterSolidRect(surface, region, color); + } else { +#if defined(THORVG_AVX_VECTOR_SUPPORT) + return avxRasterTranslucentRect(surface, region, color); +#elif defined(THORVG_NEON_VECTOR_SUPPORT) + return neonRasterTranslucentRect(surface, region, color); +#else + return cRasterTranslucentRect(surface, region, color); +#endif + } + } + return false; +} + + +/************************************************************************/ +/* Rle */ +/************************************************************************/ + +static bool _rasterMaskedRle(SwSurface* surface, SwRleData* rle, uint32_t color, uint32_t (*blendMethod)(uint32_t)) +{ + TVGLOG("SW_ENGINE", "Masked Rle"); + + auto span = rle->spans; + uint32_t src; + auto cbuffer = surface->compositor->image.data; + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x]; + if (span->coverage == 255) src = color; + else src = ALPHA_BLEND(color, span->coverage); + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) { + auto tmp = ALPHA_BLEND(src, blendMethod(*cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } + return true; +} + + +static bool _rasterSolidRle(SwSurface* surface, const SwRleData* rle, uint32_t color) +{ + auto span = rle->spans; + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + if (span->coverage == 255) { + rasterRGBA32(surface->buffer + span->y * surface->stride, color, span->x, span->len); + } else { + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto src = ALPHA_BLEND(color, span->coverage); + auto ialpha = 255 - span->coverage; + for (uint32_t x = 0; x < span->len; ++x, ++dst) { + *dst = src + ALPHA_BLEND(*dst, ialpha); + } + } + } + return true; +} + + +static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint32_t color, uint8_t opacity) +{ + if (!rle) return false; + + if (_compositing(surface)) { + if (surface->compositor->method == CompositeMethod::AlphaMask) { + return _rasterMaskedRle(surface, rle, color, _alpha); + } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { + return _rasterMaskedRle(surface, rle, color, _ialpha); + } + } else { + if (opacity == 255) { + return _rasterSolidRle(surface, rle, color); + } else { +#if defined(THORVG_AVX_VECTOR_SUPPORT) + return avxRasterTranslucentRle(surface, rle, color); +#elif defined(THORVG_NEON_VECTOR_SUPPORT) + return neonRasterTranslucentRle(surface, rle, color); +#else + return cRasterTranslucentRle(surface, rle, color); +#endif + } + } + return false; +} + + +/************************************************************************/ +/* RLE Transformed RGBA Image */ +/************************************************************************/ + +static bool _transformedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* transform, uint32_t opacity) +{ + if (_compositing(surface)) { + if (surface->compositor->method == CompositeMethod::AlphaMask) { + return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, _alpha); + } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { + return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, _ialpha); + } + } else { + return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, nullptr); + } + return false; +} + +/************************************************************************/ +/* RLE Scaled RGBA Image */ +/************************************************************************/ + +static bool _rasterScaledMaskedTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t opacity, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t)) +{ + TVGLOG("SW_ENGINE", "Scaled Masked Translucent Rle Image"); + + auto span = image->rle->spans; + + //Center (Down-Scaled) + if (image->scale < DOWN_SCALE_TOLERANCE) { + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto sy = (uint32_t)(span->y * itransform->e22 + itransform->e23); + if (sy >= image->h) continue; + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto cmp = &surface->compositor->image.data[span->y * surface->compositor->image.stride + span->x]; + auto alpha = _multiplyAlpha(span->coverage, opacity); + for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst, ++cmp) { + auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); + if (sx >= image->w) continue; + auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale), alpha); + auto tmp = ALPHA_BLEND(src, blendMethod(*cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } + //Center (Up-Scaled) + } else { + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto sy = span->y * itransform->e22 + itransform->e23; + if ((uint32_t)sy >= image->h) continue; + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto cmp = &surface->compositor->image.data[span->y * surface->compositor->image.stride + span->x]; + auto alpha = _multiplyAlpha(span->coverage, opacity); + for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst, ++cmp) { + auto sx = x * itransform->e11 + itransform->e13; + if ((uint32_t)sx >= image->w) continue; + auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), alpha); + auto tmp = ALPHA_BLEND(src, blendMethod(*cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } + } + return true; +} + + +static bool _rasterScaledMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t)) +{ + TVGLOG("SW_ENGINE", "Scaled Masked Rle Image"); + + auto span = image->rle->spans; + + //Center (Down-Scaled) + if (image->scale < DOWN_SCALE_TOLERANCE) { + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto sy = (uint32_t)(span->y * itransform->e22 + itransform->e23); + if (sy >= image->h) continue; + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto cmp = &surface->compositor->image.data[span->y * surface->compositor->image.stride + span->x]; + if (span->coverage == 255) { + for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst, ++cmp) { + auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); + if (sx >= image->w) continue; + auto tmp = ALPHA_BLEND(_interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale), blendMethod(*cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } else { + for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst, ++cmp) { + auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); + if (sx >= image->w) continue; + auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale), span->coverage); + auto tmp = ALPHA_BLEND(src, blendMethod(*cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } + } + //Center (Up-Scaled) + } else { + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto sy = span->y * itransform->e22 + itransform->e23; + if ((uint32_t)sy >= image->h) continue; + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto cmp = &surface->compositor->image.data[span->y * surface->compositor->image.stride + span->x]; + if (span->coverage == 255) { + for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst, ++cmp) { + auto sx = x * itransform->e11 + itransform->e13; + if ((uint32_t)sx >= image->w) continue; + auto tmp = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), blendMethod(*cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } else { + for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst, ++cmp) { + auto sx = x * itransform->e11 + itransform->e13; + if ((uint32_t)sx >= image->w) continue; + auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), span->coverage); + auto tmp = ALPHA_BLEND(src, blendMethod(*cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } + } + } + return true; +} + + +static bool _rasterScaledTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t opacity, uint32_t halfScale) +{ + auto span = image->rle->spans; + + //Center (Down-Scaled) + if (image->scale < DOWN_SCALE_TOLERANCE) { + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto sy = (uint32_t)(span->y * itransform->e22 + itransform->e23); + if (sy >= image->h) continue; + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto alpha = _multiplyAlpha(span->coverage, opacity); + for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) { + auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); + if (sx >= image->w) continue; + auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale), alpha); + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + } + //Center (Up-Scaled) + } else { + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto sy = span->y * itransform->e22 + itransform->e23; + if ((uint32_t)sy >= image->h) continue; + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto alpha = _multiplyAlpha(span->coverage, opacity); + for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) { + auto sx = x * itransform->e11 + itransform->e13; + if ((uint32_t)sx >= image->w) continue; + auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), alpha); + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + } + } + return true; +} + + +static bool _rasterScaledRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t opacity, uint32_t halfScale) +{ + auto span = image->rle->spans; + + //Center (Down-Scaled) + if (image->scale < DOWN_SCALE_TOLERANCE) { + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto sy = (uint32_t)(span->y * itransform->e22 + itransform->e23); + if (sy >= image->h) continue; + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + if (span->coverage == 255) { + for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) { + auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); + if (sx >= image->w) continue; + auto src = _interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale); + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + } else { + for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) { + auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); + if (sx >= image->w) continue; + auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale), span->coverage); + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + } + } + //Center (Up-Scaled) + } else { + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto sy = span->y * itransform->e22 + itransform->e23; + if ((uint32_t)sy >= image->h) continue; + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + if (span->coverage == 255) { + for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) { + auto sx = x * itransform->e11 + itransform->e13; + if ((uint32_t)sx >= image->w) continue; + auto src = _interpUpScaler(image->data, image->w, image->h, sx, sy); + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + } else { + for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) { + auto sx = x * itransform->e11 + itransform->e13; + if ((uint32_t)sx >= image->w) continue; + auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), span->coverage); + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + } + } + } + return true; +} + + +static bool _scaledRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint32_t opacity) +{ + Matrix itransform; + if (transform && !mathInverse(transform, &itransform)) return false; + + auto halfScale = _halfScale(image->scale); + + if (_compositing(surface)) { + if (opacity == 255) { + if (surface->compositor->method == CompositeMethod::AlphaMask) { + return _rasterScaledMaskedRleRGBAImage(surface, image, &itransform, region, halfScale, _alpha); + } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { + return _rasterScaledMaskedRleRGBAImage(surface, image, &itransform, region, halfScale, _ialpha); + } + } else { + if (surface->compositor->method == CompositeMethod::AlphaMask) { + return _rasterScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, region, opacity, halfScale, _alpha); + } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { + return _rasterScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, region, opacity, halfScale, _ialpha); + } + } + } else { + if (opacity == 255) return _rasterScaledRleRGBAImage(surface, image, &itransform, region, opacity, halfScale); + else return _rasterScaledTranslucentRleRGBAImage(surface, image, &itransform, region, opacity, halfScale); + } + return false; +} + + +/************************************************************************/ +/* RLE Direct RGBA Image */ +/************************************************************************/ + +static bool _rasterDirectMaskedTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, uint32_t opacity, uint32_t (*blendMethod)(uint32_t)) +{ + TVGLOG("SW_ENGINE", "Direct Masked Rle Image"); + + auto span = image->rle->spans; + auto cbuffer = surface->compositor->image.data; + + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x]; + auto img = image->data + (span->y + image->oy) * image->stride + (span->x + image->ox); + auto alpha = _multiplyAlpha(span->coverage, opacity); + if (alpha == 255) { + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++img) { + auto tmp = ALPHA_BLEND(*img, blendMethod(*cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } else { + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++img) { + auto tmp = ALPHA_BLEND(*img, _multiplyAlpha(alpha, blendMethod(*cmp))); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } + } + return true; +} + + +static bool _rasterDirectMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, uint32_t (*blendMethod)(uint32_t)) +{ + TVGLOG("SW_ENGINE", "Direct Masked Rle Image"); + + auto span = image->rle->spans; + auto cbuffer = surface->compositor->image.data; + + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x]; + auto img = image->data + (span->y + image->oy) * image->stride + (span->x + image->ox); + if (span->coverage == 255) { + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++img) { + auto tmp = ALPHA_BLEND(*img, blendMethod(*cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } else { + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++img) { + auto tmp = ALPHA_BLEND(*img, _multiplyAlpha(span->coverage, blendMethod(*cmp))); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } + } + return true; +} + + +static bool _rasterDirectTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, uint32_t opacity) +{ + auto span = image->rle->spans; + + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto img = image->data + (span->y + image->oy) * image->stride + (span->x + image->ox); + auto alpha = _multiplyAlpha(span->coverage, opacity); + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) { + auto src = ALPHA_BLEND(*img, alpha); + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + } + return true; +} + + +static bool _rasterDirectRleRGBAImage(SwSurface* surface, const SwImage* image) +{ + auto span = image->rle->spans; + + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto img = image->data + (span->y + image->oy) * image->stride + (span->x + image->ox); + if (span->coverage == 255) { + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) { + *dst = *img + ALPHA_BLEND(*dst, _ialpha(*img)); + } + } else { + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) { + auto src = ALPHA_BLEND(*img, span->coverage); + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + } + } + return true; +} + + +static bool _directRleRGBAImage(SwSurface* surface, const SwImage* image, uint32_t opacity) +{ + if (_compositing(surface)) { + if (opacity == 255) { + if (surface->compositor->method == CompositeMethod::AlphaMask) { + return _rasterDirectMaskedRleRGBAImage(surface, image, _alpha); + } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { + return _rasterDirectMaskedRleRGBAImage(surface, image, _ialpha); + } + } else { + if (surface->compositor->method == CompositeMethod::AlphaMask) { + return _rasterDirectMaskedTranslucentRleRGBAImage(surface, image, opacity, _alpha); + } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { + return _rasterDirectMaskedTranslucentRleRGBAImage(surface, image, opacity, _ialpha); + } + } + } else { + if (opacity == 255) return _rasterDirectRleRGBAImage(surface, image); + else return _rasterDirectTranslucentRleRGBAImage(surface, image, opacity); + } + return false; +} + + +/************************************************************************/ +/* Transformed RGBA Image */ +/************************************************************************/ + +static bool _transformedRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint32_t opacity) +{ + if (_compositing(surface)) { + if (surface->compositor->method == CompositeMethod::AlphaMask) { + return _rasterTexmapPolygon(surface, image, transform, ®ion, opacity, _alpha); + } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { + return _rasterTexmapPolygon(surface, image, transform, ®ion, opacity, _ialpha); + } + } else { + return _rasterTexmapPolygon(surface, image, transform, ®ion, opacity, nullptr); + } + return false; +} + + +/************************************************************************/ +/*Scaled RGBA Image */ +/************************************************************************/ + + +static bool _rasterScaledMaskedTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t opacity, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t)) +{ + TVGLOG("SW_ENGINE", "Scaled Masked Image"); + + auto dbuffer = surface->buffer + (region.min.y * surface->stride + region.min.x); + auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride + region.min.x); + + // Down-Scaled + if (image->scale < DOWN_SCALE_TOLERANCE) { + for (auto y = region.min.y; y < region.max.y; ++y) { + auto sy = (uint32_t)(y * itransform->e22 + itransform->e23); + if (sy >= image->h) continue; + auto dst = dbuffer; + auto cmp = cbuffer; + for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++cmp) { + auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); + if (sx >= image->w) continue; + auto alpha = _multiplyAlpha(opacity, blendMethod(*cmp)); + auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale), alpha); + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + dbuffer += surface->stride; + cbuffer += surface->compositor->image.stride; + } + // Up-Scaled + } else { + for (auto y = region.min.y; y < region.max.y; ++y) { + auto sy = y * itransform->e22 + itransform->e23; + if ((uint32_t)sy >= image->h) continue; + auto dst = dbuffer; + auto cmp = cbuffer; + for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++cmp) { + auto sx = x * itransform->e11 + itransform->e13; + if ((uint32_t)sx >= image->w) continue; + auto alpha = _multiplyAlpha(opacity, blendMethod(*cmp)); + auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), alpha); + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + dbuffer += surface->stride; + cbuffer += surface->compositor->image.stride; + } + } + return true; +} + + +static bool _rasterScaledMaskedRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t)) +{ + TVGLOG("SW_ENGINE", "Scaled Masked Image"); + + auto dbuffer = surface->buffer + (region.min.y * surface->stride + region.min.x); + auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride + region.min.x); + + // Down-Scaled + if (image->scale < DOWN_SCALE_TOLERANCE) { + for (auto y = region.min.y; y < region.max.y; ++y) { + auto sy = (uint32_t)(y * itransform->e22 + itransform->e23); + if (sy >= image->h) continue; + auto dst = dbuffer; + auto cmp = cbuffer; + for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++cmp) { + auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); + if (sx >= image->w) continue; + auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale), blendMethod(*cmp)); + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + dbuffer += surface->stride; + cbuffer += surface->compositor->image.stride; + } + // Up-Scaled + } else { + for (auto y = region.min.y; y < region.max.y; ++y) { + auto sy = y * itransform->e22 + itransform->e23; + if ((uint32_t)sy >= image->h) continue; + auto dst = dbuffer; + auto cmp = cbuffer; + for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++cmp) { + auto sx = x * itransform->e11 + itransform->e13; + if ((uint32_t)sx >= image->w) continue; + auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), blendMethod(*cmp)); + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + dbuffer += surface->stride; + cbuffer += surface->compositor->image.stride; + } + } + return true; +} + + +static bool _rasterScaledTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t opacity, uint32_t halfScale) +{ + auto dbuffer = surface->buffer + (region.min.y * surface->stride + region.min.x); + + // Down-Scaled + if (image->scale < DOWN_SCALE_TOLERANCE) { + for (auto y = region.min.y; y < region.max.y; ++y, dbuffer += surface->stride) { + auto sy = (uint32_t)(y * itransform->e22 + itransform->e23); + if (sy >= image->h) continue; + auto dst = dbuffer; + for (auto x = region.min.x; x < region.max.x; ++x, ++dst) { + auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); + if (sx >= image->w) continue; + auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale), opacity); + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + } + // Up-Scaled + } else { + for (auto y = region.min.y; y < region.max.y; ++y, dbuffer += surface->stride) { + auto sy = fabsf(y * itransform->e22 + itransform->e23); + if (sy >= image->h) continue; + auto dst = dbuffer; + for (auto x = region.min.x; x < region.max.x; ++x, ++dst) { + auto sx = x * itransform->e11 + itransform->e13; + if ((uint32_t)sx >= image->w) continue; + auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), opacity); + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + } + } + return true; +} + + +static bool _rasterScaledRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t halfScale) +{ + auto dbuffer = surface->buffer + (region.min.y * surface->stride + region.min.x); + + // Down-Scaled + if (image->scale < DOWN_SCALE_TOLERANCE) { + for (auto y = region.min.y; y < region.max.y; ++y, dbuffer += surface->stride) { + auto sy = (uint32_t)(y * itransform->e22 + itransform->e23); + if (sy >= image->h) continue; + auto dst = dbuffer; + for (auto x = region.min.x; x < region.max.x; ++x, ++dst) { + auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); + if (sx >= image->w) continue; + auto src = _interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale); + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + } + // Up-Scaled + } else { + for (auto y = region.min.y; y < region.max.y; ++y, dbuffer += surface->stride) { + auto sy = y * itransform->e22 + itransform->e23; + if ((uint32_t)sy >= image->h) continue; + auto dst = dbuffer; + for (auto x = region.min.x; x < region.max.x; ++x, ++dst) { + auto sx = x * itransform->e11 + itransform->e13; + if ((uint32_t)sx >= image->w) continue; + auto src = _interpUpScaler(image->data, image->w, image->h, sx, sy); + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + } + } + return true; +} + + +static bool _scaledRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint32_t opacity) +{ + Matrix itransform; + if (transform && !mathInverse(transform, &itransform)) return false; + + auto halfScale = _halfScale(image->scale); + + if (_compositing(surface)) { + if (opacity == 255) { + if (surface->compositor->method == CompositeMethod::AlphaMask) { + return _rasterScaledMaskedRGBAImage(surface, image, &itransform, region, halfScale, _alpha); + } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { + return _rasterScaledMaskedRGBAImage(surface, image, &itransform, region, halfScale, _ialpha); + } + } else { + if (surface->compositor->method == CompositeMethod::AlphaMask) { + return _rasterScaledMaskedTranslucentRGBAImage(surface, image, &itransform, region, opacity, halfScale, _alpha); + } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { + return _rasterScaledMaskedTranslucentRGBAImage(surface, image, &itransform, region, opacity, halfScale, _ialpha); + } + } + } else { + if (opacity == 255) return _rasterScaledRGBAImage(surface, image, &itransform, region, halfScale); + else return _rasterScaledTranslucentRGBAImage(surface, image, &itransform, region, opacity, halfScale); + } + return false; +} + + +/************************************************************************/ +/* Direct RGBA Image */ +/************************************************************************/ + +static bool _rasterDirectMaskedRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t (*blendMethod)(uint32_t)) +{ + TVGLOG("SW_ENGINE", "Direct Masked Image"); + + auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto h2 = static_cast<uint32_t>(region.max.y - region.min.y); + auto w2 = static_cast<uint32_t>(region.max.x - region.min.x); + + auto sbuffer = image->data + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); + auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; //compositor buffer + + for (uint32_t y = 0; y < h2; ++y) { + auto dst = buffer; + auto cmp = cbuffer; + auto src = sbuffer; + for (uint32_t x = 0; x < w2; ++x, ++dst, ++src, ++cmp) { + auto tmp = ALPHA_BLEND(*src, blendMethod(*cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + buffer += surface->stride; + cbuffer += surface->compositor->image.stride; + sbuffer += image->stride; + } + return true; +} + + +static bool _rasterDirectMaskedTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t opacity, uint32_t (*blendMethod)(uint32_t)) +{ + TVGLOG("SW_ENGINE", "Direct Masked Translucent Image"); + + auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto h2 = static_cast<uint32_t>(region.max.y - region.min.y); + auto w2 = static_cast<uint32_t>(region.max.x - region.min.x); + + auto sbuffer = image->data + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); + auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; //compositor buffer + + for (uint32_t y = 0; y < h2; ++y) { + auto dst = buffer; + auto cmp = cbuffer; + auto src = sbuffer; + for (uint32_t x = 0; x < w2; ++x, ++dst, ++src, ++cmp) { + auto tmp = ALPHA_BLEND(*src, _multiplyAlpha(opacity, blendMethod(*cmp))); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + buffer += surface->stride; + cbuffer += surface->compositor->image.stride; + sbuffer += image->stride; + } + return true; +} + + +static bool _rasterDirectTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t opacity) +{ + auto dbuffer = &surface->buffer[region.min.y * surface->stride + region.min.x]; + auto sbuffer = image->data + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); + + for (auto y = region.min.y; y < region.max.y; ++y) { + auto dst = dbuffer; + auto src = sbuffer; + for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++src) { + auto tmp = ALPHA_BLEND(*src, opacity); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + dbuffer += surface->stride; + sbuffer += image->stride; + } + return true; +} + + +static bool _rasterDirectRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region) +{ + auto dbuffer = &surface->buffer[region.min.y * surface->stride + region.min.x]; + auto sbuffer = image->data + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); + + for (auto y = region.min.y; y < region.max.y; ++y) { + auto dst = dbuffer; + auto src = sbuffer; + for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) { + *dst = *src + ALPHA_BLEND(*dst, _ialpha(*src)); + } + dbuffer += surface->stride; + sbuffer += image->stride; + } + return true; +} + + +//Blenders for the following scenarios: [Composition / Non-Composition] * [Opaque / Translucent] +static bool _directRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t opacity) +{ + if (_compositing(surface)) { + if (opacity == 255) { + if (surface->compositor->method == CompositeMethod::AlphaMask) { + return _rasterDirectMaskedRGBAImage(surface, image, region, _alpha); + } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { + return _rasterDirectMaskedRGBAImage(surface, image, region, _ialpha); + } + } else { + if (surface->compositor->method == CompositeMethod::AlphaMask) { + return _rasterDirectMaskedTranslucentRGBAImage(surface, image, region, opacity, _alpha); + } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { + return _rasterDirectMaskedTranslucentRGBAImage(surface, image, region, opacity, _ialpha); + } + } + } else { + if (opacity == 255) return _rasterDirectRGBAImage(surface, image, region); + else return _rasterDirectTranslucentRGBAImage(surface, image, region, opacity); + } + return false; +} + + +//Blenders for the following scenarios: [RLE / Whole] * [Direct / Scaled / Transformed] +static bool _rasterRGBAImage(SwSurface* surface, SwImage* image, const Matrix* transform, const SwBBox& region, uint32_t opacity) +{ + //RLE Image + if (image->rle) { + if (image->direct) return _directRleRGBAImage(surface, image, opacity); + else if (image->scaled) return _scaledRleRGBAImage(surface, image, transform, region, opacity); + else return _transformedRleRGBAImage(surface, image, transform, opacity); + //Whole Image + } else { + if (image->direct) return _directRGBAImage(surface, image, region, opacity); + else if (image->scaled) return _scaledRGBAImage(surface, image, transform, region, opacity); + else return _transformedRGBAImage(surface, image, transform, region, opacity); + } +} + + +/************************************************************************/ +/* Rect Linear Gradient */ +/************************************************************************/ + +static bool _rasterLinearGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill, uint32_t (*blendMethod)(uint32_t)) +{ + if (fill->linear.len < FLT_EPSILON) return false; + + auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto h = static_cast<uint32_t>(region.max.y - region.min.y); + auto w = static_cast<uint32_t>(region.max.x - region.min.x); + auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; + + auto sbuffer = static_cast<uint32_t*>(alloca(w * sizeof(uint32_t))); + if (!sbuffer) return false; + + for (uint32_t y = 0; y < h; ++y) { + fillFetchLinear(fill, sbuffer, region.min.y + y, region.min.x, w); + auto dst = buffer; + auto cmp = cbuffer; + auto src = sbuffer; + for (uint32_t x = 0; x < w; ++x, ++dst, ++cmp, ++src) { + auto tmp = ALPHA_BLEND(*src, blendMethod(*cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + buffer += surface->stride; + cbuffer += surface->stride; + } + return true; +} + + +static bool _rasterTranslucentLinearGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) +{ + if (fill->linear.len < FLT_EPSILON) return false; + + auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto h = static_cast<uint32_t>(region.max.y - region.min.y); + auto w = static_cast<uint32_t>(region.max.x - region.min.x); + + auto sbuffer = static_cast<uint32_t*>(alloca(w * sizeof(uint32_t))); + if (!sbuffer) return false; + + for (uint32_t y = 0; y < h; ++y) { + auto dst = buffer; + fillFetchLinear(fill, sbuffer, region.min.y + y, region.min.x, w); + for (uint32_t x = 0; x < w; ++x, ++dst) { + *dst = sbuffer[x] + ALPHA_BLEND(*dst, _ialpha(sbuffer[x])); + } + buffer += surface->stride; + } + return true; +} + + +static bool _rasterSolidLinearGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) +{ + if (fill->linear.len < FLT_EPSILON) return false; + + auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto w = static_cast<uint32_t>(region.max.x - region.min.x); + auto h = static_cast<uint32_t>(region.max.y - region.min.y); + + for (uint32_t y = 0; y < h; ++y) { + fillFetchLinear(fill, buffer + y * surface->stride, region.min.y + y, region.min.x, w); + } + return true; +} + + +static bool _rasterLinearGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) +{ + if (_compositing(surface)) { + if (surface->compositor->method == CompositeMethod::AlphaMask) { + return _rasterLinearGradientMaskedRect(surface, region, fill, _alpha); + } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { + return _rasterLinearGradientMaskedRect(surface, region, fill, _ialpha); + } + } else { + if (fill->translucent) return _rasterTranslucentLinearGradientRect(surface, region, fill); + else _rasterSolidLinearGradientRect(surface, region, fill); + } + return false; +} + + +/************************************************************************/ +/* Rle Linear Gradient */ +/************************************************************************/ + +static bool _rasterLinearGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill, uint32_t (*blendMethod)(uint32_t)) +{ + if (fill->linear.len < FLT_EPSILON) return false; + + auto span = rle->spans; + auto cbuffer = surface->compositor->image.data; + auto buffer = static_cast<uint32_t*>(alloca(surface->w * sizeof(uint32_t))); + if (!buffer) return false; + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + fillFetchLinear(fill, buffer, span->y, span->x, span->len); + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x]; + auto src = buffer; + if (span->coverage == 255) { + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++src) { + auto tmp = ALPHA_BLEND(*src, blendMethod(*cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } else { + auto ialpha = 255 - span->coverage; + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++src) { + auto tmp = ALPHA_BLEND(*src, blendMethod(*cmp)); + tmp = ALPHA_BLEND(tmp, span->coverage) + ALPHA_BLEND(*dst, ialpha); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } + } + return true; +} + + +static bool _rasterTranslucentLinearGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +{ + if (fill->linear.len < FLT_EPSILON) return false; + + auto span = rle->spans; + auto buffer = static_cast<uint32_t*>(alloca(surface->w * sizeof(uint32_t))); + if (!buffer) return false; + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + fillFetchLinear(fill, buffer, span->y, span->x, span->len); + if (span->coverage == 255) { + for (uint32_t i = 0; i < span->len; ++i, ++dst) { + *dst = buffer[i] + ALPHA_BLEND(*dst, _ialpha(buffer[i])); + } + } else { + for (uint32_t i = 0; i < span->len; ++i, ++dst) { + auto tmp = ALPHA_BLEND(buffer[i], span->coverage); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } + } + return true; +} + + +static bool _rasterSolidLinearGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +{ + if (fill->linear.len < FLT_EPSILON) return false; + + auto buf = static_cast<uint32_t*>(alloca(surface->w * sizeof(uint32_t))); + if (!buf) return false; + + auto span = rle->spans; + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + if (span->coverage == 255) { + fillFetchLinear(fill, surface->buffer + span->y * surface->stride + span->x, span->y, span->x, span->len); + } else { + fillFetchLinear(fill, buf, span->y, span->x, span->len); + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + for (uint32_t i = 0; i < span->len; ++i) { + dst[i] = INTERPOLATE(span->coverage, buf[i], dst[i]); + } + } + } + return true; +} + + +static bool _rasterLinearGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +{ + if (!rle) return false; + + if (_compositing(surface)) { + if (surface->compositor->method == CompositeMethod::AlphaMask) { + return _rasterLinearGradientMaskedRle(surface, rle, fill, _alpha); + } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { + return _rasterLinearGradientMaskedRle(surface, rle, fill, _ialpha); + } + } else { + if (fill->translucent) return _rasterTranslucentLinearGradientRle(surface, rle, fill); + else return _rasterSolidLinearGradientRle(surface, rle, fill); + } + return false; +} + + +/************************************************************************/ +/* Rect Radial Gradient */ +/************************************************************************/ + +static bool _rasterRadialGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill, uint32_t (*blendMethod)(uint32_t)) +{ + if (fill->radial.a < FLT_EPSILON) return false; + + auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto h = static_cast<uint32_t>(region.max.y - region.min.y); + auto w = static_cast<uint32_t>(region.max.x - region.min.x); + auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; + + auto sbuffer = static_cast<uint32_t*>(alloca(w * sizeof(uint32_t))); + if (!sbuffer) return false; + + for (uint32_t y = 0; y < h; ++y) { + fillFetchRadial(fill, sbuffer, region.min.y + y, region.min.x, w); + auto dst = buffer; + auto cmp = cbuffer; + auto src = sbuffer; + for (uint32_t x = 0; x < w; ++x, ++dst, ++cmp, ++src) { + auto tmp = ALPHA_BLEND(*src, blendMethod(*cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + buffer += surface->stride; + cbuffer += surface->stride; + } + return true; +} + + +static bool _rasterTranslucentRadialGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) +{ + if (fill->radial.a < FLT_EPSILON) return false; + + auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto h = static_cast<uint32_t>(region.max.y - region.min.y); + auto w = static_cast<uint32_t>(region.max.x - region.min.x); + + auto sbuffer = static_cast<uint32_t*>(alloca(w * sizeof(uint32_t))); + if (!sbuffer) return false; + + for (uint32_t y = 0; y < h; ++y) { + auto dst = buffer; + fillFetchRadial(fill, sbuffer, region.min.y + y, region.min.x, w); + for (uint32_t x = 0; x < w; ++x, ++dst) { + *dst = sbuffer[x] + ALPHA_BLEND(*dst, _ialpha(sbuffer[x])); + } + buffer += surface->stride; + } + return true; +} + + +static bool _rasterSolidRadialGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) +{ + if (fill->radial.a < FLT_EPSILON) return false; + + auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto h = static_cast<uint32_t>(region.max.y - region.min.y); + auto w = static_cast<uint32_t>(region.max.x - region.min.x); + + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + fillFetchRadial(fill, dst, region.min.y + y, region.min.x, w); + } + return true; +} + + +static bool _rasterRadialGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) +{ + if (_compositing(surface)) { + if (surface->compositor->method == CompositeMethod::AlphaMask) { + return _rasterRadialGradientMaskedRect(surface, region, fill, _alpha); + } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { + return _rasterRadialGradientMaskedRect(surface, region, fill, _ialpha); + } + } else { + if (fill->translucent) return _rasterTranslucentRadialGradientRect(surface, region, fill); + else return _rasterSolidRadialGradientRect(surface, region, fill); + } + return false; +} + + +/************************************************************************/ +/* RLE Radial Gradient */ +/************************************************************************/ + +static bool _rasterRadialGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill, uint32_t (*blendMethod)(uint32_t)) +{ + if (fill->radial.a < FLT_EPSILON) return false; + + auto span = rle->spans; + auto cbuffer = surface->compositor->image.data; + auto buffer = static_cast<uint32_t*>(alloca(surface->w * sizeof(uint32_t))); + if (!buffer) return false; + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + fillFetchRadial(fill, buffer, span->y, span->x, span->len); + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x]; + auto src = buffer; + if (span->coverage == 255) { + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++src) { + auto tmp = ALPHA_BLEND(*src, blendMethod(*cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } else { + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++src) { + auto tmp = INTERPOLATE(span->coverage, ALPHA_BLEND(*src, blendMethod(*cmp)), *dst); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } + } + return true; +} + + +static bool _rasterTranslucentRadialGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +{ + if (fill->radial.a < FLT_EPSILON) return false; + + auto span = rle->spans; + auto buffer = static_cast<uint32_t*>(alloca(surface->w * sizeof(uint32_t))); + if (!buffer) return false; + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + fillFetchRadial(fill, buffer, span->y, span->x, span->len); + if (span->coverage == 255) { + for (uint32_t i = 0; i < span->len; ++i, ++dst) { + *dst = buffer[i] + ALPHA_BLEND(*dst, _ialpha(buffer[i])); + } + } else { + for (uint32_t i = 0; i < span->len; ++i, ++dst) { + auto tmp = ALPHA_BLEND(buffer[i], span->coverage); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } + } + return true; +} + + +static bool _rasterSolidRadialGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +{ + if (fill->radial.a < FLT_EPSILON) return false; + + auto buf = static_cast<uint32_t*>(alloca(surface->w * sizeof(uint32_t))); + if (!buf) return false; + + auto span = rle->spans; + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + if (span->coverage == 255) { + fillFetchRadial(fill, dst, span->y, span->x, span->len); + } else { + fillFetchRadial(fill, buf, span->y, span->x, span->len); + auto ialpha = 255 - span->coverage; + for (uint32_t i = 0; i < span->len; ++i, ++dst) { + *dst = ALPHA_BLEND(buf[i], span->coverage) + ALPHA_BLEND(*dst, ialpha); + } + } + } + return true; +} + + +static bool _rasterRadialGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +{ + if (!rle) return false; + + if (_compositing(surface)) { + if (surface->compositor->method == CompositeMethod::AlphaMask) { + return _rasterRadialGradientMaskedRle(surface, rle, fill, _alpha); + } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { + return _rasterRadialGradientMaskedRle(surface, rle, fill, _ialpha); + } + } else { + if (fill->translucent) _rasterTranslucentRadialGradientRle(surface, rle, fill); + else return _rasterSolidRadialGradientRle(surface, rle, fill); + } + return false; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +void rasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len) +{ +#if defined(THORVG_AVX_VECTOR_SUPPORT) + avxRasterRGBA32(dst, val, offset, len); +#elif defined(THORVG_NEON_VECTOR_SUPPORT) + neonRasterRGBA32(dst, val, offset, len); +#else + cRasterRGBA32(dst, val, offset, len); +#endif +} + + +bool rasterCompositor(SwSurface* surface) +{ + if (surface->cs == SwCanvas::ABGR8888 || surface->cs == SwCanvas::ABGR8888_STRAIGHT) { + surface->blender.join = _abgrJoin; + } else if (surface->cs == SwCanvas::ARGB8888 || surface->cs == SwCanvas::ARGB8888_STRAIGHT) { + surface->blender.join = _argbJoin; + } else { + //What Color Space ??? + return false; + } + return true; +} + + +bool rasterClear(SwSurface* surface) +{ + if (!surface || !surface->buffer || surface->stride <= 0 || surface->w <= 0 || surface->h <= 0) return false; + + if (surface->w == surface->stride) { + rasterRGBA32(surface->buffer, 0x00000000, 0, surface->w * surface->h); + } else { + for (uint32_t i = 0; i < surface->h; i++) { + rasterRGBA32(surface->buffer + surface->stride * i, 0x00000000, 0, surface->w); + } + } + return true; +} + + +void rasterUnpremultiply(SwSurface* surface) +{ + //OPTIMIZE_ME: +SIMD + for (uint32_t y = 0; y < surface->h; y++) { + auto buffer = surface->buffer + surface->stride * y; + for (uint32_t x = 0; x < surface->w; ++x) { + uint8_t a = buffer[x] >> 24; + if (a == 255) { + continue; + } else if (a == 0) { + buffer[x] = 0x00ffffff; + } else { + uint16_t r = ((buffer[x] >> 8) & 0xff00) / a; + uint16_t g = ((buffer[x]) & 0xff00) / a; + uint16_t b = ((buffer[x] << 8) & 0xff00) / a; + if (r > 0xff) r = 0xff; + if (g > 0xff) g = 0xff; + if (b > 0xff) b = 0xff; + buffer[x] = (a << 24) | (r << 16) | (g << 8) | (b); + } + } + } +} + + +bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id) +{ + if (!shape->fill) return false; + + if (shape->fastTrack) { + if (id == TVG_CLASS_ID_LINEAR) return _rasterLinearGradientRect(surface, shape->bbox, shape->fill); + else if (id == TVG_CLASS_ID_RADIAL)return _rasterRadialGradientRect(surface, shape->bbox, shape->fill); + } else { + if (id == TVG_CLASS_ID_LINEAR) return _rasterLinearGradientRle(surface, shape->rle, shape->fill); + else if (id == TVG_CLASS_ID_RADIAL) return _rasterRadialGradientRle(surface, shape->rle, shape->fill); + } + return false; +} + + +bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id) +{ + if (!shape->stroke || !shape->stroke->fill || !shape->strokeRle) return false; + + if (id == TVG_CLASS_ID_LINEAR) return _rasterLinearGradientRle(surface, shape->strokeRle, shape->stroke->fill); + else if (id == TVG_CLASS_ID_RADIAL) return _rasterRadialGradientRle(surface, shape->strokeRle, shape->stroke->fill); + + return false; +} + + +bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + if (a < 255) { + r = _multiplyAlpha(r, a); + g = _multiplyAlpha(g, a); + b = _multiplyAlpha(b, a); + } + + auto color = surface->blender.join(r, g, b, a); + + if (shape->fastTrack) return _rasterRect(surface, shape->bbox, color, a); + else return _rasterRle(surface, shape->rle, color, a); +} + + +bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + if (a < 255) { + r = _multiplyAlpha(r, a); + g = _multiplyAlpha(g, a); + b = _multiplyAlpha(b, a); + } + + auto color = surface->blender.join(r, g, b, a); + + return _rasterRle(surface, shape->strokeRle, color, a); +} + + +bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, const SwBBox& bbox, uint32_t opacity) +{ + //Verify Boundary + if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= surface->w || bbox.min.y >= surface->h) return false; + + //TOOD: switch (image->format) + //TODO: case: _rasterRGBImage() + //TODO: case: _rasterGrayscaleImage() + //TODO: case: _rasterAlphaImage() + return _rasterRGBAImage(surface, image, transform, bbox, opacity); +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterAvx.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterAvx.h new file mode 100644 index 0000000000..1d6552f3e9 --- /dev/null +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterAvx.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifdef THORVG_AVX_VECTOR_SUPPORT + +#include <immintrin.h> + +#define N_32BITS_IN_128REG 4 +#define N_32BITS_IN_256REG 8 + +static inline __m128i ALPHA_BLEND(__m128i c, __m128i a) +{ + //1. set the masks for the A/G and R/B channels + auto AG = _mm_set1_epi32(0xff00ff00); + auto RB = _mm_set1_epi32(0x00ff00ff); + + //2. mask the alpha vector - originally quartet [a, a, a, a] + auto aAG = _mm_and_si128(a, AG); + auto aRB = _mm_and_si128(a, RB); + + //3. calculate the alpha blending of the 2nd and 4th channel + //- mask the color vector + //- multiply it by the masked alpha vector + //- add the correction to compensate bit shifting used instead of dividing by 255 + //- shift bits - corresponding to division by 256 + auto even = _mm_and_si128(c, RB); + even = _mm_mullo_epi16(even, aRB); + even =_mm_add_epi16(even, RB); + even = _mm_srli_epi16(even, 8); + + //4. calculate the alpha blending of the 1st and 3rd channel: + //- mask the color vector + //- multiply it by the corresponding masked alpha vector and store the high bits of the result + //- add the correction to compensate division by 256 instead of by 255 (next step) + //- remove the low 8 bits to mimic the division by 256 + auto odd = _mm_and_si128(c, AG); + odd = _mm_mulhi_epu16(odd, aAG); + odd = _mm_add_epi16(odd, RB); + odd = _mm_and_si128(odd, AG); + + //5. the final result + return _mm_or_si128(odd, even); +} + + +static void avxRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len) +{ + //1. calculate how many iterations we need to cover the length + uint32_t iterations = len / N_32BITS_IN_256REG; + uint32_t avxFilled = iterations * N_32BITS_IN_256REG; + + //2. set the beginning of the array + dst += offset; + + //3. fill the octets + for (uint32_t i = 0; i < iterations; ++i, dst += N_32BITS_IN_256REG) { + _mm256_storeu_si256((__m256i*)dst, _mm256_set1_epi32(val)); + } + + //4. fill leftovers (in the first step we have to set the pointer to the place where the avx job is done) + int32_t leftovers = len - avxFilled; + while (leftovers--) *dst++ = val; +} + + +static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color) +{ + auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto h = static_cast<uint32_t>(region.max.y - region.min.y); + auto w = static_cast<uint32_t>(region.max.x - region.min.x); + + auto ialpha = 255 - static_cast<uint8_t>(_alpha(color)); + + auto avxColor = _mm_set1_epi32(color); + auto avxIalpha = _mm_set1_epi8(ialpha); + + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + + //1. fill the not aligned memory (for 128-bit registers a 16-bytes alignment is required) + auto notAligned = ((uintptr_t)dst & 0xf) / 4; + if (notAligned) { + notAligned = (N_32BITS_IN_128REG - notAligned > w ? w : N_32BITS_IN_128REG - notAligned); + for (uint32_t x = 0; x < notAligned; ++x, ++dst) { + *dst = color + ALPHA_BLEND(*dst, ialpha); + } + } + + //2. fill the aligned memory - N_32BITS_IN_128REG pixels processed at once + uint32_t iterations = (w - notAligned) / N_32BITS_IN_128REG; + uint32_t avxFilled = iterations * N_32BITS_IN_128REG; + auto avxDst = (__m128i*)dst; + for (uint32_t x = 0; x < iterations; ++x, ++avxDst) { + *avxDst = _mm_add_epi32(avxColor, ALPHA_BLEND(*avxDst, avxIalpha)); + } + + //3. fill the remaining pixels + int32_t leftovers = w - notAligned - avxFilled; + dst += avxFilled; + while (leftovers--) { + *dst = color + ALPHA_BLEND(*dst, ialpha); + dst++; + } + } + return true; +} + + +static bool avxRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color) +{ + auto span = rle->spans; + uint32_t src; + + for (uint32_t i = 0; i < rle->size; ++i) { + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + + if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage); + else src = color; + + auto ialpha = 255 - static_cast<uint8_t>(_alpha(src)); + + //1. fill the not aligned memory (for 128-bit registers a 16-bytes alignment is required) + auto notAligned = ((uintptr_t)dst & 0xf) / 4; + if (notAligned) { + notAligned = (N_32BITS_IN_128REG - notAligned > span->len ? span->len : N_32BITS_IN_128REG - notAligned); + for (uint32_t x = 0; x < notAligned; ++x, ++dst) { + *dst = src + ALPHA_BLEND(*dst, ialpha); + } + } + + //2. fill the aligned memory using avx - N_32BITS_IN_128REG pixels processed at once + //In order to avoid unneccessary avx variables declarations a check is made whether there are any iterations at all + uint32_t iterations = (span->len - notAligned) / N_32BITS_IN_128REG; + uint32_t avxFilled = 0; + if (iterations > 0) { + auto avxSrc = _mm_set1_epi32(src); + auto avxIalpha = _mm_set1_epi8(ialpha); + + avxFilled = iterations * N_32BITS_IN_128REG; + auto avxDst = (__m128i*)dst; + for (uint32_t x = 0; x < iterations; ++x, ++avxDst) { + *avxDst = _mm_add_epi32(avxSrc, ALPHA_BLEND(*avxDst, avxIalpha)); + } + } + + //3. fill the remaining pixels + int32_t leftovers = span->len - notAligned - avxFilled; + dst += avxFilled; + while (leftovers--) { + *dst = src + ALPHA_BLEND(*dst, ialpha); + dst++; + } + + ++span; + } + return true; +} + + +#endif diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterC.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterC.h new file mode 100644 index 0000000000..6d60957eb9 --- /dev/null +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterC.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +static void inline cRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len) +{ + dst += offset; + while (len--) *dst++ = val; +} + + +static bool inline cRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color) +{ + auto span = rle->spans; + uint32_t src; + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + + if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage); + else src = color; + + for (uint32_t x = 0; x < span->len; ++x, ++dst) { + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + } + return true; +} + + +static bool inline cRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color) +{ + auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto h = static_cast<uint32_t>(region.max.y - region.min.y); + auto w = static_cast<uint32_t>(region.max.x - region.min.x); + auto ialpha = _ialpha(color); + + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + for (uint32_t x = 0; x < w; ++x, ++dst) { + *dst = color + ALPHA_BLEND(*dst, ialpha); + } + } + return true; +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterNeon.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterNeon.h new file mode 100644 index 0000000000..c74a6b309c --- /dev/null +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterNeon.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifdef THORVG_NEON_VECTOR_SUPPORT + +#include <arm_neon.h> + +static inline uint8x8_t ALPHA_BLEND(uint8x8_t c, uint8x8_t a) +{ + uint16x8_t t = vmull_u8(c, a); + return vshrn_n_u16(t, 8); +} + + +static void neonRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len) +{ + uint32_t iterations = len / 4; + uint32_t neonFilled = iterations * 4; + + dst += offset; + uint32x4_t vectorVal = {val, val, val, val}; + + for (uint32_t i = 0; i < iterations; ++i) { + vst1q_u32(dst, vectorVal); + dst += 4; + } + + int32_t leftovers = len - neonFilled; + while (leftovers--) *dst++ = val; +} + + +static bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color) +{ + auto span = rle->spans; + uint32_t src; + uint8x8_t *vDst = nullptr; + uint16_t align; + + for (uint32_t i = 0; i < rle->size; ++i) { + if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage); + else src = color; + + auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto ialpha = 255 - _alpha(src); + + if ((((uint32_t) dst) & 0x7) != 0) { + //fill not aligned byte + *dst = src + ALPHA_BLEND(*dst, ialpha); + vDst = (uint8x8_t*)(dst + 1); + align = 1; + } else { + vDst = (uint8x8_t*) dst; + align = 0; + } + + uint8x8_t vSrc = (uint8x8_t) vdup_n_u32(src); + uint8x8_t vIalpha = vdup_n_u8((uint8_t) ialpha); + + for (uint32_t x = 0; x < (span->len - align) / 2; ++x) + vDst[x] = vadd_u8(vSrc, ALPHA_BLEND(vDst[x], vIalpha)); + + auto leftovers = (span->len - align) % 2; + if (leftovers > 0) dst[span->len - 1] = src + ALPHA_BLEND(dst[span->len - 1], ialpha); + + ++span; + } + return true; +} + + +static bool neonRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color) +{ + auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto h = static_cast<uint32_t>(region.max.y - region.min.y); + auto w = static_cast<uint32_t>(region.max.x - region.min.x); + auto ialpha = 255 - _alpha(color); + + auto vColor = vdup_n_u32(color); + auto vIalpha = vdup_n_u8((uint8_t) ialpha); + + uint8x8_t* vDst = nullptr; + uint32_t align; + + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + + if ((((uint32_t) dst) & 0x7) != 0) { + //fill not aligned byte + *dst = color + ALPHA_BLEND(*dst, ialpha); + vDst = (uint8x8_t*) (dst + 1); + align = 1; + } else { + vDst = (uint8x8_t*) dst; + align = 0; + } + + for (uint32_t x = 0; x < (w - align) / 2; ++x) + vDst[x] = vadd_u8((uint8x8_t)vColor, ALPHA_BLEND(vDst[x], vIalpha)); + + auto leftovers = (w - align) % 2; + if (leftovers > 0) dst[w - 1] = color + ALPHA_BLEND(dst[w - 1], ialpha); + } + return true; +} + +#endif diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmap.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmap.h new file mode 100644 index 0000000000..2cf9fb4e93 --- /dev/null +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmap.h @@ -0,0 +1,602 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +struct Vertex +{ + Point pt; + Point uv; +}; + +struct Polygon +{ + Vertex vertex[3]; +}; + +struct AALine +{ + int32_t x[2]; + int32_t coverage[2]; + int32_t length[2]; +}; + +struct AASpans +{ + AALine *lines; + int32_t yStart; + int32_t yEnd; +}; + +static inline void _swap(float& a, float& b, float& tmp) +{ + tmp = a; + a = b; + b = tmp; +} + +//Careful! Shared resource, No support threading +static float dudx, dvdx; +static float dxdya, dxdyb, dudya, dvdya; +static float xa, xb, ua, va; + + +//Y Range exception handling +static bool _arrange(const SwImage* image, const SwBBox* region, int& yStart, int& yEnd) +{ + int32_t regionTop, regionBottom; + + if (region) { + regionTop = region->min.y; + regionBottom = region->max.y; + } else { + regionTop = image->rle->spans->y; + regionBottom = image->rle->spans[image->rle->size - 1].y; + } + + if (yStart >= regionBottom) return false; + + if (yStart < regionTop) yStart = regionTop; + if (yEnd > regionBottom) yEnd = regionBottom; + + return true; +} + + +static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, uint32_t opacity, uint32_t (*blendMethod)(uint32_t), AASpans* aaSpans) +{ +#define TEXMAP_TRANSLUCENT +#define TEXMAP_MASKING + #include "tvgSwRasterTexmapInternal.h" +#undef TEXMAP_MASKING +#undef TEXMAP_TRANSLUCENT +} + + +static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, uint32_t (*blendMethod)(uint32_t), AASpans* aaSpans) +{ +#define TEXMAP_MASKING + #include "tvgSwRasterTexmapInternal.h" +#undef TEXMAP_MASKING +} + + +static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, uint32_t opacity, AASpans* aaSpans) +{ +#define TEXMAP_TRANSLUCENT + #include "tvgSwRasterTexmapInternal.h" +#undef TEXMAP_TRANSLUCENT +} + + +static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, AASpans* aaSpans) +{ + #include "tvgSwRasterTexmapInternal.h" +} + + +/* This mapping algorithm is based on Mikael Kalms's. */ +static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const SwBBox* region, uint32_t opacity, Polygon& polygon, uint32_t (*blendMethod)(uint32_t), AASpans* aaSpans) +{ + float x[3] = {polygon.vertex[0].pt.x, polygon.vertex[1].pt.x, polygon.vertex[2].pt.x}; + float y[3] = {polygon.vertex[0].pt.y, polygon.vertex[1].pt.y, polygon.vertex[2].pt.y}; + float u[3] = {polygon.vertex[0].uv.x, polygon.vertex[1].uv.x, polygon.vertex[2].uv.x}; + float v[3] = {polygon.vertex[0].uv.y, polygon.vertex[1].uv.y, polygon.vertex[2].uv.y}; + + float off_y; + float dxdy[3] = {0.0f, 0.0f, 0.0f}; + float tmp; + + auto upper = false; + + //Sort the vertices in ascending Y order + if (y[0] > y[1]) { + _swap(x[0], x[1], tmp); + _swap(y[0], y[1], tmp); + _swap(u[0], u[1], tmp); + _swap(v[0], v[1], tmp); + } + if (y[0] > y[2]) { + _swap(x[0], x[2], tmp); + _swap(y[0], y[2], tmp); + _swap(u[0], u[2], tmp); + _swap(v[0], v[2], tmp); + } + if (y[1] > y[2]) { + _swap(x[1], x[2], tmp); + _swap(y[1], y[2], tmp); + _swap(u[1], u[2], tmp); + _swap(v[1], v[2], tmp); + } + + //Y indexes + int yi[3] = {(int)y[0], (int)y[1], (int)y[2]}; + + //Skip drawing if it's too thin to cover any pixels at all. + if ((yi[0] == yi[1] && yi[0] == yi[2]) || ((int) x[0] == (int) x[1] && (int) x[0] == (int) x[2])) return; + + //Calculate horizontal and vertical increments for UV axes (these calcs are certainly not optimal, although they're stable (handles any dy being 0) + auto denom = ((x[2] - x[0]) * (y[1] - y[0]) - (x[1] - x[0]) * (y[2] - y[0])); + + //Skip poly if it's an infinitely thin line + if (mathZero(denom)) return; + + denom = 1 / denom; //Reciprocal for speeding up + dudx = ((u[2] - u[0]) * (y[1] - y[0]) - (u[1] - u[0]) * (y[2] - y[0])) * denom; + dvdx = ((v[2] - v[0]) * (y[1] - y[0]) - (v[1] - v[0]) * (y[2] - y[0])) * denom; + auto dudy = ((u[1] - u[0]) * (x[2] - x[0]) - (u[2] - u[0]) * (x[1] - x[0])) * denom; + auto dvdy = ((v[1] - v[0]) * (x[2] - x[0]) - (v[2] - v[0]) * (x[1] - x[0])) * denom; + + //Calculate X-slopes along the edges + if (y[1] > y[0]) dxdy[0] = (x[1] - x[0]) / (y[1] - y[0]); + if (y[2] > y[0]) dxdy[1] = (x[2] - x[0]) / (y[2] - y[0]); + if (y[2] > y[1]) dxdy[2] = (x[2] - x[1]) / (y[2] - y[1]); + + //Determine which side of the polygon the longer edge is on + auto side = (dxdy[1] > dxdy[0]) ? true : false; + + if (mathEqual(y[0], y[1])) side = x[0] > x[1]; + if (mathEqual(y[1], y[2])) side = x[2] > x[1]; + + auto regionTop = region ? region->min.y : image->rle->spans->y; //Normal Image or Rle Image? + + //Longer edge is on the left side + if (!side) { + //Calculate slopes along left edge + dxdya = dxdy[1]; + dudya = dxdya * dudx + dudy; + dvdya = dxdya * dvdx + dvdy; + + //Perform subpixel pre-stepping along left edge + auto dy = 1.0f - (y[0] - yi[0]); + xa = x[0] + dy * dxdya; + ua = u[0] + dy * dudya; + va = v[0] + dy * dvdya; + + //Draw upper segment if possibly visible + if (yi[0] < yi[1]) { + off_y = y[0] < regionTop ? (regionTop - y[0]) : 0; + xa += (off_y * dxdya); + ua += (off_y * dudya); + va += (off_y * dvdya); + + // Set right edge X-slope and perform subpixel pre-stepping + dxdyb = dxdy[0]; + xb = x[0] + dy * dxdyb + (off_y * dxdyb); + + if (blendMethod) { + if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], blendMethod, aaSpans); + else _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, blendMethod, aaSpans); + } else { + if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], aaSpans); + else _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, aaSpans); + } + + upper = true; + } + //Draw lower segment if possibly visible + if (yi[1] < yi[2]) { + off_y = y[1] < regionTop ? (regionTop - y[1]) : 0; + if (!upper) { + xa += (off_y * dxdya); + ua += (off_y * dudya); + va += (off_y * dvdya); + } + // Set right edge X-slope and perform subpixel pre-stepping + dxdyb = dxdy[2]; + xb = x[1] + (1 - (y[1] - yi[1])) * dxdyb + (off_y * dxdyb); + if (blendMethod) { + if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], blendMethod, aaSpans); + else _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, blendMethod, aaSpans); + } else { + if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], aaSpans); + else _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, aaSpans); + } + } + //Longer edge is on the right side + } else { + //Set right edge X-slope and perform subpixel pre-stepping + dxdyb = dxdy[1]; + auto dy = 1.0f - (y[0] - yi[0]); + xb = x[0] + dy * dxdyb; + + //Draw upper segment if possibly visible + if (yi[0] < yi[1]) { + off_y = y[0] < regionTop ? (regionTop - y[0]) : 0; + xb += (off_y *dxdyb); + + // Set slopes along left edge and perform subpixel pre-stepping + dxdya = dxdy[0]; + dudya = dxdya * dudx + dudy; + dvdya = dxdya * dvdx + dvdy; + + xa = x[0] + dy * dxdya + (off_y * dxdya); + ua = u[0] + dy * dudya + (off_y * dudya); + va = v[0] + dy * dvdya + (off_y * dvdya); + + if (blendMethod) { + if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], blendMethod, aaSpans); + else _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, blendMethod, aaSpans); + } else { + if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], aaSpans); + else _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, aaSpans); + } + + upper = true; + } + //Draw lower segment if possibly visible + if (yi[1] < yi[2]) { + off_y = y[1] < regionTop ? (regionTop - y[1]) : 0; + if (!upper) xb += (off_y *dxdyb); + + // Set slopes along left edge and perform subpixel pre-stepping + dxdya = dxdy[2]; + dudya = dxdya * dudx + dudy; + dvdya = dxdya * dvdx + dvdy; + dy = 1 - (y[1] - yi[1]); + xa = x[1] + dy * dxdya + (off_y * dxdya); + ua = u[1] + dy * dudya + (off_y * dudya); + va = v[1] + dy * dvdya + (off_y * dvdya); + + if (blendMethod) { + if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], blendMethod, aaSpans); + else _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, blendMethod, aaSpans); + } else { + if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], aaSpans); + else _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, aaSpans); + } + } + } +} + + +static AASpans* _AASpans(const Vertex* vertices, const SwImage* image, const SwBBox* region) +{ + //Initialize Y range + float ys = FLT_MAX, ye = -1.0f; + + for (int i = 0; i < 4; i++) { + if (vertices[i].pt.y < ys) ys = vertices[i].pt.y; + if (vertices[i].pt.y > ye) ye = vertices[i].pt.y; + } + + auto yStart = static_cast<int32_t>(ys); + auto yEnd = static_cast<int32_t>(ye); + + if (!_arrange(image, region, yStart, yEnd)) return nullptr; + + auto aaSpans = static_cast<AASpans*>(malloc(sizeof(AASpans))); + aaSpans->yStart = yStart; + aaSpans->yEnd = yEnd; + + //Initialize X range + auto height = yEnd - yStart; + + aaSpans->lines = static_cast<AALine*>(calloc(height, sizeof(AALine))); + + for (int32_t i = 0; i < height; i++) { + aaSpans->lines[i].x[0] = INT32_MAX; + aaSpans->lines[i].x[1] = INT32_MIN; + } + return aaSpans; +} + + +static void _calcIrregularCoverage(AALine* lines, int32_t eidx, int32_t y, int32_t diagonal, int32_t edgeDist, bool reverse) +{ + if (eidx == 1) reverse = !reverse; + int32_t coverage = (255 / (diagonal + 2)); + int32_t tmp; + for (int32_t ry = 0; ry < (diagonal + 2); ry++) { + tmp = y - ry - edgeDist; + if (tmp < 0) return; + lines[tmp].length[eidx] = 1; + if (reverse) lines[tmp].coverage[eidx] = 255 - (coverage * ry); + else lines[tmp].coverage[eidx] = (coverage * ry); + } +} + + +static void _calcVertCoverage(AALine *lines, int32_t eidx, int32_t y, int32_t rewind, bool reverse) +{ + if (eidx == 1) reverse = !reverse; + int32_t coverage = (255 / (rewind + 1)); + int32_t tmp; + for (int ry = 1; ry < (rewind + 1); ry++) { + tmp = y - ry; + if (tmp < 0) return; + lines[tmp].length[eidx] = 1; + if (reverse) lines[tmp].coverage[eidx] = (255 - (coverage * ry)); + else lines[tmp].coverage[eidx] = (coverage * ry); + } +} + + +static void _calcHorizCoverage(AALine *lines, int32_t eidx, int32_t y, int32_t x, int32_t x2) +{ + if (lines[y].length[eidx] < abs(x - x2)) { + lines[y].length[eidx] = abs(x - x2); + lines[y].coverage[eidx] = (255 / (lines[y].length[eidx] + 1)); + } +} + + +/* + * This Anti-Aliasing mechanism is originated from Hermet Park's idea. + * To understand this AA logic, you can refer this page: + * www.hermet.pe.kr/122 (hermetpark@gmail.com) +*/ +static void _calcAAEdge(AASpans *aaSpans, int32_t eidx) +{ +//Previous edge direction: +#define DirOutHor 0x0011 +#define DirOutVer 0x0001 +#define DirInHor 0x0010 +#define DirInVer 0x0000 +#define DirNone 0x1000 + +#define PUSH_VERTEX() \ + do { \ + pEdge.x = lines[y].x[eidx]; \ + pEdge.y = y; \ + ptx[0] = tx[0]; \ + ptx[1] = tx[1]; \ + } while (0) + + int32_t y = 0; + SwPoint pEdge = {-1, -1}; //previous edge point + SwPoint edgeDiff = {0, 0}; //temporary used for point distance + + /* store bigger to tx[0] between prev and current edge's x positions. */ + int32_t tx[2] = {0, 0}; + /* back up prev tx values */ + int32_t ptx[2] = {0, 0}; + int32_t diagonal = 0; //straight diagonal pixels count + + auto yStart = aaSpans->yStart; + auto yEnd = aaSpans->yEnd; + auto lines = aaSpans->lines; + + int32_t prevDir = DirNone; + int32_t curDir = DirNone; + + yEnd -= yStart; + + //Start Edge + if (y < yEnd) { + pEdge.x = lines[y].x[eidx]; + pEdge.y = y; + } + + //Calculates AA Edges + for (y++; y < yEnd; y++) { + //Ready tx + if (eidx == 0) { + tx[0] = pEdge.x; + tx[1] = lines[y].x[0]; + } else { + tx[0] = lines[y].x[1]; + tx[1] = pEdge.x; + } + edgeDiff.x = (tx[0] - tx[1]); + edgeDiff.y = (y - pEdge.y); + + //Confirm current edge direction + if (edgeDiff.x > 0) { + if (edgeDiff.y == 1) curDir = DirOutHor; + else curDir = DirOutVer; + } else if (edgeDiff.x < 0) { + if (edgeDiff.y == 1) curDir = DirInHor; + else curDir = DirInVer; + } else curDir = DirNone; + + //straight diagonal increase + if ((curDir == prevDir) && (y < yEnd)) { + if ((abs(edgeDiff.x) == 1) && (edgeDiff.y == 1)) { + ++diagonal; + PUSH_VERTEX(); + continue; + } + } + + switch (curDir) { + case DirOutHor: { + _calcHorizCoverage(lines, eidx, y, tx[0], tx[1]); + if (diagonal > 0) { + _calcIrregularCoverage(lines, eidx, y, diagonal, 0, true); + diagonal = 0; + } + /* Increment direction is changed: Outside Vertical -> Outside Horizontal */ + if (prevDir == DirOutVer) _calcHorizCoverage(lines, eidx, pEdge.y, ptx[0], ptx[1]); + + //Trick, but fine-tunning! + if (y == 1) _calcHorizCoverage(lines, eidx, pEdge.y, tx[0], tx[1]); + PUSH_VERTEX(); + } + break; + case DirOutVer: { + _calcVertCoverage(lines, eidx, y, edgeDiff.y, true); + if (diagonal > 0) { + _calcIrregularCoverage(lines, eidx, y, diagonal, edgeDiff.y, false); + diagonal = 0; + } + /* Increment direction is changed: Outside Horizontal -> Outside Vertical */ + if (prevDir == DirOutHor) _calcHorizCoverage(lines, eidx, pEdge.y, ptx[0], ptx[1]); + PUSH_VERTEX(); + } + break; + case DirInHor: { + _calcHorizCoverage(lines, eidx, (y - 1), tx[0], tx[1]); + if (diagonal > 0) { + _calcIrregularCoverage(lines, eidx, y, diagonal, 0, false); + diagonal = 0; + } + /* Increment direction is changed: Outside Horizontal -> Inside Horizontal */ + if (prevDir == DirOutHor) _calcHorizCoverage(lines, eidx, pEdge.y, ptx[0], ptx[1]); + PUSH_VERTEX(); + } + break; + case DirInVer: { + _calcVertCoverage(lines, eidx, y, edgeDiff.y, false); + if (prevDir == DirOutHor) edgeDiff.y -= 1; //Weird, fine tuning????????????????????? + if (diagonal > 0) { + _calcIrregularCoverage(lines, eidx, y, diagonal, edgeDiff.y, true); + diagonal = 0; + } + /* Increment direction is changed: Outside Horizontal -> Inside Vertical */ + if (prevDir == DirOutHor) _calcHorizCoverage(lines, eidx, pEdge.y, ptx[0], ptx[1]); + PUSH_VERTEX(); + } + break; + } + if (curDir != DirNone) prevDir = curDir; + } + + //leftovers...? + if ((edgeDiff.y == 1) && (edgeDiff.x != 0)) { + if (y >= yEnd) y = (yEnd - 1); + _calcHorizCoverage(lines, eidx, y - 1, ptx[0], ptx[1]); + _calcHorizCoverage(lines, eidx, y, tx[0], tx[1]); + } else { + ++y; + if (y > yEnd) y = yEnd; + _calcVertCoverage(lines, eidx, y, (edgeDiff.y + 1), (prevDir & 0x00000001)); + } +} + + +static bool _apply(SwSurface* surface, AASpans* aaSpans) +{ + auto y = aaSpans->yStart; + uint32_t pixel; + uint32_t* dst; + int32_t pos; + + //left side + _calcAAEdge(aaSpans, 0); + //right side + _calcAAEdge(aaSpans, 1); + + while (y < aaSpans->yEnd) { + auto line = &aaSpans->lines[y - aaSpans->yStart]; + auto width = line->x[1] - line->x[0]; + if (width > 0) { + auto offset = y * surface->stride; + + //Left edge + dst = surface->buffer + (offset + line->x[0]); + if (line->x[0] > 1) pixel = *(dst - 1); + else pixel = *dst; + + pos = 1; + while (pos <= line->length[0]) { + *dst = INTERPOLATE((line->coverage[0] * pos), *dst, pixel); + ++dst; + ++pos; + } + + //Right edge + dst = surface->buffer + (offset + line->x[1] - 1); + if (line->x[1] < (int32_t)(surface->w - 1)) pixel = *(dst + 1); + else pixel = *dst; + + pos = width; + while ((int32_t)(width - line->length[1]) < pos) { + *dst = INTERPOLATE(255 - (line->coverage[1] * (line->length[1] - (width - pos))), *dst, pixel); + --dst; + --pos; + } + } + y++; + } + + free(aaSpans->lines); + free(aaSpans); + + return true; +} + + +/* + 2 triangles constructs 1 mesh. + below figure illustrates vert[4] index info. + If you need better quality, please divide a mesh by more number of triangles. + + 0 -- 1 + | / | + | / | + 3 -- 2 +*/ +static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox* region, uint32_t opacity, uint32_t (*blendMethod)(uint32_t)) +{ + //Exceptions: No dedicated drawing area? + if (!region && image->rle->size == 0) return false; + + /* Prepare vertices. + shift XY coordinates to match the sub-pixeling technique. */ + Vertex vertices[4]; + vertices[0] = {{0.0f, 0.0f}, {0.0f, 0.0f}}; + vertices[1] = {{float(image->w), 0.0f}, {float(image->w), 0.0f}}; + vertices[2] = {{float(image->w), float(image->h)}, {float(image->w), float(image->h)}}; + vertices[3] = {{0.0f, float(image->h)}, {0.0f, float(image->h)}}; + + for (int i = 0; i < 4; i++) mathMultiply(&vertices[i].pt, transform); + + auto aaSpans = _AASpans(vertices, image, region); + if (!aaSpans) return true; + + Polygon polygon; + + //Draw the first polygon + polygon.vertex[0] = vertices[0]; + polygon.vertex[1] = vertices[1]; + polygon.vertex[2] = vertices[3]; + + _rasterPolygonImage(surface, image, region, opacity, polygon, blendMethod, aaSpans); + + //Draw the second polygon + polygon.vertex[0] = vertices[1]; + polygon.vertex[1] = vertices[2]; + polygon.vertex[2] = vertices[3]; + + _rasterPolygonImage(surface, image, region, opacity, polygon, blendMethod, aaSpans); + + return _apply(surface, aaSpans); +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h new file mode 100644 index 0000000000..4e8d342137 --- /dev/null +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +{ + float _dudx = dudx, _dvdx = dvdx; + float _dxdya = dxdya, _dxdyb = dxdyb, _dudya = dudya, _dvdya = dvdya; + float _xa = xa, _xb = xb, _ua = ua, _va = va; + auto sbuf = image->data; + auto dbuf = surface->buffer; + int32_t sw = static_cast<int32_t>(image->stride); + int32_t sh = image->h; + int32_t dw = surface->stride; + int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay; + int32_t vv = 0, uu = 0; + int32_t minx, maxx; + float dx, u, v, iptr; + uint32_t* buf; + SwSpan* span = nullptr; //used only when rle based. + +#ifdef TEXMAP_MASKING + uint32_t* cmp; +#endif + + if (!_arrange(image, region, yStart, yEnd)) return; + + //Loop through all lines in the segment + uint32_t spanIdx = 0; + + if (region) { + minx = region->min.x; + maxx = region->max.x; + } else { + span = image->rle->spans; + while (span->y < yStart) { + ++span; + ++spanIdx; + } + } + + y = yStart; + + while (y < yEnd) { + x1 = _xa; + x2 = _xb; + + if (!region) { + minx = INT32_MAX; + maxx = INT32_MIN; + //one single row, could be consisted of multiple spans. + while (span->y == y && spanIdx < image->rle->size) { + if (minx > span->x) minx = span->x; + if (maxx < span->x + span->len) maxx = span->x + span->len; + ++span; + ++spanIdx; + } + } + if (x1 < minx) x1 = minx; + if (x2 > maxx) x2 = maxx; + + //Anti-Aliasing frames + ay = y - aaSpans->yStart; + if (aaSpans->lines[ay].x[0] > x1) aaSpans->lines[ay].x[0] = x1; + if (aaSpans->lines[ay].x[1] < x2) aaSpans->lines[ay].x[1] = x2; + + //Range exception + if ((x2 - x1) < 1 || (x1 >= maxx) || (x2 <= minx)) goto next; + + //Perform subtexel pre-stepping on UV + dx = 1 - (_xa - x1); + u = _ua + dx * _dudx; + v = _va + dx * _dvdx; + + buf = dbuf + ((y * dw) + x1); + + x = x1; + +#ifdef TEXMAP_MASKING + cmp = &surface->compositor->image.data[y * surface->compositor->image.stride + x1]; +#endif + //Draw horizontal line + while (x++ < x2) { + uu = (int) u; + vv = (int) v; + + ar = (int)(255 * (1 - modff(u, &iptr))); + ab = (int)(255 * (1 - modff(v, &iptr))); + iru = uu + 1; + irv = vv + 1; + px = *(sbuf + (vv * sw) + uu); + + /* horizontal interpolate */ + if (iru < sw) { + /* right pixel */ + int px2 = *(sbuf + (vv * sw) + iru); + px = INTERPOLATE(ar, px, px2); + } + /* vertical interpolate */ + if (irv < sh) { + /* bottom pixel */ + int px2 = *(sbuf + (irv * sw) + uu); + + /* horizontal interpolate */ + if (iru < sw) { + /* bottom right pixel */ + int px3 = *(sbuf + (irv * sw) + iru); + px2 = INTERPOLATE(ar, px2, px3); + } + px = INTERPOLATE(ab, px, px2); + } +#if defined(TEXMAP_MASKING) && defined(TEXMAP_TRANSLUCENT) + auto src = ALPHA_BLEND(px, _multiplyAlpha(opacity, blendMethod(*cmp))); +#elif defined(TEXMAP_MASKING) + auto src = ALPHA_BLEND(px, blendMethod(*cmp)); +#elif defined(TEXMAP_TRANSLUCENT) + auto src = ALPHA_BLEND(px, opacity); +#else + auto src = px; +#endif + *buf = src + ALPHA_BLEND(*buf, _ialpha(src)); + ++buf; +#ifdef TEXMAP_MASKING + ++cmp; +#endif + //Step UV horizontally + u += _dudx; + v += _dvdx; + //range over? + if ((uint32_t)v >= image->h) break; + } +next: + //Step along both edges + _xa += _dxdya; + _xb += _dxdyb; + _ua += _dudya; + _va += _dvdya; + + if (!region && spanIdx >= image->rle->size) break; + + ++y; + } + xa = _xa; + xb = _xb; + ua = _ua; + va = _va; +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp new file mode 100644 index 0000000000..78537e7726 --- /dev/null +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp @@ -0,0 +1,685 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include <math.h> +#include "tvgSwCommon.h" +#include "tvgTaskScheduler.h" +#include "tvgSwRenderer.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ +static int32_t initEngineCnt = false; +static int32_t rendererCnt = 0; +static SwMpool* globalMpool = nullptr; +static uint32_t threadsCnt = 0; + +struct SwTask : Task +{ + Matrix* transform = nullptr; + SwSurface* surface = nullptr; + SwMpool* mpool = nullptr; + RenderUpdateFlag flags = RenderUpdateFlag::None; + Array<RenderData> clips; + uint32_t opacity; + SwBBox bbox = {{0, 0}, {0, 0}}; //Whole Rendering Region + bool pushed = false; //Pushed into task list? + bool disposed = false; //Disposed task? + + RenderRegion bounds() const + { + RenderRegion region; + + //Range over? + region.x = bbox.min.x > 0 ? bbox.min.x : 0; + region.y = bbox.min.y > 0 ? bbox.min.y : 0; + region.w = bbox.max.x - region.x; + region.h = bbox.max.y - region.y; + if (region.w < 0) region.w = 0; + if (region.h < 0) region.h = 0; + + return region; + } + + virtual bool dispose() = 0; + + virtual ~SwTask() + { + free(transform); + } +}; + + +struct SwShapeTask : SwTask +{ + SwShape shape; + const Shape* sdata = nullptr; + bool cmpStroking = false; + + void run(unsigned tid) override + { + if (opacity == 0) return; //Invisible + + uint8_t strokeAlpha = 0; + auto visibleStroke = false; + bool visibleFill = false; + auto clipRegion = bbox; + + if (HALF_STROKE(sdata->strokeWidth()) > 0) { + sdata->strokeColor(nullptr, nullptr, nullptr, &strokeAlpha); + visibleStroke = sdata->strokeFill() || (static_cast<uint32_t>(strokeAlpha * opacity / 255) > 0); + } + + //This checks also for the case, if the invisible shape turned to visible by alpha. + auto prepareShape = false; + if (!shapePrepared(&shape) && (flags & RenderUpdateFlag::Color)) prepareShape = true; + + //Shape + if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform) || prepareShape) { + uint8_t alpha = 0; + sdata->fillColor(nullptr, nullptr, nullptr, &alpha); + alpha = static_cast<uint8_t>(static_cast<uint32_t>(alpha) * opacity / 255); + visibleFill = (alpha > 0 || sdata->fill()); + if (visibleFill || visibleStroke) { + shapeReset(&shape); + if (!shapePrepare(&shape, sdata, transform, clipRegion, bbox, mpool, tid, clips.count > 0 ? true : false)) goto err; + } + } + + //Decide Stroking Composition + if (visibleStroke && visibleFill && opacity < 255) cmpStroking = true; + else cmpStroking = false; + + //Fill + if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) { + if (visibleFill) { + /* We assume that if stroke width is bigger than 2, + shape outline below stroke could be full covered by stroke drawing. + Thus it turns off antialising in that condition. + Also, it shouldn't be dash style. */ + auto antiAlias = (strokeAlpha == 255 && sdata->strokeWidth() > 2 && sdata->strokeDash(nullptr) == 0) ? false : true; + + if (!shapeGenRle(&shape, sdata, antiAlias)) goto err; + } + if (auto fill = sdata->fill()) { + auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false; + if (ctable) shapeResetFill(&shape); + if (!shapeGenFillColors(&shape, fill, transform, surface, cmpStroking ? 255 : opacity, ctable)) goto err; + } else { + shapeDelFill(&shape); + } + } + + //Stroke + if (flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) { + if (visibleStroke) { + shapeResetStroke(&shape, sdata, transform); + if (!shapeGenStrokeRle(&shape, sdata, transform, clipRegion, bbox, mpool, tid)) goto err; + + if (auto fill = sdata->strokeFill()) { + auto ctable = (flags & RenderUpdateFlag::GradientStroke) ? true : false; + if (ctable) shapeResetStrokeFill(&shape); + if (!shapeGenStrokeFillColors(&shape, fill, transform, surface, cmpStroking ? 255 : opacity, ctable)) goto err; + } else { + shapeDelStrokeFill(&shape); + } + } else { + shapeDelStroke(&shape); + } + } + + //Clip Path + for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) { + auto clipper = &static_cast<SwShapeTask*>(*clip)->shape; + //Clip shape rle + if (shape.rle) { + if (clipper->fastTrack) rleClipRect(shape.rle, &clipper->bbox); + else if (clipper->rle) rleClipPath(shape.rle, clipper->rle); + else goto err; + } + //Clip stroke rle + if (shape.strokeRle) { + if (clipper->fastTrack) rleClipRect(shape.strokeRle, &clipper->bbox); + else if (clipper->rle) rleClipPath(shape.strokeRle, clipper->rle); + else goto err; + } + } + goto end; + + err: + shapeReset(&shape); + end: + shapeDelOutline(&shape, mpool, tid); + } + + bool dispose() override + { + shapeFree(&shape); + return true; + } +}; + + +struct SwImageTask : SwTask +{ + SwImage image; + + void run(unsigned tid) override + { + auto clipRegion = bbox; + + //Invisible shape turned to visible by alpha. + if ((flags & (RenderUpdateFlag::Image | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) && (opacity > 0)) { + imageReset(&image); + if (!image.data || image.w == 0 || image.h == 0) goto end; + + if (!imagePrepare(&image, transform, clipRegion, bbox, mpool, tid)) goto end; + + if (clips.count > 0) { + if (!imageGenRle(&image, bbox, false)) goto end; + if (image.rle) { + for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) { + auto clipper = &static_cast<SwShapeTask*>(*clip)->shape; + if (clipper->fastTrack) rleClipRect(image.rle, &clipper->bbox); + else if (clipper->rle) rleClipPath(image.rle, clipper->rle); + else goto err; + } + } + } + } + goto end; + + err: + rleReset(image.rle); + end: + imageDelOutline(&image, mpool, tid); + } + + bool dispose() override + { + imageFree(&image); + return true; + } +}; + + +static void _termEngine() +{ + if (rendererCnt > 0) return; + + mpoolTerm(globalMpool); + globalMpool = nullptr; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +SwRenderer::~SwRenderer() +{ + clearCompositors(); + + if (surface) delete(surface); + + if (!sharedMpool) mpoolTerm(mpool); + + --rendererCnt; + + if (rendererCnt == 0 && initEngineCnt == 0) _termEngine(); +} + + +bool SwRenderer::clear() +{ + for (auto task = tasks.data; task < (tasks.data + tasks.count); ++task) { + if ((*task)->disposed) { + delete(*task); + } else { + (*task)->done(); + (*task)->pushed = false; + } + } + tasks.clear(); + + if (!sharedMpool) mpoolClear(mpool); + + if (surface) { + vport.x = vport.y = 0; + vport.w = surface->w; + vport.h = surface->h; + } + + return true; +} + + +bool SwRenderer::sync() +{ + return true; +} + + +RenderRegion SwRenderer::viewport() +{ + return vport; +} + + +bool SwRenderer::viewport(const RenderRegion& vp) +{ + vport = vp; + return true; +} + + +bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, uint32_t cs) +{ + if (!buffer || stride == 0 || w == 0 || h == 0 || w > stride) return false; + + if (!surface) surface = new SwSurface; + + surface->buffer = buffer; + surface->stride = stride; + surface->w = w; + surface->h = h; + surface->cs = cs; + + vport.x = vport.y = 0; + vport.w = surface->w; + vport.h = surface->h; + + return rasterCompositor(surface); +} + + +bool SwRenderer::preRender() +{ + return rasterClear(surface); +} + +void SwRenderer::clearCompositors() +{ + //Free Composite Caches + for (auto comp = compositors.data; comp < (compositors.data + compositors.count); ++comp) { + free((*comp)->compositor->image.data); + delete((*comp)->compositor); + delete(*comp); + } + compositors.reset(); +} + + +bool SwRenderer::postRender() +{ + //Unmultiply alpha if needed + if (surface->cs == SwCanvas::ABGR8888_STRAIGHT || surface->cs == SwCanvas::ARGB8888_STRAIGHT) { + rasterUnpremultiply(surface); + } + + for (auto task = tasks.data; task < (tasks.data + tasks.count); ++task) { + (*task)->pushed = false; + } + tasks.clear(); + + clearCompositors(); + return true; +} + + +bool SwRenderer::renderImage(RenderData data) +{ + auto task = static_cast<SwImageTask*>(data); + task->done(); + + if (task->opacity == 0) return true; + + return rasterImage(surface, &task->image, task->transform, task->bbox, task->opacity); +} + + +bool SwRenderer::renderShape(RenderData data) +{ + auto task = static_cast<SwShapeTask*>(data); + if (!task) return false; + + task->done(); + + if (task->opacity == 0) return true; + + uint32_t opacity; + Compositor* cmp = nullptr; + + //Do Stroking Composition + if (task->cmpStroking) { + opacity = 255; + cmp = target(task->bounds()); + beginComposite(cmp, CompositeMethod::None, task->opacity); + //No Stroking Composition + } else { + opacity = task->opacity; + } + + //Main raster stage + uint8_t r, g, b, a; + + if (auto fill = task->sdata->fill()) { + rasterGradientShape(surface, &task->shape, fill->identifier()); + } else { + task->sdata->fillColor(&r, &g, &b, &a); + a = static_cast<uint8_t>((opacity * (uint32_t) a) / 255); + if (a > 0) rasterShape(surface, &task->shape, r, g, b, a); + } + + if (auto strokeFill = task->sdata->strokeFill()) { + rasterGradientStroke(surface, &task->shape, strokeFill->identifier()); + } else { + if (task->sdata->strokeColor(&r, &g, &b, &a) == Result::Success) { + a = static_cast<uint8_t>((opacity * (uint32_t) a) / 255); + if (a > 0) rasterStroke(surface, &task->shape, r, g, b, a); + } + } + + if (task->cmpStroking) endComposite(cmp); + + return true; +} + + +RenderRegion SwRenderer::region(RenderData data) +{ + return static_cast<SwTask*>(data)->bounds(); +} + + +bool SwRenderer::beginComposite(Compositor* cmp, CompositeMethod method, uint32_t opacity) +{ + if (!cmp) return false; + auto p = static_cast<SwCompositor*>(cmp); + + p->method = method; + p->opacity = opacity; + + //Current Context? + if (p->method != CompositeMethod::None) { + surface = p->recoverSfc; + surface->compositor = p; + } + + return true; +} + + +bool SwRenderer::mempool(bool shared) +{ + if (shared == sharedMpool) return true; + + if (shared) { + if (!sharedMpool) { + if (!mpoolTerm(mpool)) return false; + mpool = globalMpool; + } + } else { + if (sharedMpool) mpool = mpoolInit(threadsCnt); + } + + sharedMpool = shared; + + if (mpool) return true; + return false; +} + + +Compositor* SwRenderer::target(const RenderRegion& region) +{ + auto x = region.x; + auto y = region.y; + auto w = region.w; + auto h = region.h; + auto sw = static_cast<int32_t>(surface->w); + auto sh = static_cast<int32_t>(surface->h); + + //Out of boundary + if (x > sw || y > sh) return nullptr; + + SwSurface* cmp = nullptr; + + //Use cached data + for (auto p = compositors.data; p < (compositors.data + compositors.count); ++p) { + if ((*p)->compositor->valid) { + cmp = *p; + break; + } + } + + //New Composition + if (!cmp) { + cmp = new SwSurface; + if (!cmp) goto err; + + //Inherits attributes from main surface + *cmp = *surface; + + cmp->compositor = new SwCompositor; + if (!cmp->compositor) goto err; + + //SwImage, Optimize Me: Surface size from MainSurface(WxH) to Parameter W x H + cmp->compositor->image.data = (uint32_t*) malloc(sizeof(uint32_t) * surface->stride * surface->h); + if (!cmp->compositor->image.data) goto err; + compositors.push(cmp); + } + + //Boundary Check + if (x + w > sw) w = (sw - x); + if (y + h > sh) h = (sh - y); + + TVGLOG("SW_ENGINE", "Using intermediate composition [Region: %d %d %d %d]", x, y, w, h); + + cmp->compositor->recoverSfc = surface; + cmp->compositor->recoverCmp = surface->compositor; + cmp->compositor->valid = false; + cmp->compositor->bbox.min.x = x; + cmp->compositor->bbox.min.y = y; + cmp->compositor->bbox.max.x = x + w; + cmp->compositor->bbox.max.y = y + h; + cmp->compositor->image.stride = surface->stride; + cmp->compositor->image.w = surface->w; + cmp->compositor->image.h = surface->h; + cmp->compositor->image.direct = true; + + //We know partial clear region + cmp->buffer = cmp->compositor->image.data + (cmp->stride * y + x); + cmp->w = w; + cmp->h = h; + + rasterClear(cmp); + + //Recover context + cmp->buffer = cmp->compositor->image.data; + cmp->w = cmp->compositor->image.w; + cmp->h = cmp->compositor->image.h; + + //Switch render target + surface = cmp; + + return cmp->compositor; + +err: + if (cmp) { + if (cmp->compositor) delete(cmp->compositor); + delete(cmp); + } + + return nullptr; +} + + +bool SwRenderer::endComposite(Compositor* cmp) +{ + if (!cmp) return false; + + auto p = static_cast<SwCompositor*>(cmp); + p->valid = true; + + //Recover Context + surface = p->recoverSfc; + surface->compositor = p->recoverCmp; + + //Default is alpha blending + if (p->method == CompositeMethod::None) { + return rasterImage(surface, &p->image, nullptr, p->bbox, p->opacity); + } + + return true; +} + + +bool SwRenderer::dispose(RenderData data) +{ + auto task = static_cast<SwTask*>(data); + if (!task) return true; + task->done(); + task->dispose(); + + if (task->pushed) task->disposed = true; + else delete(task); + + return true; +} + + +void* SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform, uint32_t opacity, const Array<RenderData>& clips, RenderUpdateFlag flags) +{ + if (!surface) return task; + if (flags == RenderUpdateFlag::None) return task; + + //Finish previous task if it has duplicated request. + task->done(); + + if (clips.count > 0) { + //Guarantee composition targets get ready. + for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) { + static_cast<SwShapeTask*>(*clip)->done(); + } + task->clips = clips; + } + + if (transform) { + if (!task->transform) task->transform = static_cast<Matrix*>(malloc(sizeof(Matrix))); + *task->transform = transform->m; + } else { + if (task->transform) free(task->transform); + task->transform = nullptr; + } + + task->opacity = opacity; + task->surface = surface; + task->mpool = mpool; + task->flags = flags; + task->bbox.min.x = max(static_cast<SwCoord>(0), static_cast<SwCoord>(vport.x)); + task->bbox.min.y = max(static_cast<SwCoord>(0), static_cast<SwCoord>(vport.y)); + task->bbox.max.x = min(static_cast<SwCoord>(surface->w), static_cast<SwCoord>(vport.x + vport.w)); + task->bbox.max.y = min(static_cast<SwCoord>(surface->h), static_cast<SwCoord>(vport.y + vport.h)); + + if (!task->pushed) { + task->pushed = true; + tasks.push(task); + } + + TaskScheduler::request(task); + + return task; +} + + +RenderData SwRenderer::prepare(Surface* image, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) +{ + //prepare task + auto task = static_cast<SwImageTask*>(data); + if (!task) { + task = new SwImageTask; + if (flags & RenderUpdateFlag::Image) { + task->image.data = image->buffer; + task->image.w = image->w; + task->image.h = image->h; + task->image.stride = image->stride; + } + } + return prepareCommon(task, transform, opacity, clips, flags); +} + + +RenderData SwRenderer::prepare(const Shape& sdata, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) +{ + //prepare task + auto task = static_cast<SwShapeTask*>(data); + if (!task) { + task = new SwShapeTask; + task->sdata = &sdata; + } + return prepareCommon(task, transform, opacity, clips, flags); +} + + +SwRenderer::SwRenderer():mpool(globalMpool) +{ +} + + +bool SwRenderer::init(uint32_t threads) +{ + if ((initEngineCnt++) > 0) return true; + + threadsCnt = threads; + + //Share the memory pool among the renderer + globalMpool = mpoolInit(threads); + if (!globalMpool) { + --initEngineCnt; + return false; + } + + return true; +} + + +int32_t SwRenderer::init() +{ + return initEngineCnt; +} + + +bool SwRenderer::term() +{ + if ((--initEngineCnt) > 0) return true; + + initEngineCnt = 0; + + _termEngine(); + + return true; +} + +SwRenderer* SwRenderer::gen() +{ + ++rendererCnt; + return new SwRenderer(); +} diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h new file mode 100644 index 0000000000..3f883ac409 --- /dev/null +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_SW_RENDERER_H_ +#define _TVG_SW_RENDERER_H_ + +#include "tvgRender.h" + +struct SwSurface; +struct SwTask; +struct SwCompositor; +struct SwMpool; + +namespace tvg +{ + +class SwRenderer : public RenderMethod +{ +public: + RenderData prepare(const Shape& shape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) override; + RenderData prepare(Surface* image, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) override; + bool preRender() override; + bool renderShape(RenderData data) override; + bool renderImage(RenderData data) override; + bool postRender() override; + bool dispose(RenderData data) override; + RenderRegion region(RenderData data) override; + RenderRegion viewport() override; + bool viewport(const RenderRegion& vp) override; + + bool clear() override; + bool sync() override; + bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, uint32_t cs); + bool mempool(bool shared); + + Compositor* target(const RenderRegion& region) override; + bool beginComposite(Compositor* cmp, CompositeMethod method, uint32_t opacity) override; + bool endComposite(Compositor* cmp) override; + void clearCompositors(); + + static SwRenderer* gen(); + static bool init(uint32_t threads); + static int32_t init(); + static bool term(); + +private: + SwSurface* surface = nullptr; //active surface + Array<SwTask*> tasks; //async task list + Array<SwSurface*> compositors; //render targets cache list + SwMpool* mpool; //private memory pool + RenderRegion vport; //viewport + + bool sharedMpool = true; //memory-pool behavior policy + + SwRenderer(); + ~SwRenderer(); + + RenderData prepareCommon(SwTask* task, const RenderTransform* transform, uint32_t opacity, const Array<RenderData>& clips, RenderUpdateFlag flags); +}; + +} + +#endif /* _TVG_SW_RENDERER_H_ */ diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRle.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRle.cpp new file mode 100644 index 0000000000..b41e48b7ca --- /dev/null +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRle.cpp @@ -0,0 +1,1043 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * The FreeType Project LICENSE + * ---------------------------- + + * 2006-Jan-27 + + * Copyright 1996-2002, 2006 by + * David Turner, Robert Wilhelm, and Werner Lemberg + + + + * Introduction + * ============ + + * The FreeType Project is distributed in several archive packages; + * some of them may contain, in addition to the FreeType font engine, + * various tools and contributions which rely on, or relate to, the + * FreeType Project. + + * This license applies to all files found in such packages, and + * which do not fall under their own explicit license. The license + * affects thus the FreeType font engine, the test programs, + * documentation and makefiles, at the very least. + + * This license was inspired by the BSD, Artistic, and IJG + * (Independent JPEG Group) licenses, which all encourage inclusion + * and use of free software in commercial and freeware products + * alike. As a consequence, its main points are that: + + * o We don't promise that this software works. However, we will be + * interested in any kind of bug reports. (`as is' distribution) + + * o You can use this software for whatever you want, in parts or + * full form, without having to pay us. (`royalty-free' usage) + + * o You may not pretend that you wrote this software. If you use + * it, or only parts of it, in a program, you must acknowledge + * somewhere in your documentation that you have used the + * FreeType code. (`credits') + + * We specifically permit and encourage the inclusion of this + * software, with or without modifications, in commercial products. + * We disclaim all warranties covering The FreeType Project and + * assume no liability related to The FreeType Project. + + + * Finally, many people asked us for a preferred form for a + * credit/disclaimer to use in compliance with this license. We thus + * encourage you to use the following text: + + * """ + * Portions of this software are copyright � <year> The FreeType + * Project (www.freetype.org). All rights reserved. + * """ + + * Please replace <year> with the value from the FreeType version you + * actually use. + +* Legal Terms +* =========== + +* 0. Definitions +* -------------- + +* Throughout this license, the terms `package', `FreeType Project', +* and `FreeType archive' refer to the set of files originally +* distributed by the authors (David Turner, Robert Wilhelm, and +* Werner Lemberg) as the `FreeType Project', be they named as alpha, +* beta or final release. + +* `You' refers to the licensee, or person using the project, where +* `using' is a generic term including compiling the project's source +* code as well as linking it to form a `program' or `executable'. +* This program is referred to as `a program using the FreeType +* engine'. + +* This license applies to all files distributed in the original +* FreeType Project, including all source code, binaries and +* documentation, unless otherwise stated in the file in its +* original, unmodified form as distributed in the original archive. +* If you are unsure whether or not a particular file is covered by +* this license, you must contact us to verify this. + +* The FreeType Project is copyright (C) 1996-2000 by David Turner, +* Robert Wilhelm, and Werner Lemberg. All rights reserved except as +* specified below. + +* 1. No Warranty +* -------------- + +* THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY +* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +* PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS +* BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO +* USE, OF THE FREETYPE PROJECT. + +* 2. Redistribution +* ----------------- + +* This license grants a worldwide, royalty-free, perpetual and +* irrevocable right and license to use, execute, perform, compile, +* display, copy, create derivative works of, distribute and +* sublicense the FreeType Project (in both source and object code +* forms) and derivative works thereof for any purpose; and to +* authorize others to exercise some or all of the rights granted +* herein, subject to the following conditions: + +* o Redistribution of source code must retain this license file +* (`FTL.TXT') unaltered; any additions, deletions or changes to +* the original files must be clearly indicated in accompanying +* documentation. The copyright notices of the unaltered, +* original files must be preserved in all copies of source +* files. + +* o Redistribution in binary form must provide a disclaimer that +* states that the software is based in part of the work of the +* FreeType Team, in the distribution documentation. We also +* encourage you to put an URL to the FreeType web page in your +* documentation, though this isn't mandatory. + +* These conditions apply to any software derived from or based on +* the FreeType Project, not just the unmodified files. If you use +* our work, you must acknowledge us. However, no fee need be paid +* to us. + +* 3. Advertising +* -------------- + +* Neither the FreeType authors and contributors nor you shall use +* the name of the other for commercial, advertising, or promotional +* purposes without specific prior written permission. + +* We suggest, but do not require, that you use one or more of the +* following phrases to refer to this software in your documentation +* or advertising materials: `FreeType Project', `FreeType Engine', +* `FreeType library', or `FreeType Distribution'. + +* As you have not signed this license, you are not required to +* accept it. However, as the FreeType Project is copyrighted +* material, only this license, or another one contracted with the +* authors, grants you the right to use, distribute, and modify it. +* Therefore, by using, distributing, or modifying the FreeType +* Project, you indicate that you understand and accept all the terms +* of this license. + +* 4. Contacts +* ----------- + +* There are two mailing lists related to FreeType: + +* o freetype@nongnu.org + +* Discusses general use and applications of FreeType, as well as +* future and wanted additions to the library and distribution. +* If you are looking for support, start in this list if you +* haven't found anything to help you in the documentation. + +* o freetype-devel@nongnu.org + +* Discusses bugs, as well as engine internals, design issues, +* specific licenses, porting, etc. + +* Our home page can be found at + +* http://www.freetype.org +*/ + +#include <setjmp.h> +#include <limits.h> +#include <memory.h> +#include "tvgSwCommon.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +constexpr auto MAX_SPANS = 256; +constexpr auto PIXEL_BITS = 8; //must be at least 6 bits! +constexpr auto ONE_PIXEL = (1L << PIXEL_BITS); + +using Area = long; + +struct Band +{ + SwCoord min, max; +}; + +struct Cell +{ + SwCoord x; + SwCoord cover; + Area area; + Cell *next; +}; + +struct RleWorker +{ + SwRleData* rle; + + SwPoint cellPos; + SwPoint cellMin; + SwPoint cellMax; + SwCoord cellXCnt; + SwCoord cellYCnt; + + Area area; + SwCoord cover; + + Cell* cells; + ptrdiff_t maxCells; + ptrdiff_t cellsCnt; + + SwPoint pos; + + SwPoint bezStack[32 * 3 + 1]; + int levStack[32]; + + SwOutline* outline; + + SwSpan spans[MAX_SPANS]; + int spansCnt; + int ySpan; + + int bandSize; + int bandShoot; + + jmp_buf jmpBuf; + + void* buffer; + long bufferSize; + + Cell** yCells; + SwCoord yCnt; + + bool invalid; + bool antiAlias; +}; + + +static inline SwPoint UPSCALE(const SwPoint& pt) +{ + return {SwCoord(((unsigned long) pt.x) << (PIXEL_BITS - 6)), SwCoord(((unsigned long) pt.y) << (PIXEL_BITS - 6))}; +} + + +static inline SwPoint TRUNC(const SwPoint& pt) +{ + return {pt.x >> PIXEL_BITS, pt.y >> PIXEL_BITS}; +} + + +static inline SwCoord TRUNC(const SwCoord x) +{ + return x >> PIXEL_BITS; +} + + +static inline SwPoint SUBPIXELS(const SwPoint& pt) +{ + return {SwCoord(((unsigned long) pt.x) << PIXEL_BITS), SwCoord(((unsigned long) pt.y) << PIXEL_BITS)}; +} + + +static inline SwCoord SUBPIXELS(const SwCoord x) +{ + return SwCoord(((unsigned long) x) << PIXEL_BITS); +} + +/* + * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min' + * algorithm. We use alpha = 1, beta = 3/8, giving us results with a + * largest error less than 7% compared to the exact value. + */ +static inline SwCoord HYPOT(SwPoint pt) +{ + if (pt.x < 0) pt.x = -pt.x; + if (pt.y < 0) pt.y = -pt.y; + return ((pt.x > pt.y) ? (pt.x + (3 * pt.y >> 3)) : (pt.y + (3 * pt.x >> 3))); +} + +static void _genSpan(SwRleData* rle, const SwSpan* spans, uint32_t count) +{ + auto newSize = rle->size + count; + + /* allocate enough memory for new spans */ + /* alloc is required to prevent free and reallocation */ + /* when the rle needs to be regenerated because of attribute change. */ + if (rle->alloc < newSize) { + rle->alloc = (newSize * 2); + //OPTIMIZE: use mempool! + rle->spans = static_cast<SwSpan*>(realloc(rle->spans, rle->alloc * sizeof(SwSpan))); + } + + //copy the new spans to the allocated memory + SwSpan* lastSpan = rle->spans + rle->size; + memcpy(lastSpan, spans, count * sizeof(SwSpan)); + + rle->size = newSize; +} + + +static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoord acount) +{ + x += rw.cellMin.x; + y += rw.cellMin.y; + + //Clip Y range + if (y < rw.cellMin.y || y >= rw.cellMax.y) return; + + /* compute the coverage line's coverage, depending on the outline fill rule */ + /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */ + auto coverage = static_cast<int>(area >> (PIXEL_BITS * 2 + 1 - 8)); //range 0 - 255 + + if (coverage < 0) coverage = -coverage; + + if (rw.outline->fillRule == FillRule::EvenOdd) { + coverage &= 511; + if (coverage > 255) coverage = 511 - coverage; + } else { + //normal non-zero winding rule + if (coverage > 255) coverage = 255; + } + + //span has ushort coordinates. check limit overflow + if (x >= SHRT_MAX) { + TVGERR("SW_ENGINE", "X-coordiante overflow!"); + x = SHRT_MAX; + } + if (y >= SHRT_MAX) { + TVGERR("SW_ENGINE", "Y Coordiante overflow!"); + y = SHRT_MAX; + } + + if (coverage > 0) { + if (!rw.antiAlias) coverage = 255; + auto count = rw.spansCnt; + auto span = rw.spans + count - 1; + + //see whether we can add this span to the current list + if ((count > 0) && (rw.ySpan == y) && + (span->x + span->len == x) && (span->coverage == coverage)) { + + //Clip x range + SwCoord xOver = 0; + if (x + acount >= rw.cellMax.x) xOver -= (x + acount - rw.cellMax.x); + if (x < rw.cellMin.x) xOver -= (rw.cellMin.x - x); + + //span->len += (acount + xOver) - 1; + span->len += (acount + xOver); + return; + } + + if (count >= MAX_SPANS) { + _genSpan(rw.rle, rw.spans, count); + rw.spansCnt = 0; + rw.ySpan = 0; + span = rw.spans; + } else { + ++span; + } + + //Clip x range + SwCoord xOver = 0; + if (x + acount >= rw.cellMax.x) xOver -= (x + acount - rw.cellMax.x); + if (x < rw.cellMin.x) { + xOver -= (rw.cellMin.x - x); + x = rw.cellMin.x; + } + + //Nothing to draw + if (acount + xOver <= 0) return; + + //add a span to the current list + span->x = x; + span->y = y; + span->len = (acount + xOver); + span->coverage = coverage; + ++rw.spansCnt; + rw.ySpan = y; + } +} + + +static void _sweep(RleWorker& rw) +{ + if (rw.cellsCnt == 0) return; + + rw.spansCnt = 0; + rw.ySpan = 0; + + for (int y = 0; y < rw.yCnt; ++y) { + auto cover = 0; + auto x = 0; + auto cell = rw.yCells[y]; + + while (cell) { + if (cell->x > x && cover != 0) _horizLine(rw, x, y, cover * (ONE_PIXEL * 2), cell->x - x); + cover += cell->cover; + auto area = cover * (ONE_PIXEL * 2) - cell->area; + if (area != 0 && cell->x >= 0) _horizLine(rw, cell->x, y, area, 1); + x = cell->x + 1; + cell = cell->next; + } + + if (cover != 0) _horizLine(rw, x, y, cover * (ONE_PIXEL * 2), rw.cellXCnt - x); + } + + if (rw.spansCnt > 0) _genSpan(rw.rle, rw.spans, rw.spansCnt); +} + + +static Cell* _findCell(RleWorker& rw) +{ + auto x = rw.cellPos.x; + if (x > rw.cellXCnt) x = rw.cellXCnt; + + auto pcell = &rw.yCells[rw.cellPos.y]; + + while(true) { + Cell* cell = *pcell; + if (!cell || cell->x > x) break; + if (cell->x == x) return cell; + pcell = &cell->next; + } + + if (rw.cellsCnt >= rw.maxCells) longjmp(rw.jmpBuf, 1); + + auto cell = rw.cells + rw.cellsCnt++; + cell->x = x; + cell->area = 0; + cell->cover = 0; + cell->next = *pcell; + *pcell = cell; + + return cell; +} + + +static void _recordCell(RleWorker& rw) +{ + if (rw.area | rw.cover) { + auto cell = _findCell(rw); + cell->area += rw.area; + cell->cover += rw.cover; + } +} + + +static void _setCell(RleWorker& rw, SwPoint pos) +{ + /* Move the cell pointer to a new position. We set the `invalid' */ + /* flag to indicate that the cell isn't part of those we're interested */ + /* in during the render phase. This means that: */ + /* */ + /* . the new vertical position must be within min_ey..max_ey-1. */ + /* . the new horizontal position must be strictly less than max_ex */ + /* */ + /* Note that if a cell is to the left of the clipping region, it is */ + /* actually set to the (min_ex-1) horizontal position. */ + + /* All cells that are on the left of the clipping region go to the + min_ex - 1 horizontal position. */ + pos.x -= rw.cellMin.x; + pos.y -= rw.cellMin.y; + + if (pos.x > rw.cellMax.x) pos.x = rw.cellMax.x; + + //Are we moving to a different cell? + if (pos != rw.cellPos) { + //Record the current one if it is valid + if (!rw.invalid) _recordCell(rw); + } + + rw.area = 0; + rw.cover = 0; + rw.cellPos = pos; + rw.invalid = ((unsigned)pos.y >= (unsigned)rw.cellYCnt || pos.x >= rw.cellXCnt); +} + + +static void _startCell(RleWorker& rw, SwPoint pos) +{ + if (pos.x > rw.cellMax.x) pos.x = rw.cellMax.x; + if (pos.x < rw.cellMin.x) pos.x = rw.cellMin.x; + + rw.area = 0; + rw.cover = 0; + rw.cellPos = pos - rw.cellMin; + rw.invalid = false; + + _setCell(rw, pos); +} + + +static void _moveTo(RleWorker& rw, const SwPoint& to) +{ + //record current cell, if any */ + if (!rw.invalid) _recordCell(rw); + + //start to a new position + _startCell(rw, TRUNC(to)); + + rw.pos = to; +} + + +static void _lineTo(RleWorker& rw, const SwPoint& to) +{ +#define SW_UDIV(a, b) \ + static_cast<SwCoord>(((unsigned long)(a) * (unsigned long)(b)) >> \ + (sizeof(long) * CHAR_BIT - PIXEL_BITS)) + + auto e1 = TRUNC(rw.pos); + auto e2 = TRUNC(to); + + //vertical clipping + if ((e1.y >= rw.cellMax.y && e2.y >= rw.cellMax.y) || (e1.y < rw.cellMin.y && e2.y < rw.cellMin.y)) { + rw.pos = to; + return; + } + + auto diff = to - rw.pos; + auto f1 = rw.pos - SUBPIXELS(e1); + SwPoint f2; + + //inside one cell + if (e1 == e2) { + ; + //any horizontal line + } else if (diff.y == 0) { + e1.x = e2.x; + _setCell(rw, e1); + } else if (diff.x == 0) { + //vertical line up + if (diff.y > 0) { + do { + f2.y = ONE_PIXEL; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * f1.x * 2; + f1.y = 0; + ++e1.y; + _setCell(rw, e1); + } while(e1.y != e2.y); + //vertical line down + } else { + do { + f2.y = 0; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * f1.x * 2; + f1.y = ONE_PIXEL; + --e1.y; + _setCell(rw, e1); + } while(e1.y != e2.y); + } + //any other line + } else { + Area prod = diff.x * f1.y - diff.y * f1.x; + + /* These macros speed up repetitive divisions by replacing them + with multiplications and right shifts. */ + auto dx_r = static_cast<long>(ULONG_MAX >> PIXEL_BITS) / (diff.x); + auto dy_r = static_cast<long>(ULONG_MAX >> PIXEL_BITS) / (diff.y); + + /* The fundamental value `prod' determines which side and the */ + /* exact coordinate where the line exits current cell. It is */ + /* also easily updated when moving from one cell to the next. */ + do { + auto px = diff.x * ONE_PIXEL; + auto py = diff.y * ONE_PIXEL; + + //left + if (prod <= 0 && prod - px > 0) { + f2 = {0, SW_UDIV(-prod, -dx_r)}; + prod -= py; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * (f1.x + f2.x); + f1 = {ONE_PIXEL, f2.y}; + --e1.x; + //up + } else if (prod - px <= 0 && prod - px + py > 0) { + prod -= px; + f2 = {SW_UDIV(-prod, dy_r), ONE_PIXEL}; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * (f1.x + f2.x); + f1 = {f2.x, 0}; + ++e1.y; + //right + } else if (prod - px + py <= 0 && prod + py >= 0) { + prod += py; + f2 = {ONE_PIXEL, SW_UDIV(prod, dx_r)}; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * (f1.x + f2.x); + f1 = {0, f2.y}; + ++e1.x; + //down + } else { + f2 = {SW_UDIV(prod, -dy_r), 0}; + prod += px; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * (f1.x + f2.x); + f1 = {f2.x, ONE_PIXEL}; + --e1.y; + } + + _setCell(rw, e1); + + } while(e1 != e2); + } + + f2 = {to.x - SUBPIXELS(e2.x), to.y - SUBPIXELS(e2.y)}; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * (f1.x + f2.x); + rw.pos = to; +} + + +static void _cubicTo(RleWorker& rw, const SwPoint& ctrl1, const SwPoint& ctrl2, const SwPoint& to) +{ + auto arc = rw.bezStack; + arc[0] = to; + arc[1] = ctrl2; + arc[2] = ctrl1; + arc[3] = rw.pos; + + //Short-cut the arc that crosses the current band + auto min = arc[0].y; + auto max = arc[0].y; + + SwCoord y; + for (auto i = 1; i < 4; ++i) { + y = arc[i].y; + if (y < min) min = y; + if (y > max) max = y; + } + + if (TRUNC(min) >= rw.cellMax.y || TRUNC(max) < rw.cellMin.y) goto draw; + + /* Decide whether to split or draw. See `Rapid Termination */ + /* Evaluation for Recursive Subdivision of Bezier Curves' by Thomas */ + /* F. Hain, at */ + /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */ + while (true) { + { + //diff is the P0 - P3 chord vector + auto diff = arc[3] - arc[0]; + auto L = HYPOT(diff); + + //avoid possible arithmetic overflow below by splitting + if (L > SHRT_MAX) goto split; + + //max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1) + auto sLimit = L * (ONE_PIXEL / 6); + + auto diff1 = arc[1] - arc[0]; + auto s = diff.y * diff1.x - diff.x * diff1.y; + if (s < 0) s = -s; + if (s > sLimit) goto split; + + //s is L * the perpendicular distance from P2 to the line P0 - P3 + auto diff2 = arc[2] - arc[0]; + s = diff.y * diff2.x - diff.x * diff2.y; + if (s < 0) s = -s; + if (s > sLimit) goto split; + + /* Split super curvy segments where the off points are so far + from the chord that the angles P0-P1-P3 or P0-P2-P3 become + acute as detected by appropriate dot products */ + if (diff1.x * (diff1.x - diff.x) + diff1.y * (diff1.y - diff.y) > 0 || + diff2.x * (diff2.x - diff.x) + diff2.y * (diff2.y - diff.y) > 0) + goto split; + + //no reason to split + goto draw; + } + split: + mathSplitCubic(arc); + arc += 3; + continue; + + draw: + _lineTo(rw, arc[0]); + if (arc == rw.bezStack) return; + arc -= 3; + } +} + + +static bool _decomposeOutline(RleWorker& rw) +{ + auto outline = rw.outline; + auto first = 0; //index of first point in contour + + for (uint32_t n = 0; n < outline->cntrsCnt; ++n) { + auto last = outline->cntrs[n]; + auto limit = outline->pts + last; + auto start = UPSCALE(outline->pts[first]); + auto pt = outline->pts + first; + auto types = outline->types + first; + + /* A contour cannot start with a cubic control point! */ + if (types[0] == SW_CURVE_TYPE_CUBIC) goto invalid_outline; + + _moveTo(rw, UPSCALE(outline->pts[first])); + + while (pt < limit) { + ++pt; + ++types; + + //emit a single line_to + if (types[0] == SW_CURVE_TYPE_POINT) { + _lineTo(rw, UPSCALE(*pt)); + //types cubic + } else { + if (pt + 1 > limit || types[1] != SW_CURVE_TYPE_CUBIC) + goto invalid_outline; + + pt += 2; + types += 2; + + if (pt <= limit) { + _cubicTo(rw, UPSCALE(pt[-2]), UPSCALE(pt[-1]), UPSCALE(pt[0])); + continue; + } + _cubicTo(rw, UPSCALE(pt[-2]), UPSCALE(pt[-1]), start); + goto close; + } + } + _lineTo(rw, start); + close: + first = last + 1; + } + + return true; + +invalid_outline: + TVGERR("SW_ENGINE", "Invalid Outline!"); + return false; +} + + +static int _genRle(RleWorker& rw) +{ + if (setjmp(rw.jmpBuf) == 0) { + auto ret = _decomposeOutline(rw); + if (!rw.invalid) _recordCell(rw); + if (ret) return 0; //success + else return 1; //fail + } + return -1; //lack of cell memory +} + + +SwSpan* _intersectSpansRegion(const SwRleData *clip, const SwRleData *targetRle, SwSpan *outSpans, uint32_t spanCnt) +{ + auto out = outSpans; + auto spans = targetRle->spans; + auto end = targetRle->spans + targetRle->size; + auto clipSpans = clip->spans; + auto clipEnd = clip->spans + clip->size; + + while (spanCnt > 0 && spans < end) { + if (clipSpans == clipEnd) { + spans = end; + break; + } + if (clipSpans->y > spans->y) { + ++spans; + continue; + } + if (spans->y != clipSpans->y) { + ++clipSpans; + continue; + } + auto sx1 = spans->x; + auto sx2 = sx1 + spans->len; + auto cx1 = clipSpans->x; + auto cx2 = cx1 + clipSpans->len; + + if (cx1 < sx1 && cx2 < sx1) { + ++clipSpans; + continue; + } + else if (sx1 < cx1 && sx2 < cx1) { + ++spans; + continue; + } + auto x = sx1 > cx1 ? sx1 : cx1; + auto len = (sx2 < cx2 ? sx2 : cx2) - x; + if (len) { + auto spansCorverage = spans->coverage; + auto clipSpansCoverage = clipSpans->coverage; + out->x = sx1 > cx1 ? sx1 : cx1; + out->len = (sx2 < cx2 ? sx2 : cx2) - out->x; + out->y = spans->y; + out->coverage = (uint8_t)(((spansCorverage * clipSpansCoverage) + 0xff) >> 8); + ++out; + --spanCnt; + } + if (sx2 < cx2) ++spans; + else ++clipSpans; + } + return out; +} + + +SwSpan* _intersectSpansRect(const SwBBox *bbox, const SwRleData *targetRle, SwSpan *outSpans, uint32_t spanCnt) +{ + auto out = outSpans; + auto spans = targetRle->spans; + auto end = targetRle->spans + targetRle->size; + auto minx = static_cast<int16_t>(bbox->min.x); + auto miny = static_cast<int16_t>(bbox->min.y); + auto maxx = minx + static_cast<int16_t>(bbox->max.x - bbox->min.x) - 1; + auto maxy = miny + static_cast<int16_t>(bbox->max.y - bbox->min.y) - 1; + + while (spanCnt && spans < end) { + if (spans->y > maxy) { + spans = end; + break; + } + if (spans->y < miny || spans->x > maxx || spans->x + spans->len <= minx) { + ++spans; + continue; + } + if (spans->x < minx) { + out->len = (spans->len - (minx - spans->x)) < (maxx - minx + 1) ? (spans->len - (minx - spans->x)) : (maxx - minx + 1); + out->x = minx; + } + else { + out->x = spans->x; + out->len = spans->len < (maxx - spans->x + 1) ? spans->len : (maxx - spans->x + 1); + } + if (out->len != 0) { + out->y = spans->y; + out->coverage = spans->coverage; + ++out; + } + ++spans; + --spanCnt; + } + return out; +} + + +void _replaceClipSpan(SwRleData *rle, SwSpan* clippedSpans, uint32_t size) +{ + free(rle->spans); + rle->spans = clippedSpans; + rle->size = rle->alloc = size; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& renderRegion, bool antiAlias) +{ + constexpr auto RENDER_POOL_SIZE = 16384L; + constexpr auto BAND_SIZE = 40; + + //TODO: We can preserve several static workers in advance + RleWorker rw; + Cell buffer[RENDER_POOL_SIZE / sizeof(Cell)]; + + //Init Cells + rw.buffer = buffer; + rw.bufferSize = sizeof(buffer); + rw.yCells = reinterpret_cast<Cell**>(buffer); + rw.cells = nullptr; + rw.maxCells = 0; + rw.cellsCnt = 0; + rw.area = 0; + rw.cover = 0; + rw.invalid = true; + rw.cellMin = renderRegion.min; + rw.cellMax = renderRegion.max; + rw.cellXCnt = rw.cellMax.x - rw.cellMin.x; + rw.cellYCnt = rw.cellMax.y - rw.cellMin.y; + rw.ySpan = 0; + rw.outline = const_cast<SwOutline*>(outline); + rw.bandSize = rw.bufferSize / (sizeof(Cell) * 8); //bandSize: 64 + rw.bandShoot = 0; + rw.antiAlias = antiAlias; + + if (!rle) rw.rle = reinterpret_cast<SwRleData*>(calloc(1, sizeof(SwRleData))); + else rw.rle = rle; + + //Generate RLE + Band bands[BAND_SIZE]; + Band* band; + + /* set up vertical bands */ + auto bandCnt = static_cast<int>((rw.cellMax.y - rw.cellMin.y) / rw.bandSize); + if (bandCnt == 0) bandCnt = 1; + else if (bandCnt >= BAND_SIZE) bandCnt = (BAND_SIZE - 1); + + auto min = rw.cellMin.y; + auto yMax = rw.cellMax.y; + SwCoord max; + int ret; + + for (int n = 0; n < bandCnt; ++n, min = max) { + max = min + rw.bandSize; + if (n == bandCnt -1 || max > yMax) max = yMax; + + bands[0].min = min; + bands[0].max = max; + band = bands; + + while (band >= bands) { + rw.yCells = static_cast<Cell**>(rw.buffer); + rw.yCnt = band->max - band->min; + + int cellStart = sizeof(Cell*) * (int)rw.yCnt; + int cellMod = cellStart % sizeof(Cell); + + if (cellMod > 0) cellStart += sizeof(Cell) - cellMod; + + auto cellEnd = rw.bufferSize; + cellEnd -= cellEnd % sizeof(Cell); + + auto cellsMax = reinterpret_cast<Cell*>((char*)rw.buffer + cellEnd); + rw.cells = reinterpret_cast<Cell*>((char*)rw.buffer + cellStart); + + if (rw.cells >= cellsMax) goto reduce_bands; + + rw.maxCells = cellsMax - rw.cells; + if (rw.maxCells < 2) goto reduce_bands; + + for (int y = 0; y < rw.yCnt; ++y) + rw.yCells[y] = nullptr; + + rw.cellsCnt = 0; + rw.invalid = true; + rw.cellMin.y = band->min; + rw.cellMax.y = band->max; + rw.cellYCnt = band->max - band->min; + + ret = _genRle(rw); + if (ret == 0) { + _sweep(rw); + --band; + continue; + } else if (ret == 1) { + goto error; + } + + reduce_bands: + /* render pool overflow: we will reduce the render band by half */ + auto bottom = band->min; + auto top = band->max; + auto middle = bottom + ((top - bottom) >> 1); + + /* This is too complex for a single scanline; there must + be some problems */ + if (middle == bottom) goto error; + + if (bottom - top >= rw.bandSize) ++rw.bandShoot; + + band[1].min = bottom; + band[1].max = middle; + band[0].min = middle; + band[0].max = top; + ++band; + } + } + + if (rw.bandShoot > 8 && rw.bandSize > 16) + rw.bandSize = (rw.bandSize >> 1); + + return rw.rle; + +error: + free(rw.rle); + rw.rle = nullptr; + return nullptr; +} + + +void rleReset(SwRleData* rle) +{ + if (!rle) return; + rle->size = 0; +} + + +void rleFree(SwRleData* rle) +{ + if (!rle) return; + if (rle->spans) free(rle->spans); + free(rle); +} + + +void rleClipPath(SwRleData *rle, const SwRleData *clip) +{ + if (rle->size == 0 || clip->size == 0) return; + auto spanCnt = rle->size > clip->size ? rle->size : clip->size; + auto spans = static_cast<SwSpan*>(malloc(sizeof(SwSpan) * (spanCnt))); + if (!spans) return; + auto spansEnd = _intersectSpansRegion(clip, rle, spans, spanCnt); + + _replaceClipSpan(rle, spans, spansEnd - spans); + + TVGLOG("SW_ENGINE", "Using ClipPath!"); +} + + +void rleClipRect(SwRleData *rle, const SwBBox* clip) +{ + if (rle->size == 0) return; + auto spans = static_cast<SwSpan*>(malloc(sizeof(SwSpan) * (rle->size))); + if (!spans) return; + auto spansEnd = _intersectSpansRect(clip, rle, spans, rle->size); + + _replaceClipSpan(rle, spans, spansEnd - spans); + + TVGLOG("SW_ENGINE", "Using ClipRect!"); +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwShape.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwShape.cpp new file mode 100644 index 0000000000..7b49c232b1 --- /dev/null +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwShape.cpp @@ -0,0 +1,664 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "tvgSwCommon.h" +#include "tvgBezier.h" +#include <float.h> +#include <math.h> + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct Line +{ + Point pt1; + Point pt2; +}; + + +static float _lineLength(const Point& pt1, const Point& pt2) +{ + /* approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm. + With alpha = 1, beta = 3/8, giving results with the largest error less + than 7% compared to the exact value. */ + Point diff = {pt2.x - pt1.x, pt2.y - pt1.y}; + if (diff.x < 0) diff.x = -diff.x; + if (diff.y < 0) diff.y = -diff.y; + return (diff.x > diff.y) ? (diff.x + diff.y * 0.375f) : (diff.y + diff.x * 0.375f); +} + + +static void _lineSplitAt(const Line& cur, float at, Line& left, Line& right) +{ + auto len = _lineLength(cur.pt1, cur.pt2); + auto dx = ((cur.pt2.x - cur.pt1.x) / len) * at; + auto dy = ((cur.pt2.y - cur.pt1.y) / len) * at; + left.pt1 = cur.pt1; + left.pt2.x = left.pt1.x + dx; + left.pt2.y = left.pt1.y + dy; + right.pt1 = left.pt2; + right.pt2 = cur.pt2; +} + + +static bool _growOutlineContour(SwOutline& outline, uint32_t n) +{ + if (outline.reservedCntrsCnt >= outline.cntrsCnt + n) return false; + outline.reservedCntrsCnt = outline.cntrsCnt + n; + outline.cntrs = static_cast<uint16_t*>(realloc(outline.cntrs, outline.reservedCntrsCnt * sizeof(uint16_t))); + return true; +} + + +static void _reserveOutlineClose(SwOutline& outline) +{ + //Dash outlines are always opened. + //Only normal outlines use this information, it sholud be same to their contour counts. + if (outline.closed) free(outline.closed); + outline.closed = static_cast<bool*>(calloc(outline.reservedCntrsCnt, sizeof(bool))); +} + + +static void _resetOutlineClose(SwOutline& outline) +{ + memset(outline.closed, 0x0, outline.reservedCntrsCnt * sizeof(bool)); +} + + +static void _growOutlinePoint(SwOutline& outline, uint32_t n) +{ + if (outline.reservedPtsCnt >= outline.ptsCnt + n) return; + outline.reservedPtsCnt = outline.ptsCnt + n; + outline.pts = static_cast<SwPoint*>(realloc(outline.pts, outline.reservedPtsCnt * sizeof(SwPoint))); + outline.types = static_cast<uint8_t*>(realloc(outline.types, outline.reservedPtsCnt * sizeof(uint8_t))); +} + + +static void _outlineEnd(SwOutline& outline) +{ + if (outline.ptsCnt == 0) return; + + _growOutlineContour(outline, 1); + outline.cntrs[outline.cntrsCnt] = outline.ptsCnt - 1; + ++outline.cntrsCnt; +} + + +static void _outlineMoveTo(SwOutline& outline, const Point* to, const Matrix* transform) +{ + _growOutlinePoint(outline, 1); + + outline.pts[outline.ptsCnt] = mathTransform(to, transform); + outline.types[outline.ptsCnt] = SW_CURVE_TYPE_POINT; + + if (outline.ptsCnt > 0) { + _growOutlineContour(outline, 1); + outline.cntrs[outline.cntrsCnt] = outline.ptsCnt - 1; + ++outline.cntrsCnt; + } + + ++outline.ptsCnt; +} + + +static void _outlineLineTo(SwOutline& outline, const Point* to, const Matrix* transform) +{ + _growOutlinePoint(outline, 1); + + outline.pts[outline.ptsCnt] = mathTransform(to, transform); + outline.types[outline.ptsCnt] = SW_CURVE_TYPE_POINT; + ++outline.ptsCnt; +} + + +static void _outlineCubicTo(SwOutline& outline, const Point* ctrl1, const Point* ctrl2, const Point* to, const Matrix* transform) +{ + _growOutlinePoint(outline, 3); + + outline.pts[outline.ptsCnt] = mathTransform(ctrl1, transform); + outline.types[outline.ptsCnt] = SW_CURVE_TYPE_CUBIC; + ++outline.ptsCnt; + + outline.pts[outline.ptsCnt] = mathTransform(ctrl2, transform); + outline.types[outline.ptsCnt] = SW_CURVE_TYPE_CUBIC; + ++outline.ptsCnt; + + outline.pts[outline.ptsCnt] = mathTransform(to, transform); + outline.types[outline.ptsCnt] = SW_CURVE_TYPE_POINT; + ++outline.ptsCnt; +} + + +static void _outlineClose(SwOutline& outline) +{ + uint32_t i = 0; + + if (outline.cntrsCnt > 0) { + i = outline.cntrs[outline.cntrsCnt - 1] + 1; + } else { + i = 0; //First Path + } + + //Make sure there is at least one point in the current path + if (outline.ptsCnt == i) return; + + //Close the path + _growOutlinePoint(outline, 1); + + outline.pts[outline.ptsCnt] = outline.pts[i]; + outline.types[outline.ptsCnt] = SW_CURVE_TYPE_POINT; + ++outline.ptsCnt; + outline.closed[outline.cntrsCnt] = true; +} + + +static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* transform) +{ + _growOutlinePoint(*dash.outline, dash.outline->ptsCnt >> 1); + _growOutlineContour(*dash.outline, dash.outline->cntrsCnt >> 1); + + Line cur = {dash.ptCur, *to}; + auto len = _lineLength(cur.pt1, cur.pt2); + + if (len < dash.curLen) { + dash.curLen -= len; + if (!dash.curOpGap) { + _outlineMoveTo(*dash.outline, &dash.ptCur, transform); + _outlineLineTo(*dash.outline, to, transform); + } + } else { + while (len > dash.curLen) { + len -= dash.curLen; + Line left, right; + _lineSplitAt(cur, dash.curLen, left, right);; + dash.curIdx = (dash.curIdx + 1) % dash.cnt; + if (!dash.curOpGap) { + _outlineMoveTo(*dash.outline, &left.pt1, transform); + _outlineLineTo(*dash.outline, &left.pt2, transform); + } + dash.curLen = dash.pattern[dash.curIdx]; + dash.curOpGap = !dash.curOpGap; + cur = right; + dash.ptCur = cur.pt1; + } + //leftovers + dash.curLen -= len; + if (!dash.curOpGap) { + _outlineMoveTo(*dash.outline, &cur.pt1, transform); + _outlineLineTo(*dash.outline, &cur.pt2, transform); + } + if (dash.curLen < 1 && TO_SWCOORD(len) > 1) { + //move to next dash + dash.curIdx = (dash.curIdx + 1) % dash.cnt; + dash.curLen = dash.pattern[dash.curIdx]; + dash.curOpGap = !dash.curOpGap; + } + } + dash.ptCur = *to; +} + + +static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ctrl2, const Point* to, const Matrix* transform) +{ + _growOutlinePoint(*dash.outline, dash.outline->ptsCnt >> 1); + _growOutlineContour(*dash.outline, dash.outline->cntrsCnt >> 1); + + Bezier cur = {dash.ptCur, *ctrl1, *ctrl2, *to}; + auto len = bezLength(cur); + + if (len < dash.curLen) { + dash.curLen -= len; + if (!dash.curOpGap) { + _outlineMoveTo(*dash.outline, &dash.ptCur, transform); + _outlineCubicTo(*dash.outline, ctrl1, ctrl2, to, transform); + } + } else { + while (len > dash.curLen) { + Bezier left, right; + len -= dash.curLen; + bezSplitAt(cur, dash.curLen, left, right); + if (!dash.curOpGap) { + // leftovers from a previous command don't require moveTo + if (dash.pattern[dash.curIdx] - dash.curLen < FLT_EPSILON) { + _outlineMoveTo(*dash.outline, &left.start, transform); + } + _outlineCubicTo(*dash.outline, &left.ctrl1, &left.ctrl2, &left.end, transform); + } + dash.curIdx = (dash.curIdx + 1) % dash.cnt; + dash.curLen = dash.pattern[dash.curIdx]; + dash.curOpGap = !dash.curOpGap; + cur = right; + dash.ptCur = right.start; + } + //leftovers + dash.curLen -= len; + if (!dash.curOpGap) { + _outlineMoveTo(*dash.outline, &cur.start, transform); + _outlineCubicTo(*dash.outline, &cur.ctrl1, &cur.ctrl2, &cur.end, transform); + } + if (dash.curLen < 1 && TO_SWCOORD(len) > 1) { + //move to next dash + dash.curIdx = (dash.curIdx + 1) % dash.cnt; + dash.curLen = dash.pattern[dash.curIdx]; + dash.curOpGap = !dash.curOpGap; + } + } + dash.ptCur = *to; +} + + +static SwOutline* _genDashOutline(const Shape* sdata, const Matrix* transform) +{ + const PathCommand* cmds = nullptr; + auto cmdCnt = sdata->pathCommands(&cmds); + + const Point* pts = nullptr; + auto ptsCnt = sdata->pathCoords(&pts); + + //No actual shape data + if (cmdCnt == 0 || ptsCnt == 0) return nullptr; + + SwDashStroke dash; + dash.curIdx = 0; + dash.curLen = 0; + dash.ptStart = {0, 0}; + dash.ptCur = {0, 0}; + dash.curOpGap = false; + + const float* pattern; + dash.cnt = sdata->strokeDash(&pattern); + if (dash.cnt == 0) return nullptr; + + //OPTMIZE ME: Use mempool??? + dash.pattern = const_cast<float*>(pattern); + dash.outline = static_cast<SwOutline*>(calloc(1, sizeof(SwOutline))); + + //smart reservation + auto outlinePtsCnt = 0; + auto outlineCntrsCnt = 0; + + for (uint32_t i = 0; i < cmdCnt; ++i) { + switch (*(cmds + i)) { + case PathCommand::Close: { + ++outlinePtsCnt; + break; + } + case PathCommand::MoveTo: { + ++outlineCntrsCnt; + ++outlinePtsCnt; + break; + } + case PathCommand::LineTo: { + ++outlinePtsCnt; + break; + } + case PathCommand::CubicTo: { + outlinePtsCnt += 3; + break; + } + } + } + + ++outlinePtsCnt; //for close + ++outlineCntrsCnt; //for end + + //No idea exact count.... Reserve Approximitely 20x... + _growOutlinePoint(*dash.outline, outlinePtsCnt * 20); + _growOutlineContour(*dash.outline, outlineCntrsCnt * 20); + + while (cmdCnt-- > 0) { + switch (*cmds) { + case PathCommand::Close: { + _dashLineTo(dash, &dash.ptStart, transform); + break; + } + case PathCommand::MoveTo: { + //reset the dash + dash.curIdx = 0; + dash.curLen = *dash.pattern; + dash.curOpGap = false; + dash.ptStart = dash.ptCur = *pts; + ++pts; + break; + } + case PathCommand::LineTo: { + _dashLineTo(dash, pts, transform); + ++pts; + break; + } + case PathCommand::CubicTo: { + _dashCubicTo(dash, pts, pts + 1, pts + 2, transform); + pts += 3; + break; + } + } + ++cmds; + } + + _outlineEnd(*dash.outline); + + return dash.outline; +} + + +static bool _axisAlignedRect(const SwOutline* outline) +{ + //Fast Track: axis-aligned rectangle? + if (outline->ptsCnt != 5) return false; + + auto pt1 = outline->pts + 0; + auto pt2 = outline->pts + 1; + auto pt3 = outline->pts + 2; + auto pt4 = outline->pts + 3; + + auto a = SwPoint{pt1->x, pt3->y}; + auto b = SwPoint{pt3->x, pt1->y}; + + if ((*pt2 == a && *pt4 == b) || (*pt2 == b && *pt4 == a)) return true; + + return false; +} + + + +static bool _genOutline(SwShape* shape, const Shape* sdata, const Matrix* transform, SwMpool* mpool, unsigned tid, bool hasComposite) +{ + const PathCommand* cmds = nullptr; + auto cmdCnt = sdata->pathCommands(&cmds); + + const Point* pts = nullptr; + auto ptsCnt = sdata->pathCoords(&pts); + + //No actual shape data + if (cmdCnt == 0 || ptsCnt == 0) return false; + + //smart reservation + auto outlinePtsCnt = 0; + auto outlineCntrsCnt = 0; + auto closeCnt = 0; + + for (uint32_t i = 0; i < cmdCnt; ++i) { + switch (*(cmds + i)) { + case PathCommand::Close: { + ++outlinePtsCnt; + ++closeCnt; + break; + } + case PathCommand::MoveTo: { + ++outlineCntrsCnt; + ++outlinePtsCnt; + break; + } + case PathCommand::LineTo: { + ++outlinePtsCnt; + break; + } + case PathCommand::CubicTo: { + outlinePtsCnt += 3; + break; + } + } + } + + if (static_cast<uint32_t>(outlinePtsCnt - closeCnt) > ptsCnt) { + TVGERR("SW_ENGINE", "Wrong a pair of the commands & points - required(%d), current(%d)", outlinePtsCnt - closeCnt, ptsCnt); + return false; + } + + ++outlinePtsCnt; //for close + ++outlineCntrsCnt; //for end + + shape->outline = mpoolReqOutline(mpool, tid); + auto outline = shape->outline; + + _growOutlinePoint(*outline, outlinePtsCnt); + + if (_growOutlineContour(*outline, outlineCntrsCnt)) { + _reserveOutlineClose(*outline); + } else { + _resetOutlineClose(*outline); + } + + //Generate Outlines + while (cmdCnt-- > 0) { + switch (*cmds) { + case PathCommand::Close: { + _outlineClose(*outline); + break; + } + case PathCommand::MoveTo: { + _outlineMoveTo(*outline, pts, transform); + ++pts; + break; + } + case PathCommand::LineTo: { + _outlineLineTo(*outline, pts, transform); + ++pts; + break; + } + case PathCommand::CubicTo: { + _outlineCubicTo(*outline, pts, pts + 1, pts + 2, transform); + pts += 3; + break; + } + } + ++cmds; + } + + _outlineEnd(*outline); + + outline->fillRule = sdata->fillRule(); + shape->outline = outline; + + shape->fastTrack = (!hasComposite && _axisAlignedRect(shape->outline)); + return true; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +bool shapePrepare(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite) +{ + if (!_genOutline(shape, sdata, transform, mpool, tid, hasComposite)) return false; + if (!mathUpdateOutlineBBox(shape->outline, clipRegion, renderRegion, shape->fastTrack)) return false; + + //Keep it for Rasterization Region + shape->bbox = renderRegion; + + //Check valid region + if (renderRegion.max.x - renderRegion.min.x < 1 && renderRegion.max.y - renderRegion.min.y < 1) return false; + + //Check boundary + if (renderRegion.min.x >= clipRegion.max.x || renderRegion.min.y >= clipRegion.max.y || + renderRegion.max.x <= clipRegion.min.x || renderRegion.max.y <= clipRegion.min.y) return false; + + return true; +} + + +bool shapePrepared(const SwShape* shape) +{ + return shape->rle ? true : false; +} + + +bool shapeGenRle(SwShape* shape, TVG_UNUSED const Shape* sdata, bool antiAlias) +{ + //FIXME: Should we draw it? + //Case: Stroke Line + //if (shape.outline->opened) return true; + + //Case A: Fast Track Rectangle Drawing + if (shape->fastTrack) return true; + + //Case B: Normal Shape RLE Drawing + if ((shape->rle = rleRender(shape->rle, shape->outline, shape->bbox, antiAlias))) return true; + + return false; +} + + +void shapeDelOutline(SwShape* shape, SwMpool* mpool, uint32_t tid) +{ + mpoolRetOutline(mpool, tid); + shape->outline = nullptr; +} + + +void shapeReset(SwShape* shape) +{ + rleReset(shape->rle); + rleReset(shape->strokeRle); + shape->fastTrack = false; + shape->bbox.reset(); +} + + +void shapeFree(SwShape* shape) +{ + rleFree(shape->rle); + shapeDelFill(shape); + + if (shape->stroke) { + rleFree(shape->strokeRle); + strokeFree(shape->stroke); + } +} + + +void shapeDelStroke(SwShape* shape) +{ + if (!shape->stroke) return; + rleFree(shape->strokeRle); + shape->strokeRle = nullptr; + strokeFree(shape->stroke); + shape->stroke = nullptr; +} + + +void shapeResetStroke(SwShape* shape, const Shape* sdata, const Matrix* transform) +{ + if (!shape->stroke) shape->stroke = static_cast<SwStroke*>(calloc(1, sizeof(SwStroke))); + auto stroke = shape->stroke; + if (!stroke) return; + + strokeReset(stroke, sdata, transform); + rleReset(shape->strokeRle); +} + + +bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid) +{ + SwOutline* shapeOutline = nullptr; + SwOutline* strokeOutline = nullptr; + bool freeOutline = false; + bool ret = true; + + //Dash Style Stroke + if (sdata->strokeDash(nullptr) > 0) { + shapeOutline = _genDashOutline(sdata, transform); + if (!shapeOutline) return false; + freeOutline = true; + //Normal Style stroke + } else { + if (!shape->outline) { + if (!_genOutline(shape, sdata, transform, mpool, tid, false)) return false; + } + shapeOutline = shape->outline; + } + + if (!strokeParseOutline(shape->stroke, *shapeOutline)) { + ret = false; + goto fail; + } + + strokeOutline = strokeExportOutline(shape->stroke, mpool, tid); + + if (!mathUpdateOutlineBBox(strokeOutline, clipRegion, renderRegion, false)) { + ret = false; + goto fail; + } + + shape->strokeRle = rleRender(shape->strokeRle, strokeOutline, renderRegion, true); + +fail: + if (freeOutline) { + if (shapeOutline->cntrs) free(shapeOutline->cntrs); + if (shapeOutline->pts) free(shapeOutline->pts); + if (shapeOutline->types) free(shapeOutline->types); + if (shapeOutline->closed) free(shapeOutline->closed); + free(shapeOutline); + } + mpoolRetStrokeOutline(mpool, tid); + + return ret; +} + + +bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable) +{ + return fillGenColorTable(shape->fill, fill, transform, surface, opacity, ctable); +} + + +bool shapeGenStrokeFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable) +{ + return fillGenColorTable(shape->stroke->fill, fill, transform, surface, opacity, ctable); +} + + +void shapeResetFill(SwShape* shape) +{ + if (!shape->fill) { + shape->fill = static_cast<SwFill*>(calloc(1, sizeof(SwFill))); + if (!shape->fill) return; + } + fillReset(shape->fill); +} + + +void shapeResetStrokeFill(SwShape* shape) +{ + if (!shape->stroke->fill) { + shape->stroke->fill = static_cast<SwFill*>(calloc(1, sizeof(SwFill))); + if (!shape->stroke->fill) return; + } + fillReset(shape->stroke->fill); +} + + +void shapeDelFill(SwShape* shape) +{ + if (!shape->fill) return; + fillFree(shape->fill); + shape->fill = nullptr; +} + + +void shapeDelStrokeFill(SwShape* shape) +{ + if (!shape->stroke->fill) return; + fillFree(shape->stroke->fill); + shape->stroke->fill = nullptr; +} diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwStroke.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwStroke.cpp new file mode 100644 index 0000000000..c0cfc1be26 --- /dev/null +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwStroke.cpp @@ -0,0 +1,932 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include <string.h> +#include <math.h> +#include "tvgSwCommon.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static constexpr auto SW_STROKE_TAG_POINT = 1; +static constexpr auto SW_STROKE_TAG_CUBIC = 2; +static constexpr auto SW_STROKE_TAG_BEGIN = 4; +static constexpr auto SW_STROKE_TAG_END = 8; + +static inline SwFixed SIDE_TO_ROTATE(const int32_t s) +{ + return (SW_ANGLE_PI2 - static_cast<SwFixed>(s) * SW_ANGLE_PI); +} + + +static inline void SCALE(const SwStroke& stroke, SwPoint& pt) +{ + pt.x = static_cast<SwCoord>(pt.x * stroke.sx); + pt.y = static_cast<SwCoord>(pt.y * stroke.sy); +} + + +static void _growBorder(SwStrokeBorder* border, uint32_t newPts) +{ + auto maxOld = border->maxPts; + auto maxNew = border->ptsCnt + newPts; + + if (maxNew <= maxOld) return; + + auto maxCur = maxOld; + + while (maxCur < maxNew) + maxCur += (maxCur >> 1) + 16; + //OPTIMIZE: use mempool! + border->pts = static_cast<SwPoint*>(realloc(border->pts, maxCur * sizeof(SwPoint))); + border->tags = static_cast<uint8_t*>(realloc(border->tags, maxCur * sizeof(uint8_t))); + border->maxPts = maxCur; +} + + +static void _borderClose(SwStrokeBorder* border, bool reverse) +{ + auto start = border->start; + auto count = border->ptsCnt; + + //Don't record empty paths! + if (count <= start + 1U) { + border->ptsCnt = start; + } else { + /* Copy the last point to the start of this sub-path, + since it contains the adjusted starting coordinates */ + border->ptsCnt = --count; + border->pts[start] = border->pts[count]; + + if (reverse) { + //reverse the points + auto pt1 = border->pts + start + 1; + auto pt2 = border->pts + count - 1; + + while (pt1 < pt2) { + auto tmp = *pt1; + *pt1 = *pt2; + *pt2 = tmp; + ++pt1; + --pt2; + } + + //reverse the tags + auto tag1 = border->tags + start + 1; + auto tag2 = border->tags + count - 1; + + while (tag1 < tag2) { + auto tmp = *tag1; + *tag1 = *tag2; + *tag2 = tmp; + ++tag1; + --tag2; + } + } + + border->tags[start] |= SW_STROKE_TAG_BEGIN; + border->tags[count - 1] |= SW_STROKE_TAG_END; + } + + border->start = -1; + border->movable = false; +} + + +static void _borderCubicTo(SwStrokeBorder* border, const SwPoint& ctrl1, const SwPoint& ctrl2, const SwPoint& to) +{ + _growBorder(border, 3); + + auto pt = border->pts + border->ptsCnt; + auto tag = border->tags + border->ptsCnt; + + pt[0] = ctrl1; + pt[1] = ctrl2; + pt[2] = to; + + tag[0] = SW_STROKE_TAG_CUBIC; + tag[1] = SW_STROKE_TAG_CUBIC; + tag[2] = SW_STROKE_TAG_POINT; + + border->ptsCnt += 3; + + border->movable = false; +} + + +static void _borderArcTo(SwStrokeBorder* border, const SwPoint& center, SwFixed radius, SwFixed angleStart, SwFixed angleDiff, SwStroke& stroke) +{ + constexpr SwFixed ARC_CUBIC_ANGLE = SW_ANGLE_PI / 2; + SwPoint a = {static_cast<SwCoord>(radius), 0}; + mathRotate(a, angleStart); + SCALE(stroke, a); + a += center; + + auto total = angleDiff; + auto angle = angleStart; + auto rotate = (angleDiff >= 0) ? SW_ANGLE_PI2 : -SW_ANGLE_PI2; + + while (total != 0) { + auto step = total; + if (step > ARC_CUBIC_ANGLE) step = ARC_CUBIC_ANGLE; + else if (step < -ARC_CUBIC_ANGLE) step = -ARC_CUBIC_ANGLE; + + auto next = angle + step; + auto theta = step; + if (theta < 0) theta = -theta; + + theta >>= 1; + + //compute end point + SwPoint b = {static_cast<SwCoord>(radius), 0}; + mathRotate(b, next); + SCALE(stroke, b); + b += center; + + //compute first and second control points + auto length = mathMulDiv(radius, mathSin(theta) * 4, (0x10000L + mathCos(theta)) * 3); + + SwPoint a2 = {static_cast<SwCoord>(length), 0}; + mathRotate(a2, angle + rotate); + SCALE(stroke, a2); + a2 += a; + + SwPoint b2 = {static_cast<SwCoord>(length), 0}; + mathRotate(b2, next - rotate); + SCALE(stroke, b2); + b2 += b; + + //add cubic arc + _borderCubicTo(border, a2, b2, b); + + //process the rest of the arc? + a = b; + total -= step; + angle = next; + } +} + + +static void _borderLineTo(SwStrokeBorder* border, const SwPoint& to, bool movable) +{ + if (border->movable) { + //move last point + border->pts[border->ptsCnt - 1] = to; + } else { + + //don't add zero-length line_to + if (border->ptsCnt > 0 && (border->pts[border->ptsCnt - 1] - to).small()) return; + + _growBorder(border, 1); + border->pts[border->ptsCnt] = to; + border->tags[border->ptsCnt] = SW_STROKE_TAG_POINT; + border->ptsCnt += 1; + } + + border->movable = movable; +} + + +static void _borderMoveTo(SwStrokeBorder* border, SwPoint& to) +{ + //close current open path if any? + if (border->start >= 0) _borderClose(border, false); + + border->start = border->ptsCnt; + border->movable = false; + + _borderLineTo(border, to, false); +} + + +static void _arcTo(SwStroke& stroke, int32_t side) +{ + auto border = stroke.borders + side; + auto rotate = SIDE_TO_ROTATE(side); + auto total = mathDiff(stroke.angleIn, stroke.angleOut); + if (total == SW_ANGLE_PI) total = -rotate * 2; + + _borderArcTo(border, stroke.center, stroke.width, stroke.angleIn + rotate, total, stroke); + border->movable = false; +} + + +static void _outside(SwStroke& stroke, int32_t side, SwFixed lineLength) +{ + constexpr SwFixed MITER_LIMIT = 4 * (1 << 16); + + auto border = stroke.borders + side; + + if (stroke.join == StrokeJoin::Round) { + _arcTo(stroke, side); + } else { + //this is a mitered (pointed) or beveled (truncated) corner + auto rotate = SIDE_TO_ROTATE(side); + auto bevel = (stroke.join == StrokeJoin::Bevel) ? true : false; + SwFixed phi = 0; + SwFixed thcos = 0; + + if (!bevel) { + auto theta = mathDiff(stroke.angleIn, stroke.angleOut); + if (theta == SW_ANGLE_PI) { + theta = rotate; + phi = stroke.angleIn; + } else { + theta /= 2; + phi = stroke.angleIn + theta + rotate; + } + + thcos = mathCos(theta); + auto sigma = mathMultiply(MITER_LIMIT, thcos); + + //is miter limit exceeded? + if (sigma < 0x10000L) bevel = true; + } + + //this is a bevel (broken angle) + if (bevel) { + SwPoint delta = {static_cast<SwCoord>(stroke.width), 0}; + mathRotate(delta, stroke.angleOut + rotate); + SCALE(stroke, delta); + delta += stroke.center; + border->movable = false; + _borderLineTo(border, delta, false); + //this is a miter (intersection) + } else { + auto length = mathDivide(stroke.width, thcos); + SwPoint delta = {static_cast<SwCoord>(length), 0}; + mathRotate(delta, phi); + SCALE(stroke, delta); + delta += stroke.center; + _borderLineTo(border, delta, false); + + /* Now add and end point + Only needed if not lineto (lineLength is zero for curves) */ + if (lineLength == 0) { + delta = {static_cast<SwCoord>(stroke.width), 0}; + mathRotate(delta, stroke.angleOut + rotate); + SCALE(stroke, delta); + delta += stroke.center; + _borderLineTo(border, delta, false); + } + } + } +} + + +static void _inside(SwStroke& stroke, int32_t side, SwFixed lineLength) +{ + auto border = stroke.borders + side; + auto theta = mathDiff(stroke.angleIn, stroke.angleOut) / 2; + SwPoint delta; + bool intersect = false; + + /* Only intersect borders if between two line_to's and both + lines are long enough (line length is zero fur curves). */ + if (border->movable && lineLength > 0) { + //compute minimum required length of lines + SwFixed minLength = abs(mathMultiply(stroke.width, mathTan(theta))); + if (stroke.lineLength >= minLength && lineLength >= minLength) intersect = true; + } + + auto rotate = SIDE_TO_ROTATE(side); + + if (!intersect) { + delta = {static_cast<SwCoord>(stroke.width), 0}; + mathRotate(delta, stroke.angleOut + rotate); + SCALE(stroke, delta); + delta += stroke.center; + border->movable = false; + } else { + //compute median angle + auto phi = stroke.angleIn + theta; + auto thcos = mathCos(theta); + delta = {static_cast<SwCoord>(mathDivide(stroke.width, thcos)), 0}; + mathRotate(delta, phi + rotate); + SCALE(stroke, delta); + delta += stroke.center; + } + + _borderLineTo(border, delta, false); +} + + +void _processCorner(SwStroke& stroke, SwFixed lineLength) +{ + auto turn = mathDiff(stroke.angleIn, stroke.angleOut); + + //no specific corner processing is required if the turn is 0 + if (turn == 0) return; + + //when we turn to the right, the inside side is 0 + int32_t inside = 0; + + //otherwise, the inside is 1 + if (turn < 0) inside = 1; + + //process the inside + _inside(stroke, inside, lineLength); + + //process the outside + _outside(stroke, 1 - inside, lineLength); +} + + +void _firstSubPath(SwStroke& stroke, SwFixed startAngle, SwFixed lineLength) +{ + SwPoint delta = {static_cast<SwCoord>(stroke.width), 0}; + mathRotate(delta, startAngle + SW_ANGLE_PI2); + SCALE(stroke, delta); + + auto pt = stroke.center + delta; + auto border = stroke.borders; + _borderMoveTo(border, pt); + + pt = stroke.center - delta; + ++border; + _borderMoveTo(border, pt); + + /* Save angle, position and line length for last join + lineLength is zero for curves */ + stroke.subPathAngle = startAngle; + stroke.firstPt = false; + stroke.subPathLineLength = lineLength; +} + + +static void _lineTo(SwStroke& stroke, const SwPoint& to) +{ + auto delta = to - stroke.center; + + //a zero-length lineto is a no-op; avoid creating a spurious corner + if (delta.zero()) return; + + //compute length of line + auto lineLength = mathLength(delta); + auto angle = mathAtan(delta); + + delta = {static_cast<SwCoord>(stroke.width), 0}; + mathRotate(delta, angle + SW_ANGLE_PI2); + SCALE(stroke, delta); + + //process corner if necessary + if (stroke.firstPt) { + /* This is the first segment of a subpath. We need to add a point to each border + at their respective starting point locations. */ + _firstSubPath(stroke, angle, lineLength); + } else { + //process the current corner + stroke.angleOut = angle; + _processCorner(stroke, lineLength); + } + + //now add a line segment to both the inside and outside paths + auto border = stroke.borders; + auto side = 1; + + while (side >= 0) { + auto pt = to + delta; + + //the ends of lineto borders are movable + _borderLineTo(border, pt, true); + + delta.x = -delta.x; + delta.y = -delta.y; + + --side; + ++border; + } + + stroke.angleIn = angle; + stroke.center = to; + stroke.lineLength = lineLength; +} + + +static void _cubicTo(SwStroke& stroke, const SwPoint& ctrl1, const SwPoint& ctrl2, const SwPoint& to) +{ + /* if all control points are coincident, this is a no-op; + avoid creating a spurious corner */ + if ((stroke.center - ctrl1).small() && (ctrl1 - ctrl2).small() && (ctrl2 - to).small()) { + stroke.center = to; + return; + } + + SwPoint bezStack[37]; //TODO: static? + auto limit = bezStack + 32; + auto arc = bezStack; + auto firstArc = true; + arc[0] = to; + arc[1] = ctrl2; + arc[2] = ctrl1; + arc[3] = stroke.center; + + while (arc >= bezStack) { + SwFixed angleIn, angleOut, angleMid; + + //initialize with current direction + angleIn = angleOut = angleMid = stroke.angleIn; + + if (arc < limit && !mathSmallCubic(arc, angleIn, angleMid, angleOut)) { + if (stroke.firstPt) stroke.angleIn = angleIn; + mathSplitCubic(arc); + arc += 3; + continue; + } + + if (firstArc) { + firstArc = false; + //process corner if necessary + if (stroke.firstPt) { + _firstSubPath(stroke, angleIn, 0); + } else { + stroke.angleOut = angleIn; + _processCorner(stroke, 0); + } + } else if (abs(mathDiff(stroke.angleIn, angleIn)) > (SW_ANGLE_PI / 8) / 4) { + //if the deviation from one arc to the next is too great add a round corner + stroke.center = arc[3]; + stroke.angleOut = angleIn; + stroke.join = StrokeJoin::Round; + + _processCorner(stroke, 0); + + //reinstate line join style + stroke.join = stroke.joinSaved; + } + + //the arc's angle is small enough; we can add it directly to each border + auto theta1 = mathDiff(angleIn, angleMid) / 2; + auto theta2 = mathDiff(angleMid, angleOut) / 2; + auto phi1 = mathMean(angleIn, angleMid); + auto phi2 = mathMean(angleMid, angleOut); + auto length1 = mathDivide(stroke.width, mathCos(theta1)); + auto length2 = mathDivide(stroke.width, mathCos(theta2)); + SwFixed alpha0 = 0; + + //compute direction of original arc + if (stroke.handleWideStrokes) { + alpha0 = mathAtan(arc[0] - arc[3]); + } + + auto border = stroke.borders; + int32_t side = 0; + + while (side <= 1) + { + auto rotate = SIDE_TO_ROTATE(side); + + //compute control points + SwPoint _ctrl1 = {static_cast<SwCoord>(length1), 0}; + mathRotate(_ctrl1, phi1 + rotate); + SCALE(stroke, _ctrl1); + _ctrl1 += arc[2]; + + SwPoint _ctrl2 = {static_cast<SwCoord>(length2), 0}; + mathRotate(_ctrl2, phi2 + rotate); + SCALE(stroke, _ctrl2); + _ctrl2 += arc[1]; + + //compute end point + SwPoint _end = {static_cast<SwCoord>(stroke.width), 0}; + mathRotate(_end, angleOut + rotate); + SCALE(stroke, _end); + _end += arc[0]; + + if (stroke.handleWideStrokes) { + + /* determine whether the border radius is greater than the radius of + curvature of the original arc */ + auto _start = border->pts[border->ptsCnt - 1]; + auto alpha1 = mathAtan(_end - _start); + + //is the direction of the border arc opposite to that of the original arc? + if (abs(mathDiff(alpha0, alpha1)) > SW_ANGLE_PI / 2) { + + //use the sine rule to find the intersection point + auto beta = mathAtan(arc[3] - _start); + auto gamma = mathAtan(arc[0] - _end); + auto bvec = _end - _start; + auto blen = mathLength(bvec); + auto sinA = abs(mathSin(alpha1 - gamma)); + auto sinB = abs(mathSin(beta - gamma)); + auto alen = mathMulDiv(blen, sinA, sinB); + + SwPoint delta = {static_cast<SwCoord>(alen), 0}; + mathRotate(delta, beta); + delta += _start; + + //circumnavigate the negative sector backwards + border->movable = false; + _borderLineTo(border, delta, false); + _borderLineTo(border, _end, false); + _borderCubicTo(border, _ctrl2, _ctrl1, _start); + + //and then move to the endpoint + _borderLineTo(border, _end, false); + + ++side; + ++border; + continue; + } + + //else fall through + } + _borderCubicTo(border, _ctrl1, _ctrl2, _end); + ++side; + ++border; + } + arc -= 3; + stroke.angleIn = angleOut; + } + stroke.center = to; +} + + +static void _addCap(SwStroke& stroke, SwFixed angle, int32_t side) +{ + if (stroke.cap == StrokeCap::Square) { + auto rotate = SIDE_TO_ROTATE(side); + auto border = stroke.borders + side; + + SwPoint delta = {static_cast<SwCoord>(stroke.width), 0}; + mathRotate(delta, angle); + SCALE(stroke, delta); + + SwPoint delta2 = {static_cast<SwCoord>(stroke.width), 0}; + mathRotate(delta2, angle + rotate); + SCALE(stroke, delta2); + delta += stroke.center + delta2; + + _borderLineTo(border, delta, false); + + delta = {static_cast<SwCoord>(stroke.width), 0}; + mathRotate(delta, angle); + SCALE(stroke, delta); + + delta2 = {static_cast<SwCoord>(stroke.width), 0}; + mathRotate(delta2, angle - rotate); + SCALE(stroke, delta2); + delta += delta2 + stroke.center; + + _borderLineTo(border, delta, false); + + } else if (stroke.cap == StrokeCap::Round) { + + stroke.angleIn = angle; + stroke.angleOut = angle + SW_ANGLE_PI; + _arcTo(stroke, side); + return; + + } else { //Butt + auto rotate = SIDE_TO_ROTATE(side); + auto border = stroke.borders + side; + + SwPoint delta = {static_cast<SwCoord>(stroke.width), 0}; + mathRotate(delta, angle + rotate); + SCALE(stroke, delta); + delta += stroke.center; + + _borderLineTo(border, delta, false); + + delta = {static_cast<SwCoord>(stroke.width), 0}; + mathRotate(delta, angle - rotate); + SCALE(stroke, delta); + delta += stroke.center; + + _borderLineTo(border, delta, false); + } +} + + +static void _addReverseLeft(SwStroke& stroke, bool opened) +{ + auto right = stroke.borders + 0; + auto left = stroke.borders + 1; + auto newPts = left->ptsCnt - left->start; + + if (newPts <= 0) return; + + _growBorder(right, newPts); + + auto dstPt = right->pts + right->ptsCnt; + auto dstTag = right->tags + right->ptsCnt; + auto srcPt = left->pts + left->ptsCnt - 1; + auto srcTag = left->tags + left->ptsCnt - 1; + + while (srcPt >= left->pts + left->start) { + *dstPt = *srcPt; + *dstTag = *srcTag; + + if (opened) { + dstTag[0] &= ~(SW_STROKE_TAG_BEGIN | SW_STROKE_TAG_END); + } else { + //switch begin/end tags if necessary + auto ttag = dstTag[0] & (SW_STROKE_TAG_BEGIN | SW_STROKE_TAG_END); + if (ttag == SW_STROKE_TAG_BEGIN || ttag == SW_STROKE_TAG_END) + dstTag[0] ^= (SW_STROKE_TAG_BEGIN | SW_STROKE_TAG_END); + } + + --srcPt; + --srcTag; + ++dstPt; + ++dstTag; + } + + left->ptsCnt = left->start; + right->ptsCnt += newPts; + right->movable = false; + left->movable = false; +} + + +static void _beginSubPath(SwStroke& stroke, const SwPoint& to, bool closed) +{ + /* We cannot process the first point because there is not enough + information regarding its corner/cap. Later, it will be processed + in the _endSubPath() */ + + stroke.firstPt = true; + stroke.center = to; + stroke.closedSubPath = closed; + + /* Determine if we need to check whether the border radius is greater + than the radius of curvature of a curve, to handle this case specially. + This is only required if bevel joins or butt caps may be created because + round & miter joins and round & square caps cover the nagative sector + created with wide strokes. */ + if ((stroke.join != StrokeJoin::Round) || (!stroke.closedSubPath && stroke.cap == StrokeCap::Butt)) + stroke.handleWideStrokes = true; + else + stroke.handleWideStrokes = false; + + stroke.ptStartSubPath = to; + stroke.angleIn = 0; +} + + +static void _endSubPath(SwStroke& stroke) +{ + if (stroke.closedSubPath) { + //close the path if needed + if (stroke.center != stroke.ptStartSubPath) + _lineTo(stroke, stroke.ptStartSubPath); + + //process the corner + stroke.angleOut = stroke.subPathAngle; + auto turn = mathDiff(stroke.angleIn, stroke.angleOut); + + //No specific corner processing is required if the turn is 0 + if (turn != 0) { + + //when we turn to the right, the inside is 0 + int32_t inside = 0; + + //otherwise, the inside is 1 + if (turn < 0) inside = 1; + + _inside(stroke, inside, stroke.subPathLineLength); //inside + _outside(stroke, 1 - inside, stroke.subPathLineLength); //outside + } + + _borderClose(stroke.borders + 0, false); + _borderClose(stroke.borders + 1, true); + } else { + auto right = stroke.borders; + + /* all right, this is an opened path, we need to add a cap between + right & left, add the reverse of left, then add a final cap + between left & right */ + _addCap(stroke, stroke.angleIn, 0); + + //add reversed points from 'left' to 'right' + _addReverseLeft(stroke, true); + + //now add the final cap + stroke.center = stroke.ptStartSubPath; + _addCap(stroke, stroke.subPathAngle + SW_ANGLE_PI, 0); + + /* now end the right subpath accordingly. The left one is rewind + and deosn't need further processing */ + _borderClose(right, false); + } +} + + +static void _getCounts(SwStrokeBorder* border, uint32_t& ptsCnt, uint32_t& cntrsCnt) +{ + auto count = border->ptsCnt; + auto tags = border->tags; + uint32_t _ptsCnt = 0; + uint32_t _cntrsCnt = 0; + bool inCntr = false; + + while (count > 0) { + if (tags[0] & SW_STROKE_TAG_BEGIN) { + if (inCntr) goto fail; + inCntr = true; + } else if (!inCntr) goto fail; + + if (tags[0] & SW_STROKE_TAG_END) { + inCntr = false; + ++_cntrsCnt; + } + --count; + ++_ptsCnt; + ++tags; + } + + if (inCntr) goto fail; + + ptsCnt = _ptsCnt; + cntrsCnt = _cntrsCnt; + + return; + +fail: + ptsCnt = 0; + cntrsCnt = 0; +} + + +static void _exportBorderOutline(const SwStroke& stroke, SwOutline* outline, uint32_t side) +{ + auto border = stroke.borders + side; + + if (border->ptsCnt == 0) return; //invalid border + + memcpy(outline->pts + outline->ptsCnt, border->pts, border->ptsCnt * sizeof(SwPoint)); + + auto cnt = border->ptsCnt; + auto src = border->tags; + auto tags = outline->types + outline->ptsCnt; + auto cntrs = outline->cntrs + outline->cntrsCnt; + uint16_t idx = outline->ptsCnt; + + while (cnt > 0) { + + if (*src & SW_STROKE_TAG_POINT) *tags = SW_CURVE_TYPE_POINT; + else if (*src & SW_STROKE_TAG_CUBIC) *tags = SW_CURVE_TYPE_CUBIC; + else { + //LOG: What type of stroke outline?? + } + + if (*src & SW_STROKE_TAG_END) { + *cntrs = idx; + ++cntrs; + ++outline->cntrsCnt; + } + ++src; + ++tags; + ++idx; + --cnt; + } + outline->ptsCnt = outline->ptsCnt + border->ptsCnt; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +void strokeFree(SwStroke* stroke) +{ + if (!stroke) return; + + //free borders + if (stroke->borders[0].pts) free(stroke->borders[0].pts); + if (stroke->borders[0].tags) free(stroke->borders[0].tags); + if (stroke->borders[1].pts) free(stroke->borders[1].pts); + if (stroke->borders[1].tags) free(stroke->borders[1].tags); + + fillFree(stroke->fill); + stroke->fill = nullptr; + + free(stroke); +} + + +void strokeReset(SwStroke* stroke, const Shape* sdata, const Matrix* transform) +{ + if (transform) { + stroke->sx = sqrtf(powf(transform->e11, 2.0f) + powf(transform->e21, 2.0f)); + stroke->sy = sqrtf(powf(transform->e12, 2.0f) + powf(transform->e22, 2.0f)); + } else { + stroke->sx = stroke->sy = 1.0f; + } + + stroke->width = HALF_STROKE(sdata->strokeWidth()); + stroke->cap = sdata->strokeCap(); + + //Save line join: it can be temporarily changed when stroking curves... + stroke->joinSaved = stroke->join = sdata->strokeJoin(); + + stroke->borders[0].ptsCnt = 0; + stroke->borders[0].start = -1; + stroke->borders[1].ptsCnt = 0; + stroke->borders[1].start = -1; +} + + +bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline) +{ + uint32_t first = 0; + + for (uint32_t i = 0; i < outline.cntrsCnt; ++i) { + auto last = outline.cntrs[i]; //index of last point in contour + auto limit = outline.pts + last; + + //Skip empty points + if (last <= first) { + first = last + 1; + continue; + } + + auto start = outline.pts[first]; + auto pt = outline.pts + first; + auto types = outline.types + first; + auto type = types[0]; + + //A contour cannot start with a cubic control point + if (type == SW_CURVE_TYPE_CUBIC) return false; + + auto closed = outline.closed ? outline.closed[i]: false; + + _beginSubPath(*stroke, start, closed); + + while (pt < limit) { + ++pt; + ++types; + + //emit a signel line_to + if (types[0] == SW_CURVE_TYPE_POINT) { + _lineTo(*stroke, *pt); + //types cubic + } else { + if (pt + 1 > limit || types[1] != SW_CURVE_TYPE_CUBIC) return false; + + pt += 2; + types += 2; + + if (pt <= limit) { + _cubicTo(*stroke, pt[-2], pt[-1], pt[0]); + continue; + } + _cubicTo(*stroke, pt[-2], pt[-1], start); + goto close; + } + } + + close: + if (!stroke->firstPt) _endSubPath(*stroke); + first = last + 1; + } + return true; +} + + +SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid) +{ + uint32_t count1, count2, count3, count4; + + _getCounts(stroke->borders + 0, count1, count2); + _getCounts(stroke->borders + 1, count3, count4); + + auto ptsCnt = count1 + count3; + auto cntrsCnt = count2 + count4; + + auto outline = mpoolReqStrokeOutline(mpool, tid); + if (outline->reservedPtsCnt < ptsCnt) { + outline->pts = static_cast<SwPoint*>(realloc(outline->pts, sizeof(SwPoint) * ptsCnt)); + outline->types = static_cast<uint8_t*>(realloc(outline->types, sizeof(uint8_t) * ptsCnt)); + outline->reservedPtsCnt = ptsCnt; + } + if (outline->reservedCntrsCnt < cntrsCnt) { + outline->cntrs = static_cast<uint16_t*>(realloc(outline->cntrs, sizeof(uint16_t) * cntrsCnt)); + outline->reservedCntrsCnt = cntrsCnt; + } + + _exportBorderOutline(*stroke, outline, 0); //left + _exportBorderOutline(*stroke, outline, 1); //right + + return outline; +} diff --git a/thirdparty/thorvg/src/lib/tvgAccessor.cpp b/thirdparty/thorvg/src/lib/tvgAccessor.cpp new file mode 100644 index 0000000000..085c8a3cbc --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgAccessor.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "tvgIteratorAccessor.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static bool accessChildren(Iterator* it, bool(*func)(const Paint* paint), IteratorAccessor& itrAccessor) +{ + while (auto child = it->next()) { + //Access the child + if (!func(child)) return false; + + //Access the children of the child + if (auto it2 = itrAccessor.iterator(child)) { + if (!accessChildren(it2, func, itrAccessor)) { + delete(it2); + return false; + } + delete(it2); + } + } + return true; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +unique_ptr<Picture> Accessor::access(unique_ptr<Picture> picture, bool(*func)(const Paint* paint)) noexcept +{ + auto p = picture.get(); + if (!p || !func) return picture; + + //Use the Preorder Tree-Search + + //Root + if (!func(p)) return picture; + + //Children + IteratorAccessor itrAccessor; + if (auto it = itrAccessor.iterator(p)) { + accessChildren(it, func, itrAccessor); + delete(it); + } + return picture; +} + + +Accessor::~Accessor() +{ + +} + + +Accessor::Accessor() +{ + +} + + +unique_ptr<Accessor> Accessor::gen() noexcept +{ + return unique_ptr<Accessor>(new Accessor); +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/tvgArray.h b/thirdparty/thorvg/src/lib/tvgArray.h new file mode 100644 index 0000000000..d04e68e73c --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgArray.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_ARRAY_H_ +#define _TVG_ARRAY_H_ + +#include <memory.h> + +namespace tvg +{ + +template<class T> +struct Array +{ + T* data = nullptr; + uint32_t count = 0; + uint32_t reserved = 0; + + void push(T element) + { + if (count + 1 > reserved) { + reserved = (count + 1) * 2; + auto p = data; + data = static_cast<T*>(realloc(data, sizeof(T) * reserved)); + if (!data) { + data = p; + return; + } + } + data[count++] = element; + } + + bool reserve(uint32_t size) + { + if (size > reserved) { + reserved = size; + auto p = data; + data = static_cast<T*>(realloc(data, sizeof(T) * reserved)); + if (!data) { + data = p; + return false; + } + } + return true; + } + + bool grow(uint32_t size) + { + return reserve(count + size); + } + + T* ptr() + { + return data + count; + } + + void pop() + { + if (count > 0) --count; + } + + void reset() + { + if (data) { + free(data); + data = nullptr; + } + count = reserved = 0; + } + + void clear() + { + count = 0; + } + + void operator=(const Array& rhs) + { + reserve(rhs.count); + if (rhs.count > 0) memcpy(data, rhs.data, sizeof(T) * reserved); + count = rhs.count; + } + + ~Array() + { + if (data) free(data); + } +}; + +} + +#endif //_TVG_ARRAY_H_ diff --git a/thirdparty/thorvg/src/lib/tvgBezier.cpp b/thirdparty/thorvg/src/lib/tvgBezier.cpp new file mode 100644 index 0000000000..2290afa728 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgBezier.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include <float.h> +#include <math.h> +#include "tvgBezier.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static float _lineLength(const Point& pt1, const Point& pt2) +{ + /* approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm. + With alpha = 1, beta = 3/8, giving results with the largest error less + than 7% compared to the exact value. */ + Point diff = {pt2.x - pt1.x, pt2.y - pt1.y}; + if (diff.x < 0) diff.x = -diff.x; + if (diff.y < 0) diff.y = -diff.y; + return (diff.x > diff.y) ? (diff.x + diff.y * 0.375f) : (diff.y + diff.x * 0.375f); +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +namespace tvg +{ + +void bezSplit(const Bezier&cur, Bezier& left, Bezier& right) +{ + auto c = (cur.ctrl1.x + cur.ctrl2.x) * 0.5f; + left.ctrl1.x = (cur.start.x + cur.ctrl1.x) * 0.5f; + right.ctrl2.x = (cur.ctrl2.x + cur.end.x) * 0.5f; + left.start.x = cur.start.x; + right.end.x = cur.end.x; + left.ctrl2.x = (left.ctrl1.x + c) * 0.5f; + right.ctrl1.x = (right.ctrl2.x + c) * 0.5f; + left.end.x = right.start.x = (left.ctrl2.x + right.ctrl1.x) * 0.5f; + + c = (cur.ctrl1.y + cur.ctrl2.y) * 0.5f; + left.ctrl1.y = (cur.start.y + cur.ctrl1.y) * 0.5f; + right.ctrl2.y = (cur.ctrl2.y + cur.end.y) * 0.5f; + left.start.y = cur.start.y; + right.end.y = cur.end.y; + left.ctrl2.y = (left.ctrl1.y + c) * 0.5f; + right.ctrl1.y = (right.ctrl2.y + c) * 0.5f; + left.end.y = right.start.y = (left.ctrl2.y + right.ctrl1.y) * 0.5f; +} + + +float bezLength(const Bezier& cur) +{ + Bezier left, right; + auto len = _lineLength(cur.start, cur.ctrl1) + _lineLength(cur.ctrl1, cur.ctrl2) + _lineLength(cur.ctrl2, cur.end); + auto chord = _lineLength(cur.start, cur.end); + + if (fabsf(len - chord) > BEZIER_EPSILON) { + bezSplit(cur, left, right); + return bezLength(left) + bezLength(right); + } + return len; +} + + +void bezSplitLeft(Bezier& cur, float at, Bezier& left) +{ + left.start = cur.start; + + left.ctrl1.x = cur.start.x + at * (cur.ctrl1.x - cur.start.x); + left.ctrl1.y = cur.start.y + at * (cur.ctrl1.y - cur.start.y); + + left.ctrl2.x = cur.ctrl1.x + at * (cur.ctrl2.x - cur.ctrl1.x); //temporary holding spot + left.ctrl2.y = cur.ctrl1.y + at * (cur.ctrl2.y - cur.ctrl1.y); //temporary holding spot + + cur.ctrl2.x = cur.ctrl2.x + at * (cur.end.x - cur.ctrl2.x); + cur.ctrl2.y = cur.ctrl2.y + at * (cur.end.y - cur.ctrl2.y); + + cur.ctrl1.x = left.ctrl2.x + at * (cur.ctrl2.x - left.ctrl2.x); + cur.ctrl1.y = left.ctrl2.y + at * (cur.ctrl2.y - left.ctrl2.y); + + left.ctrl2.x = left.ctrl1.x + at * (left.ctrl2.x - left.ctrl1.x); + left.ctrl2.y = left.ctrl1.y + at * (left.ctrl2.y - left.ctrl1.y); + + left.end.x = cur.start.x = left.ctrl2.x + at * (cur.ctrl1.x - left.ctrl2.x); + left.end.y = cur.start.y = left.ctrl2.y + at * (cur.ctrl1.y - left.ctrl2.y); +} + + +float bezAt(const Bezier& bz, float at) +{ + auto len = bezLength(bz); + auto biggest = 1.0f; + auto smallest = 0.0f; + auto t = 0.5f; + + //just in case to prevent an infinite loop + if (at <= 0) return 0.0f; + + if (at >= len) return 1.0f; + + while (true) { + auto right = bz; + Bezier left; + bezSplitLeft(right, t, left); + len = bezLength(left); + + if (fabsf(len - at) < BEZIER_EPSILON || fabsf(smallest - biggest) < BEZIER_EPSILON) { + break; + } + + if (len < at) { + smallest = t; + t = (t + biggest) * 0.5f; + } else { + biggest = t; + t = (smallest + t) * 0.5f; + } + } + return t; +} + + +void bezSplitAt(const Bezier& cur, float at, Bezier& left, Bezier& right) +{ + right = cur; + auto t = bezAt(right, at); + bezSplitLeft(right, t, left); +} + +} diff --git a/thirdparty/thorvg/src/lib/tvgBezier.h b/thirdparty/thorvg/src/lib/tvgBezier.h new file mode 100644 index 0000000000..866e39148e --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgBezier.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_BEZIER_H_ +#define _TVG_BEZIER_H_ + +#include "tvgCommon.h" + +namespace tvg +{ + +#define BEZIER_EPSILON 1e-4f + +struct Bezier +{ + Point start; + Point ctrl1; + Point ctrl2; + Point end; +}; + +void bezSplit(const Bezier&cur, Bezier& left, Bezier& right); +float bezLength(const Bezier& cur); +void bezSplitLeft(Bezier& cur, float at, Bezier& left); +float bezAt(const Bezier& bz, float at); +void bezSplitAt(const Bezier& cur, float at, Bezier& left, Bezier& right); + +} + +#endif //_TVG_BEZIER_H_ diff --git a/thirdparty/thorvg/src/lib/tvgBinaryDesc.h b/thirdparty/thorvg/src/lib/tvgBinaryDesc.h new file mode 100644 index 0000000000..30ba2d5a29 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgBinaryDesc.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_BINARY_DESC_H_ +#define _TVG_BINARY_DESC_H_ + +/* TODO: Need to consider whether uin8_t is enough size for extension... + Rather than optimal data, we can use enough size and data compress? */ + +/* Data types, do not change data types once Tvg Format is officially released, + That would occur the abi break. */ + +using TvgBinByte = uint8_t; +using TvgBinCounter = uint32_t; +using TvgBinTag = TvgBinByte; +using TvgBinFlag = TvgBinByte; + + +//Header +#define TVG_HEADER_SIZE 33 //TVG_HEADER_SIGNATURE_LENGTH + TVG_HEADER_VERSION_LENGTH + 2*SIZE(float) + TVG_HEADER_RESERVED_LENGTH + TVG_HEADER_COMPRESS_SIZE +#define TVG_HEADER_SIGNATURE "ThorVG" +#define TVG_HEADER_SIGNATURE_LENGTH 6 +#define TVG_HEADER_VERSION "000400" //Major 00, Minor 04, Micro 00 +#define TVG_HEADER_VERSION_LENGTH 6 +#define TVG_HEADER_RESERVED_LENGTH 1 //Storing flags for extensions +#define TVG_HEADER_COMPRESS_SIZE 12 //TVG_HEADER_UNCOMPRESSED_SIZE + TVG_HEADER_COMPRESSED_SIZE + TVG_HEADER_COMPRESSED_SIZE_BITS +//Compress Size +#define TVG_HEADER_UNCOMPRESSED_SIZE 4 //SIZE (TvgBinCounter) +#define TVG_HEADER_COMPRESSED_SIZE 4 //SIZE (TvgBinCounter) +#define TVG_HEADER_COMPRESSED_SIZE_BITS 4 //SIZE (TvgBinCounter) +//Reserved Flag +#define TVG_HEAD_FLAG_COMPRESSED 0x01 + +//Paint Type +#define TVG_TAG_CLASS_PICTURE (TvgBinTag)0xfc +#define TVG_TAG_CLASS_SHAPE (TvgBinTag)0xfd +#define TVG_TAG_CLASS_SCENE (TvgBinTag)0xfe + + +//Paint +#define TVG_TAG_PAINT_OPACITY (TvgBinTag)0x10 +#define TVG_TAG_PAINT_TRANSFORM (TvgBinTag)0x11 +#define TVG_TAG_PAINT_CMP_TARGET (TvgBinTag)0x01 +#define TVG_TAG_PAINT_CMP_METHOD (TvgBinTag)0x20 + + +//Scene +#define TVG_TAG_SCENE_RESERVEDCNT (TvgBinTag)0x30 + + +//Shape +#define TVG_TAG_SHAPE_PATH (TvgBinTag)0x40 +#define TVG_TAG_SHAPE_STROKE (TvgBinTag)0x41 +#define TVG_TAG_SHAPE_FILL (TvgBinTag)0x42 +#define TVG_TAG_SHAPE_COLOR (TvgBinTag)0x43 +#define TVG_TAG_SHAPE_FILLRULE (TvgBinTag)0x44 +#define TVG_TAG_SHAPE_STROKE_CAP (TvgBinTag)0x50 +#define TVG_TAG_SHAPE_STROKE_JOIN (TvgBinTag)0x51 + +//Stroke +#define TVG_TAG_SHAPE_STROKE_WIDTH (TvgBinTag)0x52 +#define TVG_TAG_SHAPE_STROKE_COLOR (TvgBinTag)0x53 +#define TVG_TAG_SHAPE_STROKE_FILL (TvgBinTag)0x54 +#define TVG_TAG_SHAPE_STROKE_DASHPTRN (TvgBinTag)0x55 + + +//Fill +#define TVG_TAG_FILL_LINEAR_GRADIENT (TvgBinTag)0x60 +#define TVG_TAG_FILL_RADIAL_GRADIENT (TvgBinTag)0x61 +#define TVG_TAG_FILL_COLORSTOPS (TvgBinTag)0x62 +#define TVG_TAG_FILL_FILLSPREAD (TvgBinTag)0x63 +#define TVG_TAG_FILL_TRANSFORM (TvgBinTag)0x64 + + +//Picture +#define TVG_TAG_PICTURE_RAW_IMAGE (TvgBinTag)0x70 + +#endif //_TVG_BINARY_DESC_H_ diff --git a/thirdparty/thorvg/src/lib/tvgCanvas.cpp b/thirdparty/thorvg/src/lib/tvgCanvas.cpp new file mode 100644 index 0000000000..bb42441c62 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgCanvas.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "tvgCanvasImpl.h" + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Canvas::Canvas(RenderMethod *pRenderer):pImpl(new Impl(pRenderer)) +{ +} + + +Canvas::~Canvas() +{ + delete(pImpl); +} + + +Result Canvas::reserve(uint32_t n) noexcept +{ + if (!pImpl->paints.reserve(n)) return Result::FailedAllocation; + return Result::Success; +} + + +Result Canvas::push(unique_ptr<Paint> paint) noexcept +{ + return pImpl->push(move(paint)); +} + + +Result Canvas::clear(bool free) noexcept +{ + return pImpl->clear(free); +} + + +Result Canvas::draw() noexcept +{ + return pImpl->draw(); +} + + +Result Canvas::update(Paint* paint) noexcept +{ + return pImpl->update(paint, false); +} + + +Result Canvas::sync() noexcept +{ + return pImpl->sync(); +} diff --git a/thirdparty/thorvg/src/lib/tvgCanvasImpl.h b/thirdparty/thorvg/src/lib/tvgCanvasImpl.h new file mode 100644 index 0000000000..848c03aaed --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgCanvasImpl.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_CANVAS_IMPL_H_ +#define _TVG_CANVAS_IMPL_H_ + +#include "tvgPaint.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct Canvas::Impl +{ + Array<Paint*> paints; + RenderMethod* renderer; + bool refresh = false; //if all paints should be updated by force. + bool drawing = false; //on drawing condition? + + Impl(RenderMethod* pRenderer):renderer(pRenderer) + { + } + + ~Impl() + { + clear(true); + delete(renderer); + } + + Result push(unique_ptr<Paint> paint) + { + //You can not push paints during rendering. + if (drawing) return Result::InsufficientCondition; + + auto p = paint.release(); + if (!p) return Result::MemoryCorruption; + paints.push(p); + + return update(p, true); + } + + Result clear(bool free) + { + //Clear render target before drawing + if (!renderer || !renderer->clear()) return Result::InsufficientCondition; + + //Free paints + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + (*paint)->pImpl->dispose(*renderer); + if (free) delete(*paint); + } + + paints.clear(); + + drawing = false; + + return Result::Success; + } + + void needRefresh() + { + refresh = true; + } + + Result update(Paint* paint, bool force) + { + if (paints.count == 0 || drawing || !renderer) return Result::InsufficientCondition; + + Array<RenderData> clips; + auto flag = RenderUpdateFlag::None; + if (refresh || force) flag = RenderUpdateFlag::All; + + //Update single paint node + if (paint) { + //Optimize Me: Can we skip the searching? + for (auto paint2 = paints.data; paint2 < (paints.data + paints.count); ++paint2) { + if ((*paint2) == paint) { + paint->pImpl->update(*renderer, nullptr, 255, clips, flag); + return Result::Success; + } + } + return Result::InvalidArguments; + //Update all retained paint nodes + } else { + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + (*paint)->pImpl->update(*renderer, nullptr, 255, clips, flag); + } + } + + refresh = false; + + return Result::Success; + } + + Result draw() + { + if (drawing || paints.count == 0 || !renderer || !renderer->preRender()) return Result::InsufficientCondition; + + bool rendered = false; + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + if ((*paint)->pImpl->render(*renderer)) rendered = true; + } + + if (!rendered || !renderer->postRender()) return Result::InsufficientCondition; + + drawing = true; + + return Result::Success; + } + + Result sync() + { + if (!drawing) return Result::InsufficientCondition; + + if (renderer->sync()) { + drawing = false; + return Result::Success; + } + + return Result::InsufficientCondition; + } +}; + +#endif /* _TVG_CANVAS_IMPL_H_ */ diff --git a/thirdparty/thorvg/src/lib/tvgCommon.h b/thirdparty/thorvg/src/lib/tvgCommon.h new file mode 100644 index 0000000000..b1c586188c --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgCommon.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_COMMON_H_ +#define _TVG_COMMON_H_ + +#include "config.h" +#include "thorvg.h" + +using namespace std; +using namespace tvg; + +//for MSVC Compat +#ifdef _MSC_VER + #define TVG_UNUSED + #define strncasecmp _strnicmp + #define strcasecmp _stricmp +#else + #define TVG_UNUSED __attribute__ ((__unused__)) +#endif + +// Portable 'fallthrough' attribute +#if __has_cpp_attribute(fallthrough) + #ifdef _MSC_VER + #define TVG_FALLTHROUGH [[fallthrough]]; + #else + #define TVG_FALLTHROUGH __attribute__ ((fallthrough)); + #endif +#else + #define TVG_FALLTHROUGH +#endif + +#if defined(_MSC_VER) && defined(__clang__) + #define strncpy strncpy_s + #define strdup _strdup +#endif + +//TVG class identifier values +#define TVG_CLASS_ID_UNDEFINED 0 +#define TVG_CLASS_ID_SHAPE 1 +#define TVG_CLASS_ID_SCENE 2 +#define TVG_CLASS_ID_PICTURE 3 +#define TVG_CLASS_ID_LINEAR 4 +#define TVG_CLASS_ID_RADIAL 5 + +enum class FileType { Tvg = 0, Svg, Raw, Png, Jpg, Unknown }; + +#ifdef THORVG_LOG_ENABLED + #define TVGLOG(tag, fmt, ...) fprintf(stdout, tag ": " fmt "\n", ##__VA_ARGS__) //Log Message for notifying user some useful info + #define TVGERR(tag, fmt, ...) fprintf(stderr, tag ": " fmt "\n", ##__VA_ARGS__) //Error Message for us to fix it +#else + #define TVGERR(...) + #define TVGLOG(...) +#endif + +uint16_t THORVG_VERSION_NUMBER(); + +#endif //_TVG_COMMON_H_ diff --git a/thirdparty/thorvg/src/lib/tvgFill.cpp b/thirdparty/thorvg/src/lib/tvgFill.cpp new file mode 100644 index 0000000000..4bfb93c102 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgFill.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "tvgFill.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Fill::Fill():pImpl(new Impl()) +{ +} + + +Fill::~Fill() +{ + delete(pImpl); +} + + +Result Fill::colorStops(const ColorStop* colorStops, uint32_t cnt) noexcept +{ + if ((!colorStops && cnt > 0) || (colorStops && cnt == 0)) return Result::InvalidArguments; + + if (cnt == 0) { + if (pImpl->colorStops) { + free(pImpl->colorStops); + pImpl->colorStops = nullptr; + pImpl->cnt = 0; + } + return Result::Success; + } + + if (pImpl->cnt != cnt) { + pImpl->colorStops = static_cast<ColorStop*>(realloc(pImpl->colorStops, cnt * sizeof(ColorStop))); + } + + pImpl->cnt = cnt; + memcpy(pImpl->colorStops, colorStops, cnt * sizeof(ColorStop)); + + return Result::Success; +} + + +uint32_t Fill::colorStops(const ColorStop** colorStops) const noexcept +{ + if (colorStops) *colorStops = pImpl->colorStops; + + return pImpl->cnt; +} + + +Result Fill::spread(FillSpread s) noexcept +{ + pImpl->spread = s; + + return Result::Success; +} + + +FillSpread Fill::spread() const noexcept +{ + return pImpl->spread; +} + + +Result Fill::transform(const Matrix& m) noexcept +{ + if (!pImpl->transform) { + pImpl->transform = static_cast<Matrix*>(malloc(sizeof(Matrix))); + } + *pImpl->transform = m; + return Result::Success; +} + + +Matrix Fill::transform() const noexcept +{ + if (pImpl->transform) return *pImpl->transform; + return {1, 0, 0, 0, 1, 0, 0, 0, 1}; +} + + +Fill* Fill::duplicate() const noexcept +{ + return pImpl->duplicate(); +} + +uint32_t Fill::identifier() const noexcept +{ + return pImpl->id; +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/tvgFill.h b/thirdparty/thorvg/src/lib/tvgFill.h new file mode 100644 index 0000000000..912091f8cb --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgFill.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_FILL_H_ +#define _TVG_FILL_H_ + +#include <cstdlib> +#include <cstring> +#include "tvgCommon.h" + +template<typename T> +struct DuplicateMethod +{ + virtual ~DuplicateMethod() {} + virtual T* duplicate() = 0; +}; + +template<class T> +struct FillDup : DuplicateMethod<Fill> +{ + T* inst = nullptr; + + FillDup(T* _inst) : inst(_inst) {} + ~FillDup() {} + + Fill* duplicate() override + { + return inst->duplicate(); + } +}; + +struct Fill::Impl +{ + ColorStop* colorStops = nullptr; + Matrix* transform = nullptr; + uint32_t cnt = 0; + FillSpread spread; + DuplicateMethod<Fill>* dup = nullptr; + uint32_t id; + + ~Impl() + { + if (dup) delete(dup); + free(colorStops); + free(transform); + } + + void method(DuplicateMethod<Fill>* dup) + { + this->dup = dup; + } + + Fill* duplicate() + { + auto ret = dup->duplicate(); + if (!ret) return nullptr; + + ret->pImpl->cnt = cnt; + ret->pImpl->spread = spread; + ret->pImpl->colorStops = static_cast<ColorStop*>(malloc(sizeof(ColorStop) * cnt)); + memcpy(ret->pImpl->colorStops, colorStops, sizeof(ColorStop) * cnt); + if (transform) { + ret->pImpl->transform = static_cast<Matrix*>(malloc(sizeof(Matrix))); + *ret->pImpl->transform = *transform; + } + return ret; + } +}; + +#endif //_TVG_FILL_H_ diff --git a/thirdparty/thorvg/src/lib/tvgGlCanvas.cpp b/thirdparty/thorvg/src/lib/tvgGlCanvas.cpp new file mode 100644 index 0000000000..3a88b6d799 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgGlCanvas.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "tvgCanvasImpl.h" + +#ifdef THORVG_GL_RASTER_SUPPORT + #include "tvgGlRenderer.h" +#else + class GlRenderer : public RenderMethod + { + //Non Supported. Dummy Class */ + }; +#endif + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct GlCanvas::Impl +{ +}; + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +#ifdef THORVG_GL_RASTER_SUPPORT +GlCanvas::GlCanvas() : Canvas(GlRenderer::gen()), pImpl(new Impl) +#else +GlCanvas::GlCanvas() : Canvas(nullptr), pImpl(new Impl) +#endif +{ +} + + + +GlCanvas::~GlCanvas() +{ + delete(pImpl); +} + + +Result GlCanvas::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h) noexcept +{ +#ifdef THORVG_GL_RASTER_SUPPORT + //We know renderer type, avoid dynamic_cast for performance. + auto renderer = static_cast<GlRenderer*>(Canvas::pImpl->renderer); + if (!renderer) return Result::MemoryCorruption; + + if (!renderer->target(buffer, stride, w, h)) return Result::Unknown; + + //Paints must be updated again with this new target. + Canvas::pImpl->needRefresh(); + + return Result::Success; +#endif + return Result::NonSupport; +} + + +unique_ptr<GlCanvas> GlCanvas::gen() noexcept +{ +#ifdef THORVG_GL_RASTER_SUPPORT + if (GlRenderer::init() <= 0) return nullptr; + return unique_ptr<GlCanvas>(new GlCanvas); +#endif + return nullptr; +} diff --git a/thirdparty/thorvg/src/lib/tvgInitializer.cpp b/thirdparty/thorvg/src/lib/tvgInitializer.cpp new file mode 100644 index 0000000000..83ec50be95 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgInitializer.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "tvgCommon.h" +#include "tvgTaskScheduler.h" +#include "tvgLoader.h" + +#ifdef _WIN32 + #include <cstring> +#endif + +#ifdef THORVG_SW_RASTER_SUPPORT + #include "tvgSwRenderer.h" +#endif + +#ifdef THORVG_GL_RASTER_SUPPORT + #include "tvgGlRenderer.h" +#endif + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static int _initCnt = 0; +static uint16_t _version = 0; + + +static bool _buildVersionInfo() +{ + auto SRC = THORVG_VERSION_STRING; //ex) 0.3.99 + auto p = SRC; + const char* x; + + char major[3]; + x = strchr(p, '.'); + if (!x) return false; + memcpy(major, p, x - p); + major[x - p] = '\0'; + p = x + 1; + + char minor[3]; + x = strchr(p, '.'); + if (!x) return false; + memcpy(minor, p, x - p); + minor[x - p] = '\0'; + p = x + 1; + + char micro[3]; + x = SRC + strlen(THORVG_VERSION_STRING); + memcpy(micro, p, x - p); + micro[x - p] = '\0'; + + char sum[7]; + snprintf(sum, sizeof(sum), "%s%s%s", major, minor, micro); + + _version = atoi(sum); + + return true; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Result Initializer::init(CanvasEngine engine, uint32_t threads) noexcept +{ + auto nonSupport = true; + + if (static_cast<uint32_t>(engine) & static_cast<uint32_t>(CanvasEngine::Sw)) { + #ifdef THORVG_SW_RASTER_SUPPORT + if (!SwRenderer::init(threads)) return Result::FailedAllocation; + nonSupport = false; + #endif + } else if (static_cast<uint32_t>(engine) & static_cast<uint32_t>(CanvasEngine::Gl)) { + #ifdef THORVG_GL_RASTER_SUPPORT + if (!GlRenderer::init(threads)) return Result::FailedAllocation; + nonSupport = false; + #endif + } else { + return Result::InvalidArguments; + } + + if (nonSupport) return Result::NonSupport; + + if (_initCnt++ > 0) return Result::Success; + + if (!_buildVersionInfo()) return Result::Unknown; + + if (!LoaderMgr::init()) return Result::Unknown; + + TaskScheduler::init(threads); + + return Result::Success; +} + + +Result Initializer::term(CanvasEngine engine) noexcept +{ + if (_initCnt == 0) return Result::InsufficientCondition; + + auto nonSupport = true; + + if (static_cast<uint32_t>(engine) & static_cast<uint32_t>(CanvasEngine::Sw)) { + #ifdef THORVG_SW_RASTER_SUPPORT + if (!SwRenderer::term()) return Result::InsufficientCondition; + nonSupport = false; + #endif + } else if (static_cast<uint32_t>(engine) & static_cast<uint32_t>(CanvasEngine::Gl)) { + #ifdef THORVG_GL_RASTER_SUPPORT + if (!GlRenderer::term()) return Result::InsufficientCondition; + nonSupport = false; + #endif + } else { + return Result::InvalidArguments; + } + + if (nonSupport) return Result::NonSupport; + + if (--_initCnt > 0) return Result::Success; + + TaskScheduler::term(); + + if (!LoaderMgr::term()) return Result::Unknown; + + return Result::Success; +} + + +uint16_t THORVG_VERSION_NUMBER() +{ + return _version; +} diff --git a/thirdparty/thorvg/src/lib/tvgIteratorAccessor.h b/thirdparty/thorvg/src/lib/tvgIteratorAccessor.h new file mode 100644 index 0000000000..10b55a536d --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgIteratorAccessor.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_ITERATOR_ACCESSOR_H_ +#define _TVG_ITERATOR_ACCESSOR_H_ + +#include "tvgPaint.h" + +namespace tvg +{ + +class IteratorAccessor +{ +public: + //Utility Method: Iterator Accessor + Iterator* iterator(const Paint* paint) + { + return paint->pImpl->iterator(); + } +}; + +} + +#endif //_TVG_ITERATOR_ACCESSOR_H_ diff --git a/thirdparty/thorvg/src/lib/tvgLinearGradient.cpp b/thirdparty/thorvg/src/lib/tvgLinearGradient.cpp new file mode 100644 index 0000000000..6ec7ddab20 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgLinearGradient.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include <float.h> +#include <math.h> +#include "tvgFill.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct LinearGradient::Impl +{ + float x1 = 0; + float y1 = 0; + float x2 = 0; + float y2 = 0; + + Fill* duplicate() + { + auto ret = LinearGradient::gen(); + if (!ret) return nullptr; + + ret->pImpl->x1 = x1; + ret->pImpl->y1 = y1; + ret->pImpl->x2 = x2; + ret->pImpl->y2 = y2; + + return ret.release(); + } +}; + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +LinearGradient::LinearGradient():pImpl(new Impl()) +{ + Fill::pImpl->id = TVG_CLASS_ID_LINEAR; + Fill::pImpl->method(new FillDup<LinearGradient::Impl>(pImpl)); +} + + +LinearGradient::~LinearGradient() +{ + delete(pImpl); +} + + +Result LinearGradient::linear(float x1, float y1, float x2, float y2) noexcept +{ + pImpl->x1 = x1; + pImpl->y1 = y1; + pImpl->x2 = x2; + pImpl->y2 = y2; + + return Result::Success; +} + + +Result LinearGradient::linear(float* x1, float* y1, float* x2, float* y2) const noexcept +{ + if (x1) *x1 = pImpl->x1; + if (x2) *x2 = pImpl->x2; + if (y1) *y1 = pImpl->y1; + if (y2) *y2 = pImpl->y2; + + return Result::Success; +} + + +unique_ptr<LinearGradient> LinearGradient::gen() noexcept +{ + return unique_ptr<LinearGradient>(new LinearGradient); +} + + +uint32_t LinearGradient::identifier() noexcept +{ + return TVG_CLASS_ID_LINEAR; +} diff --git a/thirdparty/thorvg/src/lib/tvgLoadModule.h b/thirdparty/thorvg/src/lib/tvgLoadModule.h new file mode 100644 index 0000000000..0c34ecbf6a --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgLoadModule.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_LOAD_MODULE_H_ +#define _TVG_LOAD_MODULE_H_ + +#include "tvgRender.h" + +namespace tvg +{ + +class LoadModule +{ +public: + //default view box, if any. + float vx = 0; + float vy = 0; + float vw = 0; + float vh = 0; + float w = 0, h = 0; //default image size + bool preserveAspect = true; //keep aspect ratio by default. + + virtual ~LoadModule() {} + + virtual bool open(const string& path) { return false; } + virtual bool open(const char* data, uint32_t size, bool copy) { return false; } + virtual bool open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) { return false; } + + //Override this if the vector-format has own resizing policy. + virtual bool resize(Paint* paint, float w, float h) { return false; } + + virtual bool read() = 0; + virtual bool close() = 0; + virtual unique_ptr<Surface> bitmap() { return nullptr; } + virtual unique_ptr<Paint> paint() { return nullptr; } +}; + +} + +#endif //_TVG_LOAD_MODULE_H_ diff --git a/thirdparty/thorvg/src/lib/tvgLoader.cpp b/thirdparty/thorvg/src/lib/tvgLoader.cpp new file mode 100644 index 0000000000..fb93e0faec --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgLoader.cpp @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "tvgLoader.h" + +#ifdef THORVG_SVG_LOADER_SUPPORT + #include "tvgSvgLoader.h" +#endif + +#ifdef THORVG_PNG_LOADER_SUPPORT + #include "tvgPngLoader.h" +#endif + +#ifdef THORVG_TVG_LOADER_SUPPORT + #include "tvgTvgLoader.h" +#endif + +#ifdef THORVG_JPG_LOADER_SUPPORT + #include "tvgJpgLoader.h" +#endif + +#include "tvgRawLoader.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static LoadModule* _find(FileType type) +{ + switch(type) { + case FileType::Tvg: { +#ifdef THORVG_TVG_LOADER_SUPPORT + return new TvgLoader; +#endif + break; + } + case FileType::Svg: { +#ifdef THORVG_SVG_LOADER_SUPPORT + return new SvgLoader; +#endif + break; + } + case FileType::Raw: { + return new RawLoader; + break; + } + case FileType::Png: { +#ifdef THORVG_PNG_LOADER_SUPPORT + return new PngLoader; +#endif + break; + } + case FileType::Jpg: { +#ifdef THORVG_JPG_LOADER_SUPPORT + return new JpgLoader; +#endif + break; + } + default: { + break; + } + } + +#ifdef THORVG_LOG_ENABLED + const char *format; + switch(type) { + case FileType::Tvg: { + format = "TVG"; + break; + } + case FileType::Svg: { + format = "SVG"; + break; + } + case FileType::Raw: { + format = "RAW"; + break; + } + case FileType::Png: { + format = "PNG"; + break; + } + case FileType::Jpg: { + format = "JPG"; + break; + } + default: { + format = "???"; + break; + } + } + TVGLOG("LOADER", "%s format is not supported", format); +#endif + return nullptr; +} + + +static LoadModule* _findByPath(const string& path) +{ + auto ext = path.substr(path.find_last_of(".") + 1); + if (!ext.compare("tvg")) return _find(FileType::Tvg); + if (!ext.compare("svg")) return _find(FileType::Svg); + if (!ext.compare("png")) return _find(FileType::Png); + if (!ext.compare("jpg")) return _find(FileType::Jpg); + return nullptr; +} + + +static LoadModule* _findByType(const string& mimeType) +{ + if (mimeType.empty()) return nullptr; + + auto type = FileType::Unknown; + + if (mimeType == "tvg") type = FileType::Tvg; + else if (mimeType == "svg" || mimeType == "svg+xml") type = FileType::Svg; + else if (mimeType == "raw") type = FileType::Raw; + else if (mimeType == "png") type = FileType::Png; + else if (mimeType == "jpg" || mimeType == "jpeg") type = FileType::Jpg; + else { + TVGLOG("LOADER", "Given mimetype is unknown = \"%s\".", mimeType.c_str()); + return nullptr; + } + + return _find(type); +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + + +bool LoaderMgr::init() +{ + //TODO: + + return true; +} + + +bool LoaderMgr::term() +{ + //TODO: + + return true; +} + + +shared_ptr<LoadModule> LoaderMgr::loader(const string& path, bool* invalid) +{ + *invalid = false; + + if (auto loader = _findByPath(path)) { + if (loader->open(path)) return shared_ptr<LoadModule>(loader); + else delete(loader); + *invalid = true; + } + return nullptr; +} + + +shared_ptr<LoadModule> LoaderMgr::loader(const char* data, uint32_t size, const string& mimeType, bool copy) +{ + //Try first with the given MimeType + if (auto loader = _findByType(mimeType)) { + if (loader->open(data, size, copy)) { + return shared_ptr<LoadModule>(loader); + } else { + TVGLOG("LOADER", "Given mimetype \"%s\" seems incorrect or not supported. Will try again with other types.", mimeType.c_str()); + delete(loader); + } + } + + //Abnormal MimeType. Try with the candidates in the order + for (int i = 0; i < static_cast<int>(FileType::Unknown); i++) { + auto loader = _find(static_cast<FileType>(i)); + if (loader) { + if (loader->open(data, size, copy)) return shared_ptr<LoadModule>(loader); + else delete(loader); + } + } + return nullptr; +} + + +shared_ptr<LoadModule> LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy) +{ + //function is dedicated for raw images only + auto loader = new RawLoader; + if (loader->open(data, w, h, copy)) return shared_ptr<LoadModule>(loader); + else delete(loader); + + return nullptr; +} diff --git a/thirdparty/thorvg/src/lib/tvgLoader.h b/thirdparty/thorvg/src/lib/tvgLoader.h new file mode 100644 index 0000000000..8ba3c139fa --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgLoader.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_LOADER_H_ +#define _TVG_LOADER_H_ + +#include "tvgLoadModule.h" + +struct LoaderMgr +{ + static bool init(); + static bool term(); + static shared_ptr<LoadModule> loader(const string& path, bool* invalid); + static shared_ptr<LoadModule> loader(const char* data, uint32_t size, const string& mimeType, bool copy); + static shared_ptr<LoadModule> loader(const uint32_t* data, uint32_t w, uint32_t h, bool copy); +}; + +#endif //_TVG_LOADER_H_ diff --git a/thirdparty/thorvg/src/lib/tvgLzw.cpp b/thirdparty/thorvg/src/lib/tvgLzw.cpp new file mode 100644 index 0000000000..0049c89962 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgLzw.cpp @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Lempel–Ziv–Welch (LZW) encoder/decoder by Guilherme R. Lampert(guilherme.ronaldo.lampert@gmail.com) + + * This is the compression scheme used by the GIF image format and the Unix 'compress' tool. + * Main differences from this implementation is that End Of Input (EOI) and Clear Codes (CC) + * are not stored in the output and the max code length in bits is 12, vs 16 in compress. + * + * EOI is simply detected by the end of the data stream, while CC happens if the + * dictionary gets filled. Data is written/read from bit streams, which handle + * byte-alignment for us in a transparent way. + + * The decoder relies on the hardcoded data layout produced by the encoder, since + * no additional reconstruction data is added to the output, so they must match. + * The nice thing about LZW is that we can reconstruct the dictionary directly from + * the stream of codes generated by the encoder, so this avoids storing additional + * headers in the bit stream. + + * The output code length is variable. It starts with the minimum number of bits + * required to store the base byte-sized dictionary and automatically increases + * as the dictionary gets larger (it starts at 9-bits and grows to 10-bits when + * code 512 is added, then 11-bits when 1024 is added, and so on). If the dictionary + * is filled (4096 items for a 12-bits dictionary), the whole thing is cleared and + * the process starts over. This is the main reason why the encoder and the decoder + * must match perfectly, since the lengths of the codes will not be specified with + * the data itself. + + * USEFUL LINKS: + * https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Welch + * http://rosettacode.org/wiki/LZW_compression + * http://www.cs.duke.edu/csed/curious/compression/lzw.html + * http://www.cs.cf.ac.uk/Dave/Multimedia/node214.html + * http://marknelson.us/1989/10/01/lzw-data-compression/ + */ +#include "config.h" + +#if defined(THORVG_TVG_SAVER_SUPPORT) || defined(THORVG_TVG_LOADER_SUPPORT) + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +#include <string> +#include <memory.h> +#include "tvgLzw.h" + +namespace { +//LZW Dictionary helper: +constexpr int Nil = -1; +constexpr int MaxDictBits = 12; +constexpr int StartBits = 9; +constexpr int FirstCode = (1 << (StartBits - 1)); // 256 +constexpr int MaxDictEntries = (1 << MaxDictBits); // 4096 + + +//Round up to the next power-of-two number, e.g. 37 => 64 +static int nextPowerOfTwo(int num) +{ + --num; + for (size_t i = 1; i < sizeof(num) * 8; i <<= 1) { + num = num | num >> i; + } + return ++num; +} + + +struct BitStreamWriter +{ + uint8_t* stream; //Growable buffer to store our bits. Heap allocated & owned by the class instance. + int bytesAllocated; //Current size of heap-allocated stream buffer *in bytes*. + int granularity; //Amount bytesAllocated multiplies by when auto-resizing in appendBit(). + int currBytePos; //Current byte being written to, from 0 to bytesAllocated-1. + int nextBitPos; //Bit position within the current byte to access next. 0 to 7. + int numBitsWritten; //Number of bits in use from the stream buffer, not including byte-rounding padding. + + void internalInit() + { + stream = nullptr; + bytesAllocated = 0; + granularity = 2; + currBytePos = 0; + nextBitPos = 0; + numBitsWritten = 0; + } + + uint8_t* allocBytes(const int bytesWanted, uint8_t * oldPtr, const int oldSize) + { + auto newMemory = static_cast<uint8_t *>(malloc(bytesWanted)); + memset(newMemory, 0, bytesWanted); + + if (oldPtr) { + memcpy(newMemory, oldPtr, oldSize); + free(oldPtr); + } + return newMemory; + } + + BitStreamWriter() + { + /* 8192 bits for a start (1024 bytes). It will resize if needed. + Default granularity is 2. */ + internalInit(); + allocate(8192); + } + + BitStreamWriter(const int initialSizeInBits, const int growthGranularity = 2) + { + internalInit(); + setGranularity(growthGranularity); + allocate(initialSizeInBits); + } + + ~BitStreamWriter() + { + free(stream); + } + + void allocate(int bitsWanted) + { + //Require at least a byte. + if (bitsWanted <= 0) bitsWanted = 8; + + //Round upwards if needed: + if ((bitsWanted % 8) != 0) bitsWanted = nextPowerOfTwo(bitsWanted); + + //We might already have the required count. + const int sizeInBytes = bitsWanted / 8; + if (sizeInBytes <= bytesAllocated) return; + + stream = allocBytes(sizeInBytes, stream, bytesAllocated); + bytesAllocated = sizeInBytes; + } + + void appendBit(const int bit) + { + const uint32_t mask = uint32_t(1) << nextBitPos; + stream[currBytePos] = (stream[currBytePos] & ~mask) | (-bit & mask); + ++numBitsWritten; + + if (++nextBitPos == 8) { + nextBitPos = 0; + if (++currBytePos == bytesAllocated) allocate(bytesAllocated * granularity * 8); + } + } + + void appendBitsU64(const uint64_t num, const int bitCount) + { + for (int b = 0; b < bitCount; ++b) { + const uint64_t mask = uint64_t(1) << b; + const int bit = !!(num & mask); + appendBit(bit); + } + } + + uint8_t* release() + { + auto oldPtr = stream; + internalInit(); + return oldPtr; + } + + void setGranularity(const int growthGranularity) + { + granularity = (growthGranularity >= 2) ? growthGranularity : 2; + } + + int getByteCount() const + { + int usedBytes = numBitsWritten / 8; + int leftovers = numBitsWritten % 8; + if (leftovers != 0) ++usedBytes; + return usedBytes; + } +}; + + +struct BitStreamReader +{ + const uint8_t* stream; // Pointer to the external bit stream. Not owned by the reader. + const int sizeInBytes; // Size of the stream *in bytes*. Might include padding. + const int sizeInBits; // Size of the stream *in bits*, padding *not* include. + int currBytePos = 0; // Current byte being read in the stream. + int nextBitPos = 0; // Bit position within the current byte to access next. 0 to 7. + int numBitsRead = 0; // Total bits read from the stream so far. Never includes byte-rounding padding. + + BitStreamReader(const uint8_t* bitStream, const int byteCount, const int bitCount) : stream(bitStream), sizeInBytes(byteCount), sizeInBits(bitCount) + { + } + + bool readNextBit(int& bitOut) + { + if (numBitsRead >= sizeInBits) return false; //We are done. + + const uint32_t mask = uint32_t(1) << nextBitPos; + bitOut = !!(stream[currBytePos] & mask); + ++numBitsRead; + + if (++nextBitPos == 8) { + nextBitPos = 0; + ++currBytePos; + } + return true; + } + + uint64_t readBitsU64(const int bitCount) + { + uint64_t num = 0; + for (int b = 0; b < bitCount; ++b) { + int bit; + if (!readNextBit(bit)) break; + /* Based on a "Stanford bit-hack": + http://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching */ + const uint64_t mask = uint64_t(1) << b; + num = (num & ~mask) | (-bit & mask); + } + return num; + } + + bool isEndOfStream() const + { + return numBitsRead >= sizeInBits; + } +}; + + +struct Dictionary +{ + struct Entry + { + int code; + int value; + }; + + //Dictionary entries 0-255 are always reserved to the byte/ASCII range. + int size; + Entry entries[MaxDictEntries]; + + Dictionary() + { + /* First 256 dictionary entries are reserved to the byte/ASCII range. + Additional entries follow for the character sequences found in the input. + Up to 4096 - 256 (MaxDictEntries - FirstCode). */ + size = FirstCode; + + for (int i = 0; i < size; ++i) { + entries[i].code = Nil; + entries[i].value = i; + } + } + + int findIndex(const int code, const int value) const + { + if (code == Nil) return value; + + //Linear search for now. + //TODO: Worth optimizing with a proper hash-table? + for (int i = 0; i < size; ++i) { + if (entries[i].code == code && entries[i].value == value) return i; + } + return Nil; + } + + bool add(const int code, const int value) + { + if (size == MaxDictEntries) return false; + entries[size].code = code; + entries[size].value = value; + ++size; + return true; + } + + bool flush(int & codeBitsWidth) + { + if (size == (1 << codeBitsWidth)) { + ++codeBitsWidth; + if (codeBitsWidth > MaxDictBits) { + //Clear the dictionary (except the first 256 byte entries). + codeBitsWidth = StartBits; + size = FirstCode; + return true; + } + } + return false; + } +}; + + +static bool outputByte(int code, uint8_t*& output, int outputSizeBytes, int& bytesDecodedSoFar) +{ + if (bytesDecodedSoFar >= outputSizeBytes) return false; + *output++ = static_cast<uint8_t>(code); + ++bytesDecodedSoFar; + return true; +} + + +static bool outputSequence(const Dictionary& dict, int code, uint8_t*& output, int outputSizeBytes, int& bytesDecodedSoFar, int& firstByte) +{ + /* A sequence is stored backwards, so we have to write + it to a temp then output the buffer in reverse. */ + int i = 0; + uint8_t sequence[MaxDictEntries]; + + do { + sequence[i++] = dict.entries[code].value; + code = dict.entries[code].code; + } while (code >= 0); + + firstByte = sequence[--i]; + + for (; i >= 0; --i) { + if (!outputByte(sequence[i], output, outputSizeBytes, bytesDecodedSoFar)) return false; + } + return true; +} +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +namespace tvg { + +uint8_t* lzwDecode(const uint8_t* compressed, uint32_t compressedSizeBytes, uint32_t compressedSizeBits, uint32_t uncompressedSizeBytes) +{ + int code = Nil; + int prevCode = Nil; + int firstByte = 0; + int bytesDecoded = 0; + int codeBitsWidth = StartBits; + auto uncompressed = (uint8_t*) malloc(sizeof(uint8_t) * uncompressedSizeBytes); + auto ptr = uncompressed; + + /* We'll reconstruct the dictionary based on the bit stream codes. + Unlike Huffman encoding, we don't store the dictionary as a prefix to the data. */ + Dictionary dictionary; + BitStreamReader bitStream(compressed, compressedSizeBytes, compressedSizeBits); + + /* We check to avoid an overflow of the user buffer. + If the buffer is smaller than the decompressed size, we break the loop and return the current decompression count. */ + while (!bitStream.isEndOfStream()) { + code = static_cast<int>(bitStream.readBitsU64(codeBitsWidth)); + + if (prevCode == Nil) { + if (!outputByte(code, ptr, uncompressedSizeBytes, bytesDecoded)) break; + firstByte = code; + prevCode = code; + continue; + } + if (code >= dictionary.size) { + if (!outputSequence(dictionary, prevCode, ptr, uncompressedSizeBytes, bytesDecoded, firstByte)) break; + if (!outputByte(firstByte, ptr, uncompressedSizeBytes, bytesDecoded)) break; + } else if (!outputSequence(dictionary, code, ptr, uncompressedSizeBytes, bytesDecoded, firstByte)) break; + + dictionary.add(prevCode, firstByte); + if (dictionary.flush(codeBitsWidth)) prevCode = Nil; + else prevCode = code; + } + + return uncompressed; +} + + +uint8_t* lzwEncode(const uint8_t* uncompressed, uint32_t uncompressedSizeBytes, uint32_t* compressedSizeBytes, uint32_t* compressedSizeBits) +{ + //LZW encoding context: + int code = Nil; + int codeBitsWidth = StartBits; + Dictionary dictionary; + + //Output bit stream we write to. This will allocate memory as needed to accommodate the encoded data. + BitStreamWriter bitStream; + + for (; uncompressedSizeBytes > 0; --uncompressedSizeBytes, ++uncompressed) { + const int value = *uncompressed; + const int index = dictionary.findIndex(code, value); + + if (index != Nil) { + code = index; + continue; + } + + //Write the dictionary code using the minimum bit-with: + bitStream.appendBitsU64(code, codeBitsWidth); + + //Flush it when full so we can restart the sequences. + if (!dictionary.flush(codeBitsWidth)) { + //There's still space for this sequence. + dictionary.add(code, value); + } + code = value; + } + + //Residual code at the end: + if (code != Nil) bitStream.appendBitsU64(code, codeBitsWidth); + + //Pass ownership of the compressed data buffer to the user pointer: + *compressedSizeBytes = bitStream.getByteCount(); + *compressedSizeBits = bitStream.numBitsWritten; + + return bitStream.release(); +} + +} + +#endif diff --git a/thirdparty/thorvg/src/lib/tvgLzw.h b/thirdparty/thorvg/src/lib/tvgLzw.h new file mode 100644 index 0000000000..3fdb439a02 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgLzw.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_LZW_H_ +#define _TVG_LZW_H_ + +namespace tvg +{ + uint8_t* lzwEncode(const uint8_t* uncompressed, uint32_t uncompressedSizeBytes, uint32_t* compressedSizeBytes, uint32_t* compressedSizeBits); + uint8_t* lzwDecode(const uint8_t* compressed, uint32_t compressedSizeBytes, uint32_t compressedSizeBits, uint32_t uncompressedSizeBytes); +} + +#endif //_TVG_LZW_H
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/tvgMath.h b/thirdparty/thorvg/src/lib/tvgMath.h new file mode 100644 index 0000000000..9e5c915fc3 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgMath.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_MATH_H_ +#define _TVG_MATH_H_ + + #define _USE_MATH_DEFINES + +#include <float.h> +#include <math.h> +#include "tvgCommon.h" + + +static inline bool mathZero(float a) +{ + return (fabsf(a) < FLT_EPSILON) ? true : false; +} + + +static inline bool mathEqual(float a, float b) +{ + return (fabsf(a - b) < FLT_EPSILON); +} + + +static inline bool mathRightAngle(const Matrix* m) +{ + auto radian = fabsf(atan2(m->e21, m->e11)); + if (radian < FLT_EPSILON || mathEqual(radian, float(M_PI_2)) || mathEqual(radian, float(M_PI))) return true; + return false; +} + + +static inline bool mathIdentity(const Matrix* m) +{ + if (!mathEqual(m->e11, 1.0f) || !mathZero(m->e12) || !mathZero(m->e13) || + !mathZero(m->e21) || !mathEqual(m->e22, 1.0f) || !mathZero(m->e23) || + !mathZero(m->e31) || !mathZero(m->e32) || !mathEqual(m->e33, 1.0f)) { + return false; + } + return true; +} + + +static inline bool mathInverse(const Matrix* m, Matrix* out) +{ + auto det = m->e11 * (m->e22 * m->e33 - m->e32 * m->e23) - + m->e12 * (m->e21 * m->e33 - m->e23 * m->e31) + + m->e13 * (m->e21 * m->e32 - m->e22 * m->e31); + + if (mathZero(det)) return false; + + auto invDet = 1 / det; + + out->e11 = (m->e22 * m->e33 - m->e32 * m->e23) * invDet; + out->e12 = (m->e13 * m->e32 - m->e12 * m->e33) * invDet; + out->e13 = (m->e12 * m->e23 - m->e13 * m->e22) * invDet; + out->e21 = (m->e23 * m->e31 - m->e21 * m->e33) * invDet; + out->e22 = (m->e11 * m->e33 - m->e13 * m->e31) * invDet; + out->e23 = (m->e21 * m->e13 - m->e11 * m->e23) * invDet; + out->e31 = (m->e21 * m->e32 - m->e31 * m->e22) * invDet; + out->e32 = (m->e31 * m->e12 - m->e11 * m->e32) * invDet; + out->e33 = (m->e11 * m->e22 - m->e21 * m->e12) * invDet; + + return true; +} + + +static inline void mathIdentity(Matrix* m) +{ + m->e11 = 1.0f; + m->e12 = 0.0f; + m->e13 = 0.0f; + m->e21 = 0.0f; + m->e22 = 1.0f; + m->e23 = 0.0f; + m->e31 = 0.0f; + m->e32 = 0.0f; + m->e33 = 1.0f; +} + + +static inline void mathScale(Matrix* m, float scale) +{ + m->e11 = scale; + m->e22 = scale; +} + + +static inline void mathTranslate(Matrix* m, float x, float y) +{ + m->e13 = x; + m->e23 = y; +} + + +static inline void mathRotate(Matrix* m, float degree) +{ + auto radian = degree / 180.0f * M_PI; + auto cosVal = cosf(radian); + auto sinVal = sinf(radian); + + m->e12 = m->e11 * -sinVal; + m->e11 *= cosVal; + m->e21 = m->e22 * sinVal; + m->e22 *= cosVal; +} + + +static inline void mathMultiply(Point* pt, const Matrix* transform) +{ + auto tx = pt->x * transform->e11 + pt->y * transform->e12 + transform->e13; + auto ty = pt->x * transform->e21 + pt->y * transform->e22 + transform->e23; + pt->x = tx; + pt->y = ty; +} + + +static inline Matrix mathMultiply(const Matrix* lhs, const Matrix* rhs) +{ + Matrix m; + + m.e11 = lhs->e11 * rhs->e11 + lhs->e12 * rhs->e21 + lhs->e13 * rhs->e31; + m.e12 = lhs->e11 * rhs->e12 + lhs->e12 * rhs->e22 + lhs->e13 * rhs->e32; + m.e13 = lhs->e11 * rhs->e13 + lhs->e12 * rhs->e23 + lhs->e13 * rhs->e33; + + m.e21 = lhs->e21 * rhs->e11 + lhs->e22 * rhs->e21 + lhs->e23 * rhs->e31; + m.e22 = lhs->e21 * rhs->e12 + lhs->e22 * rhs->e22 + lhs->e23 * rhs->e32; + m.e23 = lhs->e21 * rhs->e13 + lhs->e22 * rhs->e23 + lhs->e23 * rhs->e33; + + m.e31 = lhs->e31 * rhs->e11 + lhs->e32 * rhs->e21 + lhs->e33 * rhs->e31; + m.e32 = lhs->e31 * rhs->e12 + lhs->e32 * rhs->e22 + lhs->e33 * rhs->e32; + m.e33 = lhs->e31 * rhs->e13 + lhs->e32 * rhs->e23 + lhs->e33 * rhs->e33; + + return m; +} + + +#endif //_TVG_MATH_H_
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/tvgPaint.cpp b/thirdparty/thorvg/src/lib/tvgPaint.cpp new file mode 100644 index 0000000000..30e82fbc60 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgPaint.cpp @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "tvgMath.h" +#include "tvgPaint.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + + +static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, RenderTransform* rTransform, RenderRegion& viewport) +{ + /* Access Shape class by Paint is bad... but it's ok still it's an internal usage. */ + auto shape = static_cast<Shape*>(cmpTarget); + + //Rectangle Candidates? + const Point* pts; + if (shape->pathCoords(&pts) != 4) return false; + + if (rTransform) rTransform->update(); + + //No rotational. + if (pTransform && !mathRightAngle(&pTransform->m)) return false; + if (rTransform && !mathRightAngle(&rTransform->m)) return false; + + //Perpendicular Rectangle? + auto pt1 = pts + 0; + auto pt2 = pts + 1; + auto pt3 = pts + 2; + auto pt4 = pts + 3; + + if ((mathEqual(pt1->x, pt2->x) && mathEqual(pt2->y, pt3->y) && mathEqual(pt3->x, pt4->x) && mathEqual(pt1->y, pt4->y)) || + (mathEqual(pt2->x, pt3->x) && mathEqual(pt1->y, pt2->y) && mathEqual(pt1->x, pt4->x) && mathEqual(pt3->y, pt4->y))) { + + auto v1 = *pt1; + auto v2 = *pt3; + + if (rTransform) { + mathMultiply(&v1, &rTransform->m); + mathMultiply(&v2, &rTransform->m); + } + + if (pTransform) { + mathMultiply(&v1, &pTransform->m); + mathMultiply(&v2, &pTransform->m); + } + + //sorting + if (v1.x > v2.x) { + auto tmp = v2.x; + v2.x = v1.x; + v1.x = tmp; + } + + if (v1.y > v2.y) { + auto tmp = v2.y; + v2.y = v1.y; + v1.y = tmp; + } + + viewport.x = static_cast<int32_t>(v1.x); + viewport.y = static_cast<int32_t>(v1.y); + viewport.w = static_cast<int32_t>(v2.x - v1.x + 0.5f); + viewport.h = static_cast<int32_t>(v2.y - v1.y + 0.5f); + + if (viewport.w < 0) viewport.w = 0; + if (viewport.h < 0) viewport.h = 0; + + return true; + } + + return false; +} + + +Paint* Paint::Impl::duplicate() +{ + auto ret = smethod->duplicate(); + + //duplicate Transform + if (rTransform) { + ret->pImpl->rTransform = new RenderTransform(); + *ret->pImpl->rTransform = *rTransform; + ret->pImpl->renderFlag |= RenderUpdateFlag::Transform; + } + + ret->pImpl->opacity = opacity; + + if (compData) ret->pImpl->composite(ret, compData->target->duplicate(), compData->method); + + return ret; +} + + +bool Paint::Impl::rotate(float degree) +{ + if (rTransform) { + if (mathEqual(degree, rTransform->degree)) return true; + } else { + if (mathZero(degree)) return true; + rTransform = new RenderTransform(); + } + rTransform->degree = degree; + if (!rTransform->overriding) renderFlag |= RenderUpdateFlag::Transform; + + return true; +} + + +bool Paint::Impl::scale(float factor) +{ + if (rTransform) { + if (mathEqual(factor, rTransform->scale)) return true; + } else { + if (mathZero(factor)) return true; + rTransform = new RenderTransform(); + } + rTransform->scale = factor; + if (!rTransform->overriding) renderFlag |= RenderUpdateFlag::Transform; + + return true; +} + + +bool Paint::Impl::translate(float x, float y) +{ + if (rTransform) { + if (mathEqual(x, rTransform->x) && mathEqual(y, rTransform->y)) return true; + } else { + if (mathZero(x) && mathZero(y)) return true; + rTransform = new RenderTransform(); + } + rTransform->x = x; + rTransform->y = y; + if (!rTransform->overriding) renderFlag |= RenderUpdateFlag::Transform; + + return true; +} + + +bool Paint::Impl::render(RenderMethod& renderer) +{ + Compositor* cmp = nullptr; + + //OPTIMIZE_ME: Can we replace the simple AlphaMasking with ClipPath? + + /* Note: only ClipPath is processed in update() step. + Create a composition image. */ + if (compData && compData->method != CompositeMethod::ClipPath && !(compData->target->pImpl->ctxFlag & ContextFlag::FastTrack)) { + auto region = smethod->bounds(renderer); + if (region.w == 0 || region.h == 0) return true; + cmp = renderer.target(region); + renderer.beginComposite(cmp, CompositeMethod::None, 255); + compData->target->pImpl->render(renderer); + } + + if (cmp) renderer.beginComposite(cmp, compData->method, compData->target->pImpl->opacity); + + auto ret = smethod->render(renderer); + + if (cmp) renderer.endComposite(cmp); + + return ret; +} + + +void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, uint32_t pFlag) +{ + if (renderFlag & RenderUpdateFlag::Transform) { + if (!rTransform) return nullptr; + if (!rTransform->update()) { + delete(rTransform); + rTransform = nullptr; + } + } + + /* 1. Composition Pre Processing */ + void *tdata = nullptr; + RenderRegion viewport; + bool compFastTrack = false; + + if (compData) { + auto target = compData->target; + auto method = compData->method; + target->pImpl->ctxFlag &= ~ContextFlag::FastTrack; //reset + + /* If transform has no rotation factors && ClipPath / AlphaMasking is a simple rectangle, + we can avoid regular ClipPath / AlphaMasking sequence but use viewport for performance */ + auto tryFastTrack = false; + if (method == CompositeMethod::ClipPath) tryFastTrack = true; + else if (method == CompositeMethod::AlphaMask && target->identifier() == TVG_CLASS_ID_SHAPE) { + auto shape = static_cast<Shape*>(target); + uint8_t a; + shape->fillColor(nullptr, nullptr, nullptr, &a); + if (a == 255 && shape->opacity() == 255 && !shape->fill()) tryFastTrack = true; + } + if (tryFastTrack) { + RenderRegion viewport2; + if ((compFastTrack = _compFastTrack(target, pTransform, target->pImpl->rTransform, viewport2))) { + viewport = renderer.viewport(); + viewport2.intersect(viewport); + renderer.viewport(viewport2); + target->pImpl->ctxFlag |= ContextFlag::FastTrack; + } + } + if (!compFastTrack) { + tdata = target->pImpl->update(renderer, pTransform, 255, clips, pFlag); + if (method == CompositeMethod::ClipPath) clips.push(tdata); + } + } + + /* 2. Main Update */ + void *edata = nullptr; + auto newFlag = static_cast<RenderUpdateFlag>(pFlag | renderFlag); + renderFlag = RenderUpdateFlag::None; + opacity = (opacity * this->opacity) / 255; + + if (rTransform && pTransform) { + RenderTransform outTransform(pTransform, rTransform); + edata = smethod->update(renderer, &outTransform, opacity, clips, newFlag); + } else { + auto outTransform = pTransform ? pTransform : rTransform; + edata = smethod->update(renderer, outTransform, opacity, clips, newFlag); + } + + /* 3. Composition Post Processing */ + if (compFastTrack) renderer.viewport(viewport); + else if (tdata && compData->method == CompositeMethod::ClipPath) clips.pop(); + + return edata; +} + + +bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transformed) +{ + Matrix* m = nullptr; + + //Case: No transformed, quick return! + if (!transformed || !(m = this->transform())) return smethod->bounds(x, y, w, h); + + //Case: Transformed + auto tx = 0.0f; + auto ty = 0.0f; + auto tw = 0.0f; + auto th = 0.0f; + + auto ret = smethod->bounds(&tx, &ty, &tw, &th); + + //Get vertices + Point pt[4] = {{tx, ty}, {tx + tw, ty}, {tx + tw, ty + th}, {tx, ty + th}}; + + //New bounding box + auto x1 = FLT_MAX; + auto y1 = FLT_MAX; + auto x2 = -FLT_MAX; + auto y2 = -FLT_MAX; + + //Compute the AABB after transformation + for (int i = 0; i < 4; i++) { + mathMultiply(&pt[i], m); + + if (pt[i].x < x1) x1 = pt[i].x; + if (pt[i].x > x2) x2 = pt[i].x; + if (pt[i].y < y1) y1 = pt[i].y; + if (pt[i].y > y2) y2 = pt[i].y; + } + + if (x) *x = x1; + if (y) *y = y1; + if (w) *w = x2 - x1; + if (h) *h = y2 - y1; + + return ret; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Paint :: Paint() : pImpl(new Impl()) +{ +} + + +Paint :: ~Paint() +{ + delete(pImpl); +} + + +Result Paint::rotate(float degree) noexcept +{ + if (pImpl->rotate(degree)) return Result::Success; + return Result::FailedAllocation; +} + + +Result Paint::scale(float factor) noexcept +{ + if (pImpl->scale(factor)) return Result::Success; + return Result::FailedAllocation; +} + + +Result Paint::translate(float x, float y) noexcept +{ + if (pImpl->translate(x, y)) return Result::Success; + return Result::FailedAllocation; +} + + +Result Paint::transform(const Matrix& m) noexcept +{ + if (pImpl->transform(m)) return Result::Success; + return Result::FailedAllocation; +} + + +Matrix Paint::transform() noexcept +{ + auto pTransform = pImpl->transform(); + if (pTransform) return *pTransform; + return {1, 0, 0, 0, 1, 0, 0, 0, 1}; +} + + +TVG_DEPRECATED Result Paint::bounds(float* x, float* y, float* w, float* h) const noexcept +{ + return this->bounds(x, y, w, h, false); +} + + +Result Paint::bounds(float* x, float* y, float* w, float* h, bool transform) const noexcept +{ + if (pImpl->bounds(x, y, w, h, transform)) return Result::Success; + return Result::InsufficientCondition; +} + + +Paint* Paint::duplicate() const noexcept +{ + return pImpl->duplicate(); +} + + +Result Paint::composite(std::unique_ptr<Paint> target, CompositeMethod method) noexcept +{ + auto p = target.release(); + if (pImpl->composite(this, p, method)) return Result::Success; + if (p) delete(p); + return Result::InvalidArguments; +} + + +CompositeMethod Paint::composite(const Paint** target) const noexcept +{ + if (pImpl->compData) { + if (target) *target = pImpl->compData->target; + return pImpl->compData->method; + } else { + if (target) *target = nullptr; + return CompositeMethod::None; + } +} + + +Result Paint::opacity(uint8_t o) noexcept +{ + if (pImpl->opacity == o) return Result::Success; + + pImpl->opacity = o; + pImpl->renderFlag |= RenderUpdateFlag::Color; + + return Result::Success; +} + + +uint8_t Paint::opacity() const noexcept +{ + return pImpl->opacity; +} + + +uint32_t Paint::identifier() const noexcept +{ + return pImpl->id; +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/tvgPaint.h b/thirdparty/thorvg/src/lib/tvgPaint.h new file mode 100644 index 0000000000..4003bdbeac --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgPaint.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_PAINT_H_ +#define _TVG_PAINT_H_ + +#include "tvgRender.h" + + +namespace tvg +{ + enum ContextFlag {Invalid = 0, FastTrack = 1}; + + struct Iterator + { + virtual ~Iterator() {} + virtual const Paint* next() = 0; + virtual uint32_t count() = 0; + virtual void begin() = 0; + }; + + struct StrategyMethod + { + virtual ~StrategyMethod() {} + + virtual bool dispose(RenderMethod& renderer) = 0; + virtual void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag) = 0; //Return engine data if it has. + virtual bool render(RenderMethod& renderer) = 0; + virtual bool bounds(float* x, float* y, float* w, float* h) = 0; + virtual RenderRegion bounds(RenderMethod& renderer) const = 0; + virtual Paint* duplicate() = 0; + virtual Iterator* iterator() = 0; + }; + + struct Composite + { + Paint* target; + Paint* source; + CompositeMethod method; + }; + + struct Paint::Impl + { + StrategyMethod* smethod = nullptr; + RenderTransform* rTransform = nullptr; + Composite* compData = nullptr; + uint32_t renderFlag = RenderUpdateFlag::None; + uint32_t ctxFlag = ContextFlag::Invalid; + uint32_t id; + uint8_t opacity = 255; + + ~Impl() + { + if (compData) { + delete(compData->target); + free(compData); + } + if (smethod) delete(smethod); + if (rTransform) delete(rTransform); + } + + void method(StrategyMethod* method) + { + smethod = method; + } + + bool transform(const Matrix& m) + { + if (!rTransform) { + rTransform = new RenderTransform(); + if (!rTransform) return false; + } + rTransform->override(m); + renderFlag |= RenderUpdateFlag::Transform; + + return true; + } + + Matrix* transform() + { + if (rTransform) { + rTransform->update(); + return &rTransform->m; + } + return nullptr; + } + + RenderRegion bounds(RenderMethod& renderer) const + { + return smethod->bounds(renderer); + } + + bool dispose(RenderMethod& renderer) + { + if (compData) compData->target->pImpl->dispose(renderer); + return smethod->dispose(renderer); + } + + Iterator* iterator() + { + return smethod->iterator(); + } + + bool composite(Paint* source, Paint* target, CompositeMethod method) + { + //Invalid case + if ((!target && method != CompositeMethod::None) || (target && method == CompositeMethod::None)) return false; + + if (compData) { + delete(compData->target); + //Reset scenario + if (!target && method == CompositeMethod::None) { + free(compData); + compData = nullptr; + return true; + } + } else { + if (!target && method == CompositeMethod::None) return true; + compData = static_cast<Composite*>(calloc(1, sizeof(Composite))); + } + compData->target = target; + compData->source = source; + compData->method = method; + return true; + } + + bool rotate(float degree); + bool scale(float factor); + bool translate(float x, float y); + bool bounds(float* x, float* y, float* w, float* h, bool transformed); + void* update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, uint32_t pFlag); + bool render(RenderMethod& renderer); + Paint* duplicate(); + }; + + + template<class T> + struct PaintMethod : StrategyMethod + { + T* inst = nullptr; + + PaintMethod(T* _inst) : inst(_inst) {} + ~PaintMethod() {} + + bool bounds(float* x, float* y, float* w, float* h) override + { + return inst->bounds(x, y, w, h); + } + + RenderRegion bounds(RenderMethod& renderer) const override + { + return inst->bounds(renderer); + } + + bool dispose(RenderMethod& renderer) override + { + return inst->dispose(renderer); + } + + void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag renderFlag) override + { + return inst->update(renderer, transform, opacity, clips, renderFlag); + } + + bool render(RenderMethod& renderer) override + { + return inst->render(renderer); + } + + Paint* duplicate() override + { + return inst->duplicate(); + } + + Iterator* iterator() override + { + return inst->iterator(); + } + }; +} + +#endif //_TVG_PAINT_H_ diff --git a/thirdparty/thorvg/src/lib/tvgPicture.cpp b/thirdparty/thorvg/src/lib/tvgPicture.cpp new file mode 100644 index 0000000000..1d9776363c --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgPicture.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "tvgPictureImpl.h" + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Picture::Picture() : pImpl(new Impl) +{ + Paint::pImpl->id = TVG_CLASS_ID_PICTURE; + Paint::pImpl->method(new PaintMethod<Picture::Impl>(pImpl)); +} + + +Picture::~Picture() +{ + delete(pImpl); +} + + +unique_ptr<Picture> Picture::gen() noexcept +{ + return unique_ptr<Picture>(new Picture); +} + + +uint32_t Picture::identifier() noexcept +{ + return TVG_CLASS_ID_PICTURE; +} + + +Result Picture::load(const std::string& path) noexcept +{ + if (path.empty()) return Result::InvalidArguments; + + return pImpl->load(path); +} + + +Result Picture::load(const char* data, uint32_t size, const string& mimeType, bool copy) noexcept +{ + if (!data || size <= 0) return Result::InvalidArguments; + + return pImpl->load(data, size, mimeType, copy); +} + + +TVG_DEPRECATED Result Picture::load(const char* data, uint32_t size, bool copy) noexcept +{ + return load(data, size, "", copy); +} + + +Result Picture::load(uint32_t* data, uint32_t w, uint32_t h, bool copy) noexcept +{ + if (!data || w <= 0 || h <= 0) return Result::InvalidArguments; + + return pImpl->load(data, w, h, copy); +} + + +Result Picture::viewbox(float* x, float* y, float* w, float* h) const noexcept +{ + if (pImpl->viewbox(x, y, w, h)) return Result::Success; + return Result::InsufficientCondition; +} + + +Result Picture::size(float w, float h) noexcept +{ + if (pImpl->size(w, h)) return Result::Success; + return Result::InsufficientCondition; +} + + +Result Picture::size(float* w, float* h) const noexcept +{ + if (!pImpl->loader) return Result::InsufficientCondition; + if (w) *w = pImpl->w; + if (h) *h = pImpl->h; + return Result::Success; +} + + +const uint32_t* Picture::data(uint32_t* w, uint32_t* h) const noexcept +{ + //Try it, If not loaded yet. + pImpl->reload(); + + if (pImpl->loader) { + if (w) *w = static_cast<uint32_t>(pImpl->loader->w); + if (h) *h = static_cast<uint32_t>(pImpl->loader->h); + } else { + if (w) *w = 0; + if (h) *h = 0; + } + if (pImpl->surface) return pImpl->surface->buffer; + else return nullptr; +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/tvgPictureImpl.h b/thirdparty/thorvg/src/lib/tvgPictureImpl.h new file mode 100644 index 0000000000..00e8aa6dd9 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgPictureImpl.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_PICTURE_IMPL_H_ +#define _TVG_PICTURE_IMPL_H_ + +#include <string> +#include "tvgPaint.h" +#include "tvgLoader.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct PictureIterator : Iterator +{ + Paint* paint = nullptr; + Paint* ptr = nullptr; + + PictureIterator(Paint* p) : paint(p) {} + + const Paint* next() override + { + if (!ptr) ptr = paint; + else ptr = nullptr; + return ptr; + } + + uint32_t count() override + { + if (paint) return 1; + else return 0; + } + + void begin() override + { + ptr = nullptr; + } +}; + + +struct Picture::Impl +{ + shared_ptr<LoadModule> loader = nullptr; + + Paint* paint = nullptr; //vector picture uses + Surface* surface = nullptr; //bitmap picture uses + void* rdata = nullptr; //engine data + float w = 0, h = 0; + bool resizing = false; + + ~Impl() + { + if (paint) delete(paint); + free(surface); + } + + bool dispose(RenderMethod& renderer) + { + bool ret = true; + if (paint) { + ret = paint->pImpl->dispose(renderer); + } else if (surface) { + ret = renderer.dispose(rdata); + rdata = nullptr; + } + return ret; + } + + uint32_t reload() + { + if (loader) { + if (!paint) { + if (auto p = loader->paint()) { + paint = p.release(); + loader->close(); + if (w != loader->w || h != loader->h) { + loader->resize(paint, w, h); + resizing = false; + } + if (paint) return RenderUpdateFlag::None; + } + } + free(surface); + if ((surface = loader->bitmap().release())) { + loader->close(); + return RenderUpdateFlag::Image; + } + } + return RenderUpdateFlag::None; + } + + RenderTransform resizeTransform(const RenderTransform* pTransform) + { + //Overriding Transformation by the desired image size + auto sx = w / loader->w; + auto sy = h / loader->h; + auto scale = sx < sy ? sx : sy; + + RenderTransform tmp; + tmp.m = {scale, 0, 0, 0, scale, 0, 0, 0, 1}; + + if (!pTransform) return tmp; + else return RenderTransform(pTransform, &tmp); + } + + void* update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag) + { + auto flag = reload(); + + if (surface) { + auto transform = resizeTransform(pTransform); + rdata = renderer.prepare(surface, rdata, &transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag)); + } else if (paint) { + if (resizing) { + loader->resize(paint, w, h); + resizing = false; + } + rdata = paint->pImpl->update(renderer, pTransform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag)); + } + return rdata; + } + + bool render(RenderMethod &renderer) + { + if (surface) return renderer.renderImage(rdata); + else if (paint) return paint->pImpl->render(renderer); + return false; + } + + bool viewbox(float* x, float* y, float* w, float* h) const + { + if (!loader) return false; + if (x) *x = loader->vx; + if (y) *y = loader->vy; + if (w) *w = loader->vw; + if (h) *h = loader->vh; + return true; + } + + bool size(float w, float h) + { + this->w = w; + this->h = h; + resizing = true; + return true; + } + + bool bounds(float* x, float* y, float* w, float* h) + { + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = this->w; + if (h) *h = this->h; + + return true; + } + + RenderRegion bounds(RenderMethod& renderer) + { + if (rdata) return renderer.region(rdata); + if (paint) return paint->pImpl->bounds(renderer); + return {0, 0, 0, 0}; + } + + Result load(const string& path) + { + if (paint || surface) return Result::InsufficientCondition; + if (loader) loader->close(); + bool invalid; //Invalid Path + loader = LoaderMgr::loader(path, &invalid); + if (!loader) { + if (invalid) return Result::InvalidArguments; + return Result::NonSupport; + } + if (!loader->read()) return Result::Unknown; + w = loader->w; + h = loader->h; + return Result::Success; + } + + Result load(const char* data, uint32_t size, const string& mimeType, bool copy) + { + if (paint || surface) return Result::InsufficientCondition; + if (loader) loader->close(); + loader = LoaderMgr::loader(data, size, mimeType, copy); + if (!loader) return Result::NonSupport; + if (!loader->read()) return Result::Unknown; + w = loader->w; + h = loader->h; + return Result::Success; + } + + Result load(uint32_t* data, uint32_t w, uint32_t h, bool copy) + { + if (paint || surface) return Result::InsufficientCondition; + if (loader) loader->close(); + loader = LoaderMgr::loader(data, w, h, copy); + if (!loader) return Result::NonSupport; + this->w = loader->w; + this->h = loader->h; + return Result::Success; + } + + Paint* duplicate() + { + reload(); + + auto ret = Picture::gen(); + + auto dup = ret.get()->pImpl; + if (paint) dup->paint = paint->duplicate(); + + dup->loader = loader; + if (surface) { + dup->surface = static_cast<Surface*>(malloc(sizeof(Surface))); + *dup->surface = *surface; + } + dup->w = w; + dup->h = h; + dup->resizing = resizing; + + return ret.release(); + } + + Iterator* iterator() + { + reload(); + return new PictureIterator(paint); + } +}; + +#endif //_TVG_PICTURE_IMPL_H_ diff --git a/thirdparty/thorvg/src/lib/tvgRadialGradient.cpp b/thirdparty/thorvg/src/lib/tvgRadialGradient.cpp new file mode 100644 index 0000000000..42a83461e3 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgRadialGradient.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include <float.h> +#include "tvgFill.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct RadialGradient::Impl +{ + float cx = 0; + float cy = 0; + float radius = 0; + + Fill* duplicate() + { + auto ret = RadialGradient::gen(); + if (!ret) return nullptr; + + ret->pImpl->cx = cx; + ret->pImpl->cy = cy; + ret->pImpl->radius = radius; + + return ret.release(); + } +}; + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +RadialGradient::RadialGradient():pImpl(new Impl()) +{ + Fill::pImpl->id = TVG_CLASS_ID_RADIAL; + Fill::pImpl->method(new FillDup<RadialGradient::Impl>(pImpl)); +} + + +RadialGradient::~RadialGradient() +{ + delete(pImpl); +} + + +Result RadialGradient::radial(float cx, float cy, float radius) noexcept +{ + if (radius < 0) return Result::InvalidArguments; + + pImpl->cx = cx; + pImpl->cy = cy; + pImpl->radius = radius; + + return Result::Success; +} + + +Result RadialGradient::radial(float* cx, float* cy, float* radius) const noexcept +{ + if (cx) *cx = pImpl->cx; + if (cy) *cy = pImpl->cy; + if (radius) *radius = pImpl->radius; + + return Result::Success; +} + + +unique_ptr<RadialGradient> RadialGradient::gen() noexcept +{ + return unique_ptr<RadialGradient>(new RadialGradient); +} + + +uint32_t RadialGradient::identifier() noexcept +{ + return TVG_CLASS_ID_RADIAL; +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/tvgRender.cpp b/thirdparty/thorvg/src/lib/tvgRender.cpp new file mode 100644 index 0000000000..a48075dd04 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgRender.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "tvgMath.h" +#include "tvgRender.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +void RenderTransform::override(const Matrix& m) +{ + this->m = m; + + if (m.e11 == 0.0f && m.e12 == 0.0f && m.e13 == 0.0f && + m.e21 == 0.0f && m.e22 == 0.0f && m.e23 == 0.0f && + m.e31 == 0.0f && m.e32 == 0.0f && m.e33 == 0.0f) { + overriding = false; + } else overriding = true; +} + + +bool RenderTransform::update() +{ + if (overriding) return true; + + //Init Status + if (mathZero(x) && mathZero(y) && mathZero(degree) && mathEqual(scale, 1)) return false; + + mathIdentity(&m); + + mathScale(&m, scale); + + if (!mathZero(degree)) mathRotate(&m, degree); + + mathTranslate(&m, x, y); + + return true; +} + + +RenderTransform::RenderTransform() +{ +} + + +RenderTransform::RenderTransform(const RenderTransform* lhs, const RenderTransform* rhs) +{ + m = mathMultiply(&lhs->m, &rhs->m); +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/tvgRender.h b/thirdparty/thorvg/src/lib/tvgRender.h new file mode 100644 index 0000000000..f927947aa6 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgRender.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_RENDER_H_ +#define _TVG_RENDER_H_ + +#include "tvgCommon.h" +#include "tvgArray.h" + +namespace tvg +{ + +enum RenderUpdateFlag {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, All = 255}; + +struct Surface +{ + //TODO: Union for multiple types + uint32_t* buffer; + uint32_t stride; + uint32_t w, h; + uint32_t cs; +}; + +using RenderData = void*; + +struct Compositor +{ + CompositeMethod method; + uint32_t opacity; +}; + +struct RenderRegion +{ + int32_t x, y, w, h; + + void intersect(const RenderRegion& rhs) + { + auto x1 = x + w; + auto y1 = y + h; + auto x2 = rhs.x + rhs.w; + auto y2 = rhs.y + rhs.h; + + x = (x > rhs.x) ? x : rhs.x; + y = (y > rhs.y) ? y : rhs.y; + w = ((x1 < x2) ? x1 : x2) - x; + h = ((y1 < y2) ? y1 : y2) - y; + + if (w < 0) w = 0; + if (h < 0) h = 0; + } +}; + +struct RenderTransform +{ + Matrix m; //3x3 Matrix Elements + float x = 0.0f; + float y = 0.0f; + float degree = 0.0f; //rotation degree + float scale = 1.0f; //scale factor + bool overriding = false; //user transform? + + bool update(); + void override(const Matrix& m); + + RenderTransform(); + RenderTransform(const RenderTransform* lhs, const RenderTransform* rhs); +}; + + +class RenderMethod +{ +public: + virtual ~RenderMethod() {} + virtual RenderData prepare(const Shape& shape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) = 0; + virtual RenderData prepare(Surface* image, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) = 0; + virtual bool preRender() = 0; + virtual bool renderShape(RenderData data) = 0; + virtual bool renderImage(RenderData data) = 0; + virtual bool postRender() = 0; + virtual bool dispose(RenderData data) = 0; + virtual RenderRegion region(RenderData data) = 0; + virtual RenderRegion viewport() = 0; + virtual bool viewport(const RenderRegion& vp) = 0; + + virtual bool clear() = 0; + virtual bool sync() = 0; + + virtual Compositor* target(const RenderRegion& region) = 0; + virtual bool beginComposite(Compositor* cmp, CompositeMethod method, uint32_t opacity) = 0; + virtual bool endComposite(Compositor* cmp) = 0; +}; + +} + +#endif //_TVG_RENDER_H_ diff --git a/thirdparty/thorvg/src/lib/tvgSaveModule.h b/thirdparty/thorvg/src/lib/tvgSaveModule.h new file mode 100644 index 0000000000..2a0f427f11 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgSaveModule.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_SAVE_MODULE_H_ +#define _TVG_SAVE_MODULE_H_ + +#include "tvgIteratorAccessor.h" + +namespace tvg +{ + +class SaveModule : public IteratorAccessor +{ +public: + virtual ~SaveModule() {} + + virtual bool save(Paint* paint, const string& path, bool compress) = 0; + virtual bool close() = 0; +}; + +} + +#endif //_TVG_SAVE_MODULE_H_ diff --git a/thirdparty/thorvg/src/lib/tvgSaver.cpp b/thirdparty/thorvg/src/lib/tvgSaver.cpp new file mode 100644 index 0000000000..1a3e8614a6 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgSaver.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "tvgCommon.h" +#include "tvgSaveModule.h" + +#ifdef THORVG_TVG_SAVER_SUPPORT + #include "tvgTvgSaver.h" +#endif + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct Saver::Impl +{ + SaveModule* saveModule = nullptr; + ~Impl() + { + if (saveModule) delete(saveModule); + } +}; + + +static SaveModule* _find(FileType type) +{ + switch(type) { + case FileType::Tvg: { +#ifdef THORVG_TVG_SAVER_SUPPORT + return new TvgSaver; +#endif + break; + } + default: { + break; + } + } + +#ifdef THORVG_LOG_ENABLED + const char *format; + switch(type) { + case FileType::Tvg: { + format = "TVG"; + break; + } + default: { + format = "???"; + break; + } + } + TVGLOG("SAVER", "%s format is not supported", format); +#endif + return nullptr; +} + + +static SaveModule* _find(const string& path) +{ + auto ext = path.substr(path.find_last_of(".") + 1); + if (!ext.compare("tvg")) { + return _find(FileType::Tvg); + } + return nullptr; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Saver::Saver() : pImpl(new Impl()) +{ +} + + +Saver::~Saver() +{ + delete(pImpl); +} + + +Result Saver::save(std::unique_ptr<Paint> paint, const string& path, bool compress) noexcept +{ + auto p = paint.release(); + if (!p) return Result::MemoryCorruption; + + //Already on saving an other resource. + if (pImpl->saveModule) { + delete(p); + return Result::InsufficientCondition; + } + + if (auto saveModule = _find(path)) { + if (saveModule->save(p, path, compress)) { + pImpl->saveModule = saveModule; + return Result::Success; + } else { + delete(p); + delete(saveModule); + return Result::Unknown; + } + } + delete(p); + return Result::NonSupport; +} + + +Result Saver::sync() noexcept +{ + if (!pImpl->saveModule) return Result::InsufficientCondition; + pImpl->saveModule->close(); + delete(pImpl->saveModule); + pImpl->saveModule = nullptr; + + return Result::Success; +} + + +unique_ptr<Saver> Saver::gen() noexcept +{ + return unique_ptr<Saver>(new Saver); +} diff --git a/thirdparty/thorvg/src/lib/tvgScene.cpp b/thirdparty/thorvg/src/lib/tvgScene.cpp new file mode 100644 index 0000000000..4b2f77dde9 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgScene.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "tvgSceneImpl.h" + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Scene::Scene() : pImpl(new Impl()) +{ + Paint::pImpl->id = TVG_CLASS_ID_SCENE; + Paint::pImpl->method(new PaintMethod<Scene::Impl>(pImpl)); +} + + +Scene::~Scene() +{ + delete(pImpl); +} + + +unique_ptr<Scene> Scene::gen() noexcept +{ + return unique_ptr<Scene>(new Scene); +} + + +uint32_t Scene::identifier() noexcept +{ + return TVG_CLASS_ID_SCENE; +} + + +Result Scene::push(unique_ptr<Paint> paint) noexcept +{ + auto p = paint.release(); + if (!p) return Result::MemoryCorruption; + pImpl->paints.push(p); + + return Result::Success; +} + + +Result Scene::reserve(uint32_t size) noexcept +{ + if (!pImpl->paints.reserve(size)) return Result::FailedAllocation; + + return Result::Success; +} + + +Result Scene::clear(bool free) noexcept +{ + pImpl->clear(free); + + return Result::Success; +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/tvgSceneImpl.h b/thirdparty/thorvg/src/lib/tvgSceneImpl.h new file mode 100644 index 0000000000..de94a66e2f --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgSceneImpl.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_SCENE_IMPL_H_ +#define _TVG_SCENE_IMPL_H_ + +#include <float.h> +#include "tvgPaint.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct SceneIterator : Iterator +{ + Array<Paint*>* paints; + uint32_t idx = 0; + + SceneIterator(Array<Paint*>* p) : paints(p) + { + } + + const Paint* next() override + { + if (idx >= paints->count) return nullptr; + return paints->data[idx++]; + } + + uint32_t count() override + { + return paints->count; + } + + void begin() override + { + idx = 0; + } +}; + +struct Scene::Impl +{ + Array<Paint*> paints; + uint8_t opacity; //for composition + RenderMethod* renderer = nullptr; //keep it for explicit clear + + ~Impl() + { + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + delete(*paint); + } + } + + bool dispose(RenderMethod& renderer) + { + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + (*paint)->pImpl->dispose(renderer); + } + + this->renderer = nullptr; + + return true; + } + + bool needComposition(uint32_t opacity) + { + //Half translucent requires intermediate composition. + if (opacity == 255 || opacity == 0) return false; + + //If scene has several children or only scene, it may require composition. + if (paints.count > 1) return true; + if (paints.count == 1 && (*paints.data)->identifier() == TVG_CLASS_ID_SCENE) return true; + return false; + } + + void* update(RenderMethod &renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flag) + { + /* Overriding opacity value. If this scene is half-translucent, + It must do intermeidate composition with that opacity value. */ + this->opacity = static_cast<uint8_t>(opacity); + if (needComposition(opacity)) opacity = 255; + + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + (*paint)->pImpl->update(renderer, transform, opacity, clips, static_cast<uint32_t>(flag)); + } + + /* FXIME: it requires to return list of children engine data + This is necessary for scene composition */ + + this->renderer = &renderer; + + return nullptr; + } + + bool render(RenderMethod& renderer) + { + Compositor* cmp = nullptr; + + if (needComposition(opacity)) { + cmp = renderer.target(bounds(renderer)); + renderer.beginComposite(cmp, CompositeMethod::None, opacity); + } + + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + if (!(*paint)->pImpl->render(renderer)) return false; + } + + if (cmp) renderer.endComposite(cmp); + + return true; + } + + RenderRegion bounds(RenderMethod& renderer) const + { + if (paints.count == 0) return {0, 0, 0, 0}; + + int32_t x1 = INT32_MAX; + int32_t y1 = INT32_MAX; + int32_t x2 = 0; + int32_t y2 = 0; + + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + auto region = (*paint)->pImpl->bounds(renderer); + + //Merge regions + if (region.x < x1) x1 = region.x; + if (x2 < region.x + region.w) x2 = (region.x + region.w); + if (region.y < y1) y1 = region.y; + if (y2 < region.y + region.h) y2 = (region.y + region.h); + } + + return {x1, y1, (x2 - x1), (y2 - y1)}; + } + + bool bounds(float* px, float* py, float* pw, float* ph) + { + if (paints.count == 0) return false; + + auto x1 = FLT_MAX; + auto y1 = FLT_MAX; + auto x2 = -FLT_MAX; + auto y2 = -FLT_MAX; + + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + auto x = FLT_MAX; + auto y = FLT_MAX; + auto w = 0.0f; + auto h = 0.0f; + + if ((*paint)->bounds(&x, &y, &w, &h, true) != tvg::Result::Success) continue; + + //Merge regions + if (x < x1) x1 = x; + if (x2 < x + w) x2 = (x + w); + if (y < y1) y1 = y; + if (y2 < y + h) y2 = (y + h); + } + + if (px) *px = x1; + if (py) *py = y1; + if (pw) *pw = (x2 - x1); + if (ph) *ph = (y2 - y1); + + return true; + } + + Paint* duplicate() + { + auto ret = Scene::gen(); + + auto dup = ret.get()->pImpl; + + dup->paints.reserve(paints.count); + + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + dup->paints.push((*paint)->duplicate()); + } + + return ret.release(); + } + + void clear(bool free) + { + auto dispose = renderer ? true : false; + + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + if (dispose) (*paint)->pImpl->dispose(*renderer); + if (free) delete(*paint); + } + paints.clear(); + renderer = nullptr; + } + + Iterator* iterator() + { + return new SceneIterator(&paints); + } +}; + +#endif //_TVG_SCENE_IMPL_H_ diff --git a/thirdparty/thorvg/src/lib/tvgShape.cpp b/thirdparty/thorvg/src/lib/tvgShape.cpp new file mode 100644 index 0000000000..8db5635932 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgShape.cpp @@ -0,0 +1,427 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "tvgMath.h" +#include "tvgShapeImpl.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ +constexpr auto PATH_KAPPA = 0.552284f; + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Shape :: Shape() : pImpl(new Impl(this)) +{ + Paint::pImpl->id = TVG_CLASS_ID_SHAPE; + Paint::pImpl->method(new PaintMethod<Shape::Impl>(pImpl)); +} + + +Shape :: ~Shape() +{ + delete(pImpl); +} + + +unique_ptr<Shape> Shape::gen() noexcept +{ + return unique_ptr<Shape>(new Shape); +} + + +uint32_t Shape::identifier() noexcept +{ + return TVG_CLASS_ID_SHAPE; +} + + +Result Shape::reset() noexcept +{ + pImpl->path.reset(); + pImpl->flag = RenderUpdateFlag::Path; + + return Result::Success; +} + + +uint32_t Shape::pathCommands(const PathCommand** cmds) const noexcept +{ + if (!cmds) return 0; + + *cmds = pImpl->path.cmds; + + return pImpl->path.cmdCnt; +} + + +uint32_t Shape::pathCoords(const Point** pts) const noexcept +{ + if (!pts) return 0; + + *pts = pImpl->path.pts; + + return pImpl->path.ptsCnt; +} + + +Result Shape::appendPath(const PathCommand *cmds, uint32_t cmdCnt, const Point* pts, uint32_t ptsCnt) noexcept +{ + if (cmdCnt == 0 || ptsCnt == 0 || !cmds || !pts) return Result::InvalidArguments; + + pImpl->path.grow(cmdCnt, ptsCnt); + pImpl->path.append(cmds, cmdCnt, pts, ptsCnt); + + pImpl->flag |= RenderUpdateFlag::Path; + + return Result::Success; +} + + +Result Shape::moveTo(float x, float y) noexcept +{ + pImpl->path.moveTo(x, y); + + pImpl->flag |= RenderUpdateFlag::Path; + + return Result::Success; +} + + +Result Shape::lineTo(float x, float y) noexcept +{ + pImpl->path.lineTo(x, y); + + pImpl->flag |= RenderUpdateFlag::Path; + + return Result::Success; +} + + +Result Shape::cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) noexcept +{ + pImpl->path.cubicTo(cx1, cy1, cx2, cy2, x, y); + + pImpl->flag |= RenderUpdateFlag::Path; + + return Result::Success; +} + + +Result Shape::close() noexcept +{ + pImpl->path.close(); + + pImpl->flag |= RenderUpdateFlag::Path; + + return Result::Success; +} + + +Result Shape::appendCircle(float cx, float cy, float rx, float ry) noexcept +{ + auto rxKappa = rx * PATH_KAPPA; + auto ryKappa = ry * PATH_KAPPA; + + pImpl->path.grow(6, 13); + pImpl->path.moveTo(cx, cy - ry); + pImpl->path.cubicTo(cx + rxKappa, cy - ry, cx + rx, cy - ryKappa, cx + rx, cy); + pImpl->path.cubicTo(cx + rx, cy + ryKappa, cx + rxKappa, cy + ry, cx, cy + ry); + pImpl->path.cubicTo(cx - rxKappa, cy + ry, cx - rx, cy + ryKappa, cx - rx, cy); + pImpl->path.cubicTo(cx - rx, cy - ryKappa, cx - rxKappa, cy - ry, cx, cy - ry); + pImpl->path.close(); + + pImpl->flag |= RenderUpdateFlag::Path; + + return Result::Success; +} + +Result Shape::appendArc(float cx, float cy, float radius, float startAngle, float sweep, bool pie) noexcept +{ + //just circle + if (sweep >= 360.0f || sweep <= -360.0f) return appendCircle(cx, cy, radius, radius); + + startAngle = (startAngle * M_PI) / 180.0f; + sweep = sweep * M_PI / 180.0f; + + auto nCurves = ceil(fabsf(sweep / float(M_PI_2))); + auto sweepSign = (sweep < 0 ? -1 : 1); + auto fract = fmodf(sweep, float(M_PI_2)); + fract = (mathZero(fract)) ? float(M_PI_2) * sweepSign : fract; + + //Start from here + Point start = {radius * cosf(startAngle), radius * sinf(startAngle)}; + + if (pie) { + pImpl->path.moveTo(cx, cy); + pImpl->path.lineTo(start.x + cx, start.y + cy); + } else { + pImpl->path.moveTo(start.x + cx, start.y + cy); + } + + for (int i = 0; i < nCurves; ++i) { + auto endAngle = startAngle + ((i != nCurves - 1) ? float(M_PI_2) * sweepSign : fract); + Point end = {radius * cosf(endAngle), radius * sinf(endAngle)}; + + //variables needed to calculate bezier control points + + //get bezier control points using article: + //(http://itc.ktu.lt/index.php/ITC/article/view/11812/6479) + auto ax = start.x; + auto ay = start.y; + auto bx = end.x; + auto by = end.y; + auto q1 = ax * ax + ay * ay; + auto q2 = ax * bx + ay * by + q1; + auto k2 = (4.0f/3.0f) * ((sqrtf(2 * q1 * q2) - q2) / (ax * by - ay * bx)); + + start = end; //Next start point is the current end point + + end.x += cx; + end.y += cy; + + Point ctrl1 = {ax - k2 * ay + cx, ay + k2 * ax + cy}; + Point ctrl2 = {bx + k2 * by + cx, by - k2 * bx + cy}; + + pImpl->path.cubicTo(ctrl1.x, ctrl1.y, ctrl2.x, ctrl2.y, end.x, end.y); + + startAngle = endAngle; + } + + if (pie) pImpl->path.close(); + + pImpl->flag |= RenderUpdateFlag::Path; + + return Result::Success; +} + + +Result Shape::appendRect(float x, float y, float w, float h, float rx, float ry) noexcept +{ + auto halfW = w * 0.5f; + auto halfH = h * 0.5f; + + //clamping cornerRadius by minimum size + if (rx > halfW) rx = halfW; + if (ry > halfH) ry = halfH; + + //rectangle + if (rx == 0 && ry == 0) { + pImpl->path.grow(5, 4); + pImpl->path.moveTo(x, y); + pImpl->path.lineTo(x + w, y); + pImpl->path.lineTo(x + w, y + h); + pImpl->path.lineTo(x, y + h); + pImpl->path.close(); + //circle + } else if (mathEqual(rx, halfW) && mathEqual(ry, halfH)) { + return appendCircle(x + (w * 0.5f), y + (h * 0.5f), rx, ry); + } else { + auto hrx = rx * 0.5f; + auto hry = ry * 0.5f; + pImpl->path.grow(10, 17); + pImpl->path.moveTo(x + rx, y); + pImpl->path.lineTo(x + w - rx, y); + pImpl->path.cubicTo(x + w - rx + hrx, y, x + w, y + ry - hry, x + w, y + ry); + pImpl->path.lineTo(x + w, y + h - ry); + pImpl->path.cubicTo(x + w, y + h - ry + hry, x + w - rx + hrx, y + h, x + w - rx, y + h); + pImpl->path.lineTo(x + rx, y + h); + pImpl->path.cubicTo(x + rx - hrx, y + h, x, y + h - ry + hry, x, y + h - ry); + pImpl->path.lineTo(x, y + ry); + pImpl->path.cubicTo(x, y + ry - hry, x + rx - hrx, y, x + rx, y); + pImpl->path.close(); + } + + pImpl->flag |= RenderUpdateFlag::Path; + + return Result::Success; +} + + +Result Shape::fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept +{ + pImpl->color[0] = r; + pImpl->color[1] = g; + pImpl->color[2] = b; + pImpl->color[3] = a; + pImpl->flag |= RenderUpdateFlag::Color; + + if (pImpl->fill) { + delete(pImpl->fill); + pImpl->fill = nullptr; + pImpl->flag |= RenderUpdateFlag::Gradient; + } + + return Result::Success; +} + + +Result Shape::fill(unique_ptr<Fill> f) noexcept +{ + auto p = f.release(); + if (!p) return Result::MemoryCorruption; + + if (pImpl->fill && pImpl->fill != p) delete(pImpl->fill); + pImpl->fill = p; + pImpl->flag |= RenderUpdateFlag::Gradient; + + return Result::Success; +} + + +Result Shape::fillColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const noexcept +{ + if (r) *r = pImpl->color[0]; + if (g) *g = pImpl->color[1]; + if (b) *b = pImpl->color[2]; + if (a) *a = pImpl->color[3]; + + return Result::Success; +} + +const Fill* Shape::fill() const noexcept +{ + return pImpl->fill; +} + + +Result Shape::stroke(float width) noexcept +{ + if (!pImpl->strokeWidth(width)) return Result::FailedAllocation; + + return Result::Success; +} + + +float Shape::strokeWidth() const noexcept +{ + if (!pImpl->stroke) return 0; + return pImpl->stroke->width; +} + + +Result Shape::stroke(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept +{ + if (!pImpl->strokeColor(r, g, b, a)) return Result::FailedAllocation; + + return Result::Success; +} + + +Result Shape::strokeColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const noexcept +{ + if (!pImpl->stroke) return Result::InsufficientCondition; + + if (r) *r = pImpl->stroke->color[0]; + if (g) *g = pImpl->stroke->color[1]; + if (b) *b = pImpl->stroke->color[2]; + if (a) *a = pImpl->stroke->color[3]; + + return Result::Success; +} + + +Result Shape::stroke(unique_ptr<Fill> f) noexcept +{ + return pImpl->strokeFill(move(f)); +} + + +const Fill* Shape::strokeFill() const noexcept +{ + if (!pImpl->stroke) return nullptr; + + return pImpl->stroke->fill; +} + + +Result Shape::stroke(const float* dashPattern, uint32_t cnt) noexcept +{ + if ((cnt == 1) || (!dashPattern && cnt > 0) || (dashPattern && cnt == 0)) { + return Result::InvalidArguments; + } + + for (uint32_t i = 0; i < cnt; i++) + if (dashPattern[i] < FLT_EPSILON) return Result::InvalidArguments; + + if (!pImpl->strokeDash(dashPattern, cnt)) return Result::FailedAllocation; + + return Result::Success; +} + + +uint32_t Shape::strokeDash(const float** dashPattern) const noexcept +{ + if (!pImpl->stroke) return 0; + + if (dashPattern) *dashPattern = pImpl->stroke->dashPattern; + + return pImpl->stroke->dashCnt; +} + + +Result Shape::stroke(StrokeCap cap) noexcept +{ + if (!pImpl->strokeCap(cap)) return Result::FailedAllocation; + + return Result::Success; +} + + +Result Shape::stroke(StrokeJoin join) noexcept +{ + if (!pImpl->strokeJoin(join)) return Result::FailedAllocation; + + return Result::Success; +} + + +StrokeCap Shape::strokeCap() const noexcept +{ + if (!pImpl->stroke) return StrokeCap::Square; + + return pImpl->stroke->cap; +} + + +StrokeJoin Shape::strokeJoin() const noexcept +{ + if (!pImpl->stroke) return StrokeJoin::Bevel; + + return pImpl->stroke->join; +} + + +Result Shape::fill(FillRule r) noexcept +{ + pImpl->rule = r; + + return Result::Success; +} + + +FillRule Shape::fillRule() const noexcept +{ + return pImpl->rule; +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/tvgShapeImpl.h b/thirdparty/thorvg/src/lib/tvgShapeImpl.h new file mode 100644 index 0000000000..dcf4e6e954 --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgShapeImpl.h @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_SHAPE_IMPL_H_ +#define _TVG_SHAPE_IMPL_H_ + +#include <memory.h> +#include "tvgPaint.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct ShapeStroke +{ + float width; + uint8_t color[4]; + Fill *fill; + float* dashPattern; + uint32_t dashCnt; + StrokeCap cap; + StrokeJoin join; + + void copy(const ShapeStroke* src) + { + width = src->width; + dashCnt = src->dashCnt; + cap = src->cap; + join = src->join; + + memcpy(color, src->color, sizeof(color)); + if (dashCnt > 0) { + dashPattern = static_cast<float*>(malloc(sizeof(float) * dashCnt)); + memcpy(dashPattern, src->dashPattern, sizeof(float) * dashCnt); + } + if (src->fill) fill = src->fill->duplicate(); + } + + void clear() + { + if (dashPattern) free(dashPattern); + if (fill) delete(fill); + } +}; + + +struct ShapePath +{ + PathCommand* cmds = nullptr; + uint32_t cmdCnt = 0; + uint32_t reservedCmdCnt = 0; + + Point *pts = nullptr; + uint32_t ptsCnt = 0; + uint32_t reservedPtsCnt = 0; + + ~ShapePath() + { + if (cmds) free(cmds); + if (pts) free(pts); + } + + ShapePath() + { + } + + void duplicate(const ShapePath* src) + { + if (src->cmdCnt == 0 || src->ptsCnt == 0) return; + + cmdCnt = src->cmdCnt; + reservedCmdCnt = src->reservedCmdCnt; + ptsCnt = src->ptsCnt; + reservedPtsCnt = src->reservedPtsCnt; + + cmds = static_cast<PathCommand*>(malloc(sizeof(PathCommand) * reservedCmdCnt)); + if (!cmds) return; + memcpy(cmds, src->cmds, sizeof(PathCommand) * cmdCnt); + + pts = static_cast<Point*>(malloc(sizeof(Point) * reservedPtsCnt)); + if (!pts) { + free(cmds); + return; + } + memcpy(pts, src->pts, sizeof(Point) * ptsCnt); + } + + void reserveCmd(uint32_t cmdCnt) + { + if (cmdCnt <= reservedCmdCnt) return; + reservedCmdCnt = cmdCnt; + cmds = static_cast<PathCommand*>(realloc(cmds, sizeof(PathCommand) * reservedCmdCnt)); + } + + void reservePts(uint32_t ptsCnt) + { + if (ptsCnt <= reservedPtsCnt) return; + reservedPtsCnt = ptsCnt; + pts = static_cast<Point*>(realloc(pts, sizeof(Point) * reservedPtsCnt)); + } + + void grow(uint32_t cmdCnt, uint32_t ptsCnt) + { + reserveCmd(this->cmdCnt + cmdCnt); + reservePts(this->ptsCnt + ptsCnt); + } + + void reset() + { + cmdCnt = 0; + ptsCnt = 0; + } + + void append(const PathCommand* cmds, uint32_t cmdCnt, const Point* pts, uint32_t ptsCnt) + { + memcpy(this->cmds + this->cmdCnt, cmds, sizeof(PathCommand) * cmdCnt); + memcpy(this->pts + this->ptsCnt, pts, sizeof(Point) * ptsCnt); + this->cmdCnt += cmdCnt; + this->ptsCnt += ptsCnt; + } + + void moveTo(float x, float y) + { + if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2); + if (ptsCnt + 2 > reservedPtsCnt) reservePts((ptsCnt + 2) * 2); + + cmds[cmdCnt++] = PathCommand::MoveTo; + pts[ptsCnt++] = {x, y}; + } + + void lineTo(float x, float y) + { + if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2); + if (ptsCnt + 2 > reservedPtsCnt) reservePts((ptsCnt + 2) * 2); + + cmds[cmdCnt++] = PathCommand::LineTo; + pts[ptsCnt++] = {x, y}; + } + + void cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) + { + if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2); + if (ptsCnt + 3 > reservedPtsCnt) reservePts((ptsCnt + 3) * 2); + + cmds[cmdCnt++] = PathCommand::CubicTo; + pts[ptsCnt++] = {cx1, cy1}; + pts[ptsCnt++] = {cx2, cy2}; + pts[ptsCnt++] = {x, y}; + } + + void close() + { + if (cmdCnt > 0 && cmds[cmdCnt - 1] == PathCommand::Close) return; + + if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2); + cmds[cmdCnt++] = PathCommand::Close; + } + + bool bounds(float* x, float* y, float* w, float* h) const + { + if (ptsCnt == 0) return false; + + Point min = { pts[0].x, pts[0].y }; + Point max = { pts[0].x, pts[0].y }; + + for (uint32_t i = 1; i < ptsCnt; ++i) { + if (pts[i].x < min.x) min.x = pts[i].x; + if (pts[i].y < min.y) min.y = pts[i].y; + if (pts[i].x > max.x) max.x = pts[i].x; + if (pts[i].y > max.y) max.y = pts[i].y; + } + + if (x) *x = min.x; + if (y) *y = min.y; + if (w) *w = max.x - min.x; + if (h) *h = max.y - min.y; + + return true; + } +}; + + +struct Shape::Impl +{ + ShapePath path; + Fill *fill = nullptr; + ShapeStroke *stroke = nullptr; + uint8_t color[4] = {0, 0, 0, 0}; //r, g, b, a + FillRule rule = FillRule::Winding; + RenderData rdata = nullptr; //engine data + Shape *shape = nullptr; + uint32_t flag = RenderUpdateFlag::None; + + Impl(Shape* s) : shape(s) + { + } + + ~Impl() + { + if (fill) delete(fill); + if (stroke) { + stroke->clear(); + free (stroke); + } + } + + bool dispose(RenderMethod& renderer) + { + auto ret = renderer.dispose(rdata); + rdata = nullptr; + return ret; + } + + bool render(RenderMethod& renderer) + { + return renderer.renderShape(rdata); + } + + void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag) + { + this->rdata = renderer.prepare(*shape, this->rdata, transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag)); + flag = RenderUpdateFlag::None; + return this->rdata; + } + + RenderRegion bounds(RenderMethod& renderer) + { + return renderer.region(rdata); + } + + bool bounds(float* x, float* y, float* w, float* h) + { + auto ret = path.bounds(x, y, w, h); + + //Stroke feathering + if (stroke) { + if (x) *x -= stroke->width * 0.5f; + if (y) *y -= stroke->width * 0.5f; + if (w) *w += stroke->width; + if (h) *h += stroke->width; + } + return ret; + } + + bool strokeWidth(float width) + { + //TODO: Size Exception? + + if (!stroke) stroke = static_cast<ShapeStroke*>(calloc(sizeof(ShapeStroke), 1)); + stroke->width = width; + flag |= RenderUpdateFlag::Stroke; + + return true; + } + + bool strokeCap(StrokeCap cap) + { + if (!stroke) stroke = static_cast<ShapeStroke*>(calloc(sizeof(ShapeStroke), 1)); + stroke->cap = cap; + flag |= RenderUpdateFlag::Stroke; + + return true; + } + + bool strokeJoin(StrokeJoin join) + { + if (!stroke) stroke = static_cast<ShapeStroke*>(calloc(sizeof(ShapeStroke), 1)); + stroke->join = join; + flag |= RenderUpdateFlag::Stroke; + + return true; + } + + bool strokeColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a) + { + if (!stroke) stroke = static_cast<ShapeStroke*>(calloc(sizeof(ShapeStroke), 1)); + if (stroke->fill) { + delete(stroke->fill); + stroke->fill = nullptr; + flag |= RenderUpdateFlag::GradientStroke; + } + + stroke->color[0] = r; + stroke->color[1] = g; + stroke->color[2] = b; + stroke->color[3] = a; + + flag |= RenderUpdateFlag::Stroke; + + return true; + } + + Result strokeFill(unique_ptr<Fill> f) + { + auto p = f.release(); + if (!p) return Result::MemoryCorruption; + + if (!stroke) stroke = static_cast<ShapeStroke*>(calloc(sizeof(ShapeStroke), 1)); + if (stroke->fill && stroke->fill != p) delete(stroke->fill); + stroke->fill = p; + + flag |= RenderUpdateFlag::Stroke; + flag |= RenderUpdateFlag::GradientStroke; + + return Result::Success; + } + + bool strokeDash(const float* pattern, uint32_t cnt) + { + //Reset dash + if (!pattern && cnt == 0) { + free(stroke->dashPattern); + stroke->dashPattern = nullptr; + } else { + if (!stroke) stroke = static_cast<ShapeStroke*>(calloc(sizeof(ShapeStroke), 1)); + if (stroke->dashCnt != cnt) { + free(stroke->dashPattern); + stroke->dashPattern = nullptr; + } + if (!stroke->dashPattern) { + stroke->dashPattern = static_cast<float*>(malloc(sizeof(float) * cnt)); + if (!stroke->dashPattern) return false; + } + for (uint32_t i = 0; i < cnt; ++i) { + stroke->dashPattern[i] = pattern[i]; + } + } + stroke->dashCnt = cnt; + flag |= RenderUpdateFlag::Stroke; + + return true; + } + + Paint* duplicate() + { + auto ret = Shape::gen(); + + auto dup = ret.get()->pImpl; + dup->rule = rule; + + //Color + memcpy(dup->color, color, sizeof(color)); + dup->flag = RenderUpdateFlag::Color; + + //Path + dup->path.duplicate(&path); + dup->flag |= RenderUpdateFlag::Path; + + //Stroke + if (stroke) { + dup->stroke = static_cast<ShapeStroke*>(calloc(sizeof(ShapeStroke), 1)); + dup->stroke->copy(stroke); + dup->flag |= RenderUpdateFlag::Stroke; + + if (stroke->fill) + dup->flag |= RenderUpdateFlag::GradientStroke; + } + + //Fill + if (fill) { + dup->fill = fill->duplicate(); + dup->flag |= RenderUpdateFlag::Gradient; + } + + return ret.release(); + } + + Iterator* iterator() + { + return nullptr; + } +}; + +#endif //_TVG_SHAPE_IMPL_H_ diff --git a/thirdparty/thorvg/src/lib/tvgSwCanvas.cpp b/thirdparty/thorvg/src/lib/tvgSwCanvas.cpp new file mode 100644 index 0000000000..f7a03b819c --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgSwCanvas.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "tvgCanvasImpl.h" + +#ifdef THORVG_SW_RASTER_SUPPORT + #include "tvgSwRenderer.h" +#else + class SwRenderer : public RenderMethod + { + //Non Supported. Dummy Class */ + }; +#endif + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct SwCanvas::Impl +{ +}; + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +#ifdef THORVG_SW_RASTER_SUPPORT +SwCanvas::SwCanvas() : Canvas(SwRenderer::gen()), pImpl(new Impl) +#else +SwCanvas::SwCanvas() : Canvas(nullptr), pImpl(new Impl) +#endif +{ +} + + +SwCanvas::~SwCanvas() +{ + delete(pImpl); +} + + +Result SwCanvas::mempool(MempoolPolicy policy) noexcept +{ +#ifdef THORVG_SW_RASTER_SUPPORT + //We know renderer type, avoid dynamic_cast for performance. + auto renderer = static_cast<SwRenderer*>(Canvas::pImpl->renderer); + if (!renderer) return Result::MemoryCorruption; + + //It can't change the policy during the running. + if (Canvas::pImpl->paints.count > 0) return Result::InsufficientCondition; + + if (policy == MempoolPolicy::Individual) renderer->mempool(false); + else renderer->mempool(true); + + return Result::Success; +#endif + return Result::NonSupport; +} + + +Result SwCanvas::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, Colorspace cs) noexcept +{ +#ifdef THORVG_SW_RASTER_SUPPORT + //We know renderer type, avoid dynamic_cast for performance. + auto renderer = static_cast<SwRenderer*>(Canvas::pImpl->renderer); + if (!renderer) return Result::MemoryCorruption; + + if (!renderer->target(buffer, stride, w, h, cs)) return Result::InvalidArguments; + + //Paints must be updated again with this new target. + Canvas::pImpl->needRefresh(); + + return Result::Success; +#endif + return Result::NonSupport; +} + + +unique_ptr<SwCanvas> SwCanvas::gen() noexcept +{ +#ifdef THORVG_SW_RASTER_SUPPORT + if (SwRenderer::init() <= 0) return nullptr; + return unique_ptr<SwCanvas>(new SwCanvas); +#endif + return nullptr; +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/lib/tvgTaskScheduler.cpp b/thirdparty/thorvg/src/lib/tvgTaskScheduler.cpp new file mode 100644 index 0000000000..780127b87b --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgTaskScheduler.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include <deque> +#include <thread> +#include <vector> +#include <atomic> +#include <condition_variable> +#include "tvgTaskScheduler.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +namespace tvg { + +struct TaskQueue { + deque<Task*> taskDeque; + mutex mtx; + condition_variable ready; + bool done = false; + + bool tryPop(Task** task) + { + unique_lock<mutex> lock{mtx, try_to_lock}; + if (!lock || taskDeque.empty()) return false; + *task = taskDeque.front(); + taskDeque.pop_front(); + + return true; + } + + bool tryPush(Task* task) + { + { + unique_lock<mutex> lock{mtx, try_to_lock}; + if (!lock) return false; + taskDeque.push_back(task); + } + + ready.notify_one(); + + return true; + } + + void complete() + { + { + unique_lock<mutex> lock{mtx}; + done = true; + } + ready.notify_all(); + } + + bool pop(Task** task) + { + unique_lock<mutex> lock{mtx}; + + while (taskDeque.empty() && !done) { + ready.wait(lock); + } + + if (taskDeque.empty()) return false; + + *task = taskDeque.front(); + taskDeque.pop_front(); + + return true; + } + + void push(Task* task) + { + { + unique_lock<mutex> lock{mtx}; + taskDeque.push_back(task); + } + + ready.notify_one(); + } + +}; + + +class TaskSchedulerImpl +{ +public: + unsigned threadCnt; + vector<thread> threads; + vector<TaskQueue> taskQueues; + atomic<unsigned> idx{0}; + + TaskSchedulerImpl(unsigned threadCnt) : threadCnt(threadCnt), taskQueues(threadCnt) + { + for (unsigned i = 0; i < threadCnt; ++i) { + threads.emplace_back([&, i] { run(i); }); + } + } + + ~TaskSchedulerImpl() + { + for (auto& queue : taskQueues) queue.complete(); + for (auto& thread : threads) thread.join(); + } + + void run(unsigned i) + { + Task* task; + + //Thread Loop + while (true) { + auto success = false; + for (unsigned x = 0; x < threadCnt * 2; ++x) { + if (taskQueues[(i + x) % threadCnt].tryPop(&task)) { + success = true; + break; + } + } + + if (!success && !taskQueues[i].pop(&task)) break; + (*task)(i); + } + } + + void request(Task* task) + { + //Async + if (threadCnt > 0) { + task->prepare(); + auto i = idx++; + for (unsigned n = 0; n < threadCnt; ++n) { + if (taskQueues[(i + n) % threadCnt].tryPush(task)) return; + } + taskQueues[i % threadCnt].push(task); + //Sync + } else { + task->run(0); + } + } +}; + +} + +static TaskSchedulerImpl* inst = nullptr; + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +void TaskScheduler::init(unsigned threads) +{ + if (inst) return; + inst = new TaskSchedulerImpl(threads); +} + + +void TaskScheduler::term() +{ + if (!inst) return; + delete(inst); + inst = nullptr; +} + + +void TaskScheduler::request(Task* task) +{ + if (inst) inst->request(task); +} + + +unsigned TaskScheduler::threads() +{ + if (inst) return inst->threadCnt; + return 0; +} diff --git a/thirdparty/thorvg/src/lib/tvgTaskScheduler.h b/thirdparty/thorvg/src/lib/tvgTaskScheduler.h new file mode 100644 index 0000000000..f30bdf9a8f --- /dev/null +++ b/thirdparty/thorvg/src/lib/tvgTaskScheduler.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_TASK_SCHEDULER_H_ +#define _TVG_TASK_SCHEDULER_H_ + +#include <mutex> +#include <condition_variable> +#include "tvgCommon.h" + +namespace tvg +{ + +struct Task; + +struct TaskScheduler +{ + static unsigned threads(); + static void init(unsigned threads); + static void term(); + static void request(Task* task); +}; + +struct Task +{ +private: + mutex mtx; + condition_variable cv; + bool ready{true}; + bool pending{false}; + +public: + virtual ~Task() = default; + + void done() + { + if (!pending) return; + + unique_lock<mutex> lock(mtx); + while (!ready) cv.wait(lock); + pending = false; + } + +protected: + virtual void run(unsigned tid) = 0; + +private: + void operator()(unsigned tid) + { + run(tid); + + lock_guard<mutex> lock(mtx); + ready = true; + cv.notify_one(); + } + + void prepare() + { + ready = false; + pending = true; + } + + friend class TaskSchedulerImpl; +}; + + + +} + +#endif //_TVG_TASK_SCHEDULER_H_ diff --git a/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.cpp b/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.cpp new file mode 100644 index 0000000000..6f9416b69c --- /dev/null +++ b/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <memory.h> +#include <turbojpeg.h> +#include "tvgLoader.h" +#include "tvgJpgLoader.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +void JpgLoader::clear() +{ + if (freeData) free(data); + data = nullptr; + size = 0; + freeData = false; +} + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +JpgLoader::JpgLoader() +{ + jpegDecompressor = tjInitDecompress(); +} + + +JpgLoader::~JpgLoader() +{ + if (freeData) free(data); + tjDestroy(jpegDecompressor); + + //This image is shared with raster engine. + tjFree(image); +} + + +bool JpgLoader::open(const string& path) +{ + clear(); + + auto jpegFile = fopen(path.c_str(), "rb"); + if (!jpegFile) return false; + + auto ret = false; + + //determine size + if (fseek(jpegFile, 0, SEEK_END) < 0) goto finalize; + if (((size = ftell(jpegFile)) < 1)) goto finalize; + if (fseek(jpegFile, 0, SEEK_SET)) goto finalize; + + data = (unsigned char *) malloc(size); + if (!data) goto finalize; + + freeData = true; + + if (fread(data, size, 1, jpegFile) < 1) goto failure; + + int width, height, subSample, colorSpace; + if (tjDecompressHeader3(jpegDecompressor, data, size, &width, &height, &subSample, &colorSpace) < 0) { + TVGERR("JPG LOADER", "%s", tjGetErrorStr()); + goto failure; + } + + w = static_cast<float>(width); + h = static_cast<float>(height); + ret = true; + + goto finalize; + +failure: + clear(); + +finalize: + fclose(jpegFile); + return ret; +} + + +bool JpgLoader::open(const char* data, uint32_t size, bool copy) +{ + clear(); + + int width, height, subSample, colorSpace; + if (tjDecompressHeader3(jpegDecompressor, (unsigned char *) data, size, &width, &height, &subSample, &colorSpace) < 0) return false; + + if (copy) { + this->data = (unsigned char *) malloc(size); + if (!this->data) return false; + memcpy((unsigned char *)this->data, data, size); + freeData = true; + } else { + this->data = (unsigned char *) data; + freeData = false; + } + + w = static_cast<float>(width); + h = static_cast<float>(height); + this->size = size; + + return true; +} + + +bool JpgLoader::read() +{ + if (image) tjFree(image); + image = (unsigned char *)tjAlloc(static_cast<int>(w) * static_cast<int>(h) * tjPixelSize[TJPF_BGRX]); + if (!image) return false; + + //decompress jpg image + if (tjDecompress2(jpegDecompressor, data, size, image, static_cast<int>(w), 0, static_cast<int>(h), TJPF_BGRX, 0) < 0) { + TVGERR("JPG LOADER", "%s", tjGetErrorStr()); + tjFree(image); + image = nullptr; + return false; + } + + return true; +} + + +bool JpgLoader::close() +{ + clear(); + return true; +} + + +unique_ptr<Surface> JpgLoader::bitmap() +{ + if (!image) return nullptr; + + auto surface = static_cast<Surface*>(malloc(sizeof(Surface))); + surface->buffer = (uint32_t*)(image); + surface->stride = w; + surface->w = w; + surface->h = h; + surface->cs = SwCanvas::ARGB8888; + + return unique_ptr<Surface>(surface); +} diff --git a/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.h b/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.h new file mode 100644 index 0000000000..7d35e57d72 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_JPG_LOADER_H_ +#define _TVG_JPG_LOADER_H_ + +using tjhandle = void*; + +//TODO: Use Task? +class JpgLoader : public LoadModule +{ +public: + JpgLoader(); + ~JpgLoader(); + + using LoadModule::open; + bool open(const string& path) override; + bool open(const char* data, uint32_t size, bool copy) override; + bool read() override; + bool close() override; + + unique_ptr<Surface> bitmap() override; + +private: + void clear(); + + tjhandle jpegDecompressor; + unsigned char* data = nullptr; + unsigned char *image = nullptr; + unsigned long size = 0; + bool freeData = false; +}; + +#endif //_TVG_JPG_LOADER_H_ diff --git a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp new file mode 100644 index 0000000000..c3d281482a --- /dev/null +++ b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "tvgLoader.h" +#include "tvgPngLoader.h" + +static inline uint32_t PREMULTIPLY(uint32_t c) +{ + auto a = (c >> 24); + return (c & 0xff000000) + ((((c >> 8) & 0xff) * a) & 0xff00) + ((((c & 0x00ff00ff) * a) >> 8) & 0x00ff00ff); +} + + +static void _premultiply(uint32_t* data, uint32_t w, uint32_t h) +{ + auto buffer = data; + for (uint32_t y = 0; y < h; ++y, buffer += w) { + auto src = buffer; + for (uint32_t x = 0; x < w; ++x, ++src) { + *src = PREMULTIPLY(*src); + } + } +} + + +PngLoader::PngLoader() +{ + image = static_cast<png_imagep>(calloc(1, sizeof(png_image))); + image->version = PNG_IMAGE_VERSION; + image->opaque = NULL; +} + +PngLoader::~PngLoader() +{ + if (content) { + free((void*)content); + content = nullptr; + } + free(image); +} + +bool PngLoader::open(const string& path) +{ + image->opaque = NULL; + + if (!png_image_begin_read_from_file(image, path.c_str())) return false; + + w = (float)image->width; + h = (float)image->height; + + return true; +} + +bool PngLoader::open(const char* data, uint32_t size, bool copy) +{ + image->opaque = NULL; + + if (!png_image_begin_read_from_memory(image, data, size)) return false; + + w = (float)image->width; + h = (float)image->height; + + return true; +} + + +bool PngLoader::read() +{ + png_bytep buffer; + image->format = PNG_FORMAT_BGRA; + buffer = static_cast<png_bytep>(malloc(PNG_IMAGE_SIZE((*image)))); + if (!buffer) { + //out of memory, only time when libpng doesnt free its data + png_image_free(image); + return false; + } + if (!png_image_finish_read(image, NULL, buffer, 0, NULL)) return false; + content = reinterpret_cast<uint32_t*>(buffer); + + _premultiply(reinterpret_cast<uint32_t*>(buffer), image->width, image->height); + + return true; +} + +bool PngLoader::close() +{ + png_image_free(image); + return true; +} + +unique_ptr<Surface> PngLoader::bitmap() +{ + if (!content) return nullptr; + + auto surface = static_cast<Surface*>(malloc(sizeof(Surface))); + surface->buffer = (uint32_t*)(content); + surface->stride = w; + surface->w = w; + surface->h = h; + surface->cs = SwCanvas::ARGB8888; + + return unique_ptr<Surface>(surface); +} diff --git a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h new file mode 100644 index 0000000000..b42537c73f --- /dev/null +++ b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_PNG_LOADER_H_ +#define _TVG_PNG_LOADER_H_ + +#include <png.h> + +class PngLoader : public LoadModule +{ +public: + PngLoader(); + ~PngLoader(); + + using LoadModule::open; + bool open(const string& path) override; + bool open(const char* data, uint32_t size, bool copy) override; + bool read() override; + bool close() override; + + unique_ptr<Surface> bitmap() override; + +private: + png_imagep image = nullptr; + const uint32_t* content = nullptr; +}; + +#endif //_TVG_PNG_LOADER_H_ diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp new file mode 100644 index 0000000000..8846613c6b --- /dev/null +++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <memory.h> +#include "tvgLoader.h" +#include "tvgJpgLoader.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +void JpgLoader::clear() +{ + jpgdDelete(decoder); + if (freeData) free(data); + decoder = nullptr; + data = nullptr; + freeData = false; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + + +JpgLoader::~JpgLoader() +{ + jpgdDelete(decoder); + if (freeData) free(data); +} + + +bool JpgLoader::open(const string& path) +{ + clear(); + + int width, height; + decoder = jpgdHeader(path.c_str(), &width, &height); + if (!decoder) return false; + + w = static_cast<float>(width); + h = static_cast<float>(height); + + return true; +} + + +bool JpgLoader::open(const char* data, uint32_t size, bool copy) +{ + clear(); + + if (copy) { + this->data = (char *) malloc(size); + if (!this->data) return false; + memcpy((char *)this->data, data, size); + freeData = true; + } else { + this->data = (char *) data; + freeData = false; + } + + int width, height; + decoder = jpgdHeader(this->data, size, &width, &height); + if (!decoder) return false; + + w = static_cast<float>(width); + h = static_cast<float>(height); + + return true; +} + + + +bool JpgLoader::read() +{ + if (!decoder || w <= 0 || h <= 0) return false; + + TaskScheduler::request(this); + + return true; +} + + +bool JpgLoader::close() +{ + this->done(); + clear(); + return true; +} + + +unique_ptr<Surface> JpgLoader::bitmap() +{ + this->done(); + + if (!image) return nullptr; + + auto surface = static_cast<Surface*>(malloc(sizeof(Surface))); + surface->buffer = (uint32_t*)(image); + surface->stride = w; + surface->w = w; + surface->h = h; + surface->cs = SwCanvas::ARGB8888; + + return unique_ptr<Surface>(surface); +} + + +void JpgLoader::run(unsigned tid) +{ + image = jpgdDecompress(decoder); +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h new file mode 100644 index 0000000000..39732dbc3a --- /dev/null +++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_JPG_LOADER_H_ +#define _TVG_JPG_LOADER_H_ + +#include "tvgTaskScheduler.h" +#include "tvgJpgd.h" + +class JpgLoader : public LoadModule, public Task +{ +private: + jpeg_decoder* decoder = nullptr; + char* data = nullptr; + unsigned char *image = nullptr; + bool freeData = false; + + void clear(); + +public: + ~JpgLoader(); + + using LoadModule::open; + bool open(const string& path) override; + bool open(const char* data, uint32_t size, bool copy) override; + bool read() override; + bool close() override; + + unique_ptr<Surface> bitmap() override; + void run(unsigned tid) override; +}; + +#endif //_TVG_JPG_LOADER_H_ diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp new file mode 100644 index 0000000000..fa72734ec4 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp @@ -0,0 +1,3028 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// jpgd.cpp - C++ class for JPEG decompression. +// Public domain, Rich Geldreich <richgel99@gmail.com> +// Alex Evans: Linear memory allocator (taken from jpge.h). +// v1.04, May. 19, 2012: Code tweaks to fix VS2008 static code analysis warnings (all looked harmless) +// +// Supports progressive and baseline sequential JPEG image files, and the most common chroma subsampling factors: Y, H1V1, H2V1, H1V2, and H2V2. +// +// Chroma upsampling quality: H2V2 is upsampled in the frequency domain, H2V1 and H1V2 are upsampled using point sampling. +// Chroma upsampling reference: "Fast Scheme for Image Size Change in the Compressed Domain" +// http://vision.ai.uiuc.edu/~dugad/research/dct/index.html + +#include <memory.h> +#include <stdlib.h> +#include <stdio.h> +#include <setjmp.h> +#include <stdint.h> +#include "tvgJpgd.h" + +#ifdef _MSC_VER + #pragma warning (disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable + #define JPGD_NORETURN __declspec(noreturn) +#elif defined(__GNUC__) + #define JPGD_NORETURN __attribute__ ((noreturn)) +#else + #define JPGD_NORETURN +#endif + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + + +// Set to 1 to enable freq. domain chroma upsampling on images using H2V2 subsampling (0=faster nearest neighbor sampling). +// This is slower, but results in higher quality on images with highly saturated colors. +#define JPGD_SUPPORT_FREQ_DOMAIN_UPSAMPLING 1 + +#define JPGD_ASSERT(x) +#define JPGD_MAX(a,b) (((a)>(b)) ? (a) : (b)) +#define JPGD_MIN(a,b) (((a)<(b)) ? (a) : (b)) + +typedef int16_t jpgd_quant_t; +typedef int16_t jpgd_block_t; + +// Success/failure error codes. +enum jpgd_status +{ + JPGD_SUCCESS = 0, JPGD_FAILED = -1, JPGD_DONE = 1, + JPGD_BAD_DHT_COUNTS = -256, JPGD_BAD_DHT_INDEX, JPGD_BAD_DHT_MARKER, JPGD_BAD_DQT_MARKER, JPGD_BAD_DQT_TABLE, + JPGD_BAD_PRECISION, JPGD_BAD_HEIGHT, JPGD_BAD_WIDTH, JPGD_TOO_MANY_COMPONENTS, + JPGD_BAD_SOF_LENGTH, JPGD_BAD_VARIABLE_MARKER, JPGD_BAD_DRI_LENGTH, JPGD_BAD_SOS_LENGTH, + JPGD_BAD_SOS_COMP_ID, JPGD_W_EXTRA_BYTES_BEFORE_MARKER, JPGD_NO_ARITHMITIC_SUPPORT, JPGD_UNEXPECTED_MARKER, + JPGD_NOT_JPEG, JPGD_UNSUPPORTED_MARKER, JPGD_BAD_DQT_LENGTH, JPGD_TOO_MANY_BLOCKS, + JPGD_UNDEFINED_QUANT_TABLE, JPGD_UNDEFINED_HUFF_TABLE, JPGD_NOT_SINGLE_SCAN, JPGD_UNSUPPORTED_COLORSPACE, + JPGD_UNSUPPORTED_SAMP_FACTORS, JPGD_DECODE_ERROR, JPGD_BAD_RESTART_MARKER, JPGD_ASSERTION_ERROR, + JPGD_BAD_SOS_SPECTRAL, JPGD_BAD_SOS_SUCCESSIVE, JPGD_STREAM_READ, JPGD_NOTENOUGHMEM +}; + +enum +{ + JPGD_IN_BUF_SIZE = 8192, JPGD_MAX_BLOCKS_PER_MCU = 10, JPGD_MAX_HUFF_TABLES = 8, JPGD_MAX_QUANT_TABLES = 4, + JPGD_MAX_COMPONENTS = 4, JPGD_MAX_COMPS_IN_SCAN = 4, JPGD_MAX_BLOCKS_PER_ROW = 8192, JPGD_MAX_HEIGHT = 16384, JPGD_MAX_WIDTH = 16384 +}; + +// Input stream interface. +// Derive from this class to read input data from sources other than files or memory. Set m_eof_flag to true when no more data is available. +// The decoder is rather greedy: it will keep on calling this method until its internal input buffer is full, or until the EOF flag is set. +// It the input stream contains data after the JPEG stream's EOI (end of image) marker it will probably be pulled into the internal buffer. +// Call the get_total_bytes_read() method to determine the actual size of the JPEG stream after successful decoding. +struct jpeg_decoder_stream +{ + jpeg_decoder_stream() { } + virtual ~jpeg_decoder_stream() { } + + // The read() method is called when the internal input buffer is empty. + // Parameters: + // pBuf - input buffer + // max_bytes_to_read - maximum bytes that can be written to pBuf + // pEOF_flag - set this to true if at end of stream (no more bytes remaining) + // Returns -1 on error, otherwise return the number of bytes actually written to the buffer (which may be 0). + // Notes: This method will be called in a loop until you set *pEOF_flag to true or the internal buffer is full. + virtual int read(uint8_t *pBuf, int max_bytes_to_read, bool *pEOF_flag) = 0; +}; + + +// stdio FILE stream class. +class jpeg_decoder_file_stream : public jpeg_decoder_stream +{ + jpeg_decoder_file_stream(const jpeg_decoder_file_stream &); + jpeg_decoder_file_stream &operator =(const jpeg_decoder_file_stream &); + + FILE *m_pFile = nullptr; + bool m_eof_flag = false; + bool m_error_flag = false; + +public: + jpeg_decoder_file_stream() {} + virtual ~jpeg_decoder_file_stream(); + bool open(const char *Pfilename); + void close(); + virtual int read(uint8_t *pBuf, int max_bytes_to_read, bool *pEOF_flag); + }; + + +// Memory stream class. +class jpeg_decoder_mem_stream : public jpeg_decoder_stream +{ + const uint8_t *m_pSrc_data; + uint32_t m_ofs, m_size; + +public: + jpeg_decoder_mem_stream() : m_pSrc_data(nullptr), m_ofs(0), m_size(0) {} + jpeg_decoder_mem_stream(const uint8_t *pSrc_data, uint32_t size) : m_pSrc_data(pSrc_data), m_ofs(0), m_size(size) {} + virtual ~jpeg_decoder_mem_stream() {} + bool open(const uint8_t *pSrc_data, uint32_t size); + void close() { m_pSrc_data = nullptr; m_ofs = 0; m_size = 0; } + virtual int read(uint8_t *pBuf, int max_bytes_to_read, bool *pEOF_flag); +}; + + +class jpeg_decoder +{ +public: + // Call get_error_code() after constructing to determine if the stream is valid or not. You may call the get_width(), get_height(), etc. + // methods after the constructor is called. You may then either destruct the object, or begin decoding the image by calling begin_decoding(), then decode() on each scanline. + jpeg_decoder(jpeg_decoder_stream *pStream); + ~jpeg_decoder(); + + // Call this method after constructing the object to begin decompression. + // If JPGD_SUCCESS is returned you may then call decode() on each scanline. + int begin_decoding(); + // Returns the next scan line. + // For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (get_bytes_per_pixel() will return 1). + // Otherwise, it will always point to a buffer containing 32-bit RGBA pixels (A will always be 255, and get_bytes_per_pixel() will return 4). + // Returns JPGD_SUCCESS if a scan line has been returned. + // Returns JPGD_DONE if all scan lines have been returned. + // Returns JPGD_FAILED if an error occurred. Call get_error_code() for a more info. + int decode(const void** pScan_line, uint32_t* pScan_line_len); + inline jpgd_status get_error_code() const { return m_error_code; } + inline int get_width() const { return m_image_x_size; } + inline int get_height() const { return m_image_y_size; } + inline int get_num_components() const { return m_comps_in_frame; } + inline int get_bytes_per_pixel() const { return m_dest_bytes_per_pixel; } + inline int get_bytes_per_scan_line() const { return m_image_x_size * get_bytes_per_pixel(); } + // Returns the total number of bytes actually consumed by the decoder (which should equal the actual size of the JPEG file). + inline int get_total_bytes_read() const { return m_total_bytes_read; } + +private: + jpeg_decoder(const jpeg_decoder &); + jpeg_decoder &operator =(const jpeg_decoder &); + + typedef void (*pDecode_block_func)(jpeg_decoder *, int, int, int); + + struct huff_tables + { + bool ac_table; + uint32_t look_up[256]; + uint32_t look_up2[256]; + uint8_t code_size[256]; + uint32_t tree[512]; + }; + + struct coeff_buf + { + uint8_t *pData; + int block_num_x, block_num_y; + int block_len_x, block_len_y; + int block_size; + }; + + struct mem_block + { + mem_block *m_pNext; + size_t m_used_count; + size_t m_size; + char m_data[1]; + }; + + jmp_buf m_jmp_state; + mem_block *m_pMem_blocks; + int m_image_x_size; + int m_image_y_size; + jpeg_decoder_stream *m_pStream; + int m_progressive_flag; + uint8_t m_huff_ac[JPGD_MAX_HUFF_TABLES]; + uint8_t* m_huff_num[JPGD_MAX_HUFF_TABLES]; // pointer to number of Huffman codes per bit size + uint8_t* m_huff_val[JPGD_MAX_HUFF_TABLES]; // pointer to Huffman codes per bit size + jpgd_quant_t* m_quant[JPGD_MAX_QUANT_TABLES]; // pointer to quantization tables + int m_scan_type; // Gray, Yh1v1, Yh1v2, Yh2v1, Yh2v2 (CMYK111, CMYK4114 no longer supported) + int m_comps_in_frame; // # of components in frame + int m_comp_h_samp[JPGD_MAX_COMPONENTS]; // component's horizontal sampling factor + int m_comp_v_samp[JPGD_MAX_COMPONENTS]; // component's vertical sampling factor + int m_comp_quant[JPGD_MAX_COMPONENTS]; // component's quantization table selector + int m_comp_ident[JPGD_MAX_COMPONENTS]; // component's ID + int m_comp_h_blocks[JPGD_MAX_COMPONENTS]; + int m_comp_v_blocks[JPGD_MAX_COMPONENTS]; + int m_comps_in_scan; // # of components in scan + int m_comp_list[JPGD_MAX_COMPS_IN_SCAN]; // components in this scan + int m_comp_dc_tab[JPGD_MAX_COMPONENTS]; // component's DC Huffman coding table selector + int m_comp_ac_tab[JPGD_MAX_COMPONENTS]; // component's AC Huffman coding table selector + int m_spectral_start; // spectral selection start + int m_spectral_end; // spectral selection end + int m_successive_low; // successive approximation low + int m_successive_high; // successive approximation high + int m_max_mcu_x_size; // MCU's max. X size in pixels + int m_max_mcu_y_size; // MCU's max. Y size in pixels + int m_blocks_per_mcu; + int m_max_blocks_per_row; + int m_mcus_per_row, m_mcus_per_col; + int m_mcu_org[JPGD_MAX_BLOCKS_PER_MCU]; + int m_total_lines_left; // total # lines left in image + int m_mcu_lines_left; // total # lines left in this MCU + int m_real_dest_bytes_per_scan_line; + int m_dest_bytes_per_scan_line; // rounded up + int m_dest_bytes_per_pixel; // 4 (RGB) or 1 (Y) + huff_tables* m_pHuff_tabs[JPGD_MAX_HUFF_TABLES]; + coeff_buf* m_dc_coeffs[JPGD_MAX_COMPONENTS]; + coeff_buf* m_ac_coeffs[JPGD_MAX_COMPONENTS]; + int m_eob_run; + int m_block_y_mcu[JPGD_MAX_COMPONENTS]; + uint8_t* m_pIn_buf_ofs; + int m_in_buf_left; + int m_tem_flag; + bool m_eof_flag; + uint8_t m_in_buf_pad_start[128]; + uint8_t m_in_buf[JPGD_IN_BUF_SIZE + 128]; + uint8_t m_in_buf_pad_end[128]; + int m_bits_left; + uint32_t m_bit_buf; + int m_restart_interval; + int m_restarts_left; + int m_next_restart_num; + int m_max_mcus_per_row; + int m_max_blocks_per_mcu; + int m_expanded_blocks_per_mcu; + int m_expanded_blocks_per_row; + int m_expanded_blocks_per_component; + bool m_freq_domain_chroma_upsample; + int m_max_mcus_per_col; + uint32_t m_last_dc_val[JPGD_MAX_COMPONENTS]; + jpgd_block_t* m_pMCU_coefficients; + int m_mcu_block_max_zag[JPGD_MAX_BLOCKS_PER_MCU]; + uint8_t* m_pSample_buf; + int m_crr[256]; + int m_cbb[256]; + int m_crg[256]; + int m_cbg[256]; + uint8_t* m_pScan_line_0; + uint8_t* m_pScan_line_1; + jpgd_status m_error_code; + bool m_ready_flag; + int m_total_bytes_read; + + void free_all_blocks(); + JPGD_NORETURN void stop_decoding(jpgd_status status); + void *alloc(size_t n, bool zero = false); + void word_clear(void *p, uint16_t c, uint32_t n); + void prep_in_buffer(); + void read_dht_marker(); + void read_dqt_marker(); + void read_sof_marker(); + void skip_variable_marker(); + void read_dri_marker(); + void read_sos_marker(); + int next_marker(); + int process_markers(); + void locate_soi_marker(); + void locate_sof_marker(); + int locate_sos_marker(); + void init(jpeg_decoder_stream * pStream); + void create_look_ups(); + void fix_in_buffer(); + void transform_mcu(int mcu_row); + void transform_mcu_expand(int mcu_row); + coeff_buf* coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y); + inline jpgd_block_t *coeff_buf_getp(coeff_buf *cb, int block_x, int block_y); + void load_next_row(); + void decode_next_row(); + void make_huff_table(int index, huff_tables *pH); + void check_quant_tables(); + void check_huff_tables(); + void calc_mcu_block_order(); + int init_scan(); + void init_frame(); + void process_restart(); + void decode_scan(pDecode_block_func decode_block_func); + void init_progressive(); + void init_sequential(); + void decode_start(); + void decode_init(jpeg_decoder_stream * pStream); + void H2V2Convert(); + void H2V1Convert(); + void H1V2Convert(); + void H1V1Convert(); + void gray_convert(); + void expanded_convert(); + void find_eoi(); + inline uint32_t get_char(); + inline uint32_t get_char(bool *pPadding_flag); + inline void stuff_char(uint8_t q); + inline uint8_t get_octet(); + inline uint32_t get_bits(int num_bits); + inline uint32_t get_bits_no_markers(int numbits); + inline int huff_decode(huff_tables *pH); + inline int huff_decode(huff_tables *pH, int& extrabits); + static inline uint8_t clamp(int i); + static void decode_block_dc_first(jpeg_decoder *pD, int component_id, int block_x, int block_y); + static void decode_block_dc_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y); + static void decode_block_ac_first(jpeg_decoder *pD, int component_id, int block_x, int block_y); + static void decode_block_ac_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y); +}; + + +// DCT coefficients are stored in this sequence. +static int g_ZAG[64] = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 }; + +enum JPEG_MARKER +{ + M_SOF0 = 0xC0, M_SOF1 = 0xC1, M_SOF2 = 0xC2, M_SOF3 = 0xC3, M_SOF5 = 0xC5, M_SOF6 = 0xC6, M_SOF7 = 0xC7, M_JPG = 0xC8, + M_SOF9 = 0xC9, M_SOF10 = 0xCA, M_SOF11 = 0xCB, M_SOF13 = 0xCD, M_SOF14 = 0xCE, M_SOF15 = 0xCF, M_DHT = 0xC4, M_DAC = 0xCC, + M_RST0 = 0xD0, M_RST1 = 0xD1, M_RST2 = 0xD2, M_RST3 = 0xD3, M_RST4 = 0xD4, M_RST5 = 0xD5, M_RST6 = 0xD6, M_RST7 = 0xD7, + M_SOI = 0xD8, M_EOI = 0xD9, M_SOS = 0xDA, M_DQT = 0xDB, M_DNL = 0xDC, M_DRI = 0xDD, M_DHP = 0xDE, M_EXP = 0xDF, + M_APP0 = 0xE0, M_APP15 = 0xEF, M_JPG0 = 0xF0, M_JPG13 = 0xFD, M_COM = 0xFE, M_TEM = 0x01, M_ERROR = 0x100, RST0 = 0xD0 +}; + +enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, JPGD_YH2V2 }; + +#define CONST_BITS 13 +#define PASS1_BITS 2 +#define SCALEDONE ((int32_t)1) +#define DESCALE(x,n) (((x) + (SCALEDONE << ((n)-1))) >> (n)) +#define DESCALE_ZEROSHIFT(x,n) (((x) + (128 << (n)) + (SCALEDONE << ((n)-1))) >> (n)) +#define MULTIPLY(var, cnst) ((var) * (cnst)) +#define CLAMP(i) ((static_cast<uint32_t>(i) > 255) ? (((~i) >> 31) & 0xFF) : (i)) + +#define FIX_0_298631336 ((int32_t)2446) /* FIX(0.298631336) */ +#define FIX_0_390180644 ((int32_t)3196) /* FIX(0.390180644) */ +#define FIX_0_541196100 ((int32_t)4433) /* FIX(0.541196100) */ +#define FIX_0_765366865 ((int32_t)6270) /* FIX(0.765366865) */ +#define FIX_0_899976223 ((int32_t)7373) /* FIX(0.899976223) */ +#define FIX_1_175875602 ((int32_t)9633) /* FIX(1.175875602) */ +#define FIX_1_501321110 ((int32_t)12299) /* FIX(1.501321110) */ +#define FIX_1_847759065 ((int32_t)15137) /* FIX(1.847759065) */ +#define FIX_1_961570560 ((int32_t)16069) /* FIX(1.961570560) */ +#define FIX_2_053119869 ((int32_t)16819) /* FIX(2.053119869) */ +#define FIX_2_562915447 ((int32_t)20995) /* FIX(2.562915447) */ +#define FIX_3_072711026 ((int32_t)25172) /* FIX(3.072711026) */ + + +// Compiler creates a fast path 1D IDCT for X non-zero columns +template <int NONZERO_COLS> +struct Row +{ + static void idct(int* pTemp, const jpgd_block_t* pSrc) + { + // ACCESS_COL() will be optimized at compile time to either an array access, or 0. + #define ACCESS_COL(x) (((x) < NONZERO_COLS) ? (int)pSrc[x] : 0) + + const int z2 = ACCESS_COL(2), z3 = ACCESS_COL(6); + const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + const int tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); + const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + const int tmp0 = (ACCESS_COL(0) + ACCESS_COL(4)) << CONST_BITS; + const int tmp1 = (ACCESS_COL(0) - ACCESS_COL(4)) << CONST_BITS; + + const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; + + const int atmp0 = ACCESS_COL(7), atmp1 = ACCESS_COL(5), atmp2 = ACCESS_COL(3), atmp3 = ACCESS_COL(1); + + const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3; + const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602); + + const int az1 = MULTIPLY(bz1, - FIX_0_899976223); + const int az2 = MULTIPLY(bz2, - FIX_2_562915447); + const int az3 = MULTIPLY(bz3, - FIX_1_961570560) + bz5; + const int az4 = MULTIPLY(bz4, - FIX_0_390180644) + bz5; + + const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3; + const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4; + const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3; + const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4; + + pTemp[0] = DESCALE(tmp10 + btmp3, CONST_BITS-PASS1_BITS); + pTemp[7] = DESCALE(tmp10 - btmp3, CONST_BITS-PASS1_BITS); + pTemp[1] = DESCALE(tmp11 + btmp2, CONST_BITS-PASS1_BITS); + pTemp[6] = DESCALE(tmp11 - btmp2, CONST_BITS-PASS1_BITS); + pTemp[2] = DESCALE(tmp12 + btmp1, CONST_BITS-PASS1_BITS); + pTemp[5] = DESCALE(tmp12 - btmp1, CONST_BITS-PASS1_BITS); + pTemp[3] = DESCALE(tmp13 + btmp0, CONST_BITS-PASS1_BITS); + pTemp[4] = DESCALE(tmp13 - btmp0, CONST_BITS-PASS1_BITS); + } +}; + + +template <> +struct Row<0> +{ + static void idct(int* pTemp, const jpgd_block_t* pSrc) + { +#ifdef _MSC_VER + pTemp; pSrc; +#endif + } +}; + + +template <> +struct Row<1> +{ + static void idct(int* pTemp, const jpgd_block_t* pSrc) + { + const int dcval = (pSrc[0] << PASS1_BITS); + + pTemp[0] = dcval; + pTemp[1] = dcval; + pTemp[2] = dcval; + pTemp[3] = dcval; + pTemp[4] = dcval; + pTemp[5] = dcval; + pTemp[6] = dcval; + pTemp[7] = dcval; + } +}; + + +// Compiler creates a fast path 1D IDCT for X non-zero rows +template <int NONZERO_ROWS> +struct Col +{ + static void idct(uint8_t* pDst_ptr, const int* pTemp) + { + // ACCESS_ROW() will be optimized at compile time to either an array access, or 0. + #define ACCESS_ROW(x) (((x) < NONZERO_ROWS) ? pTemp[x * 8] : 0) + + const int z2 = ACCESS_ROW(2); + const int z3 = ACCESS_ROW(6); + + const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + const int tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); + const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + const int tmp0 = (ACCESS_ROW(0) + ACCESS_ROW(4)) << CONST_BITS; + const int tmp1 = (ACCESS_ROW(0) - ACCESS_ROW(4)) << CONST_BITS; + + const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; + + const int atmp0 = ACCESS_ROW(7), atmp1 = ACCESS_ROW(5), atmp2 = ACCESS_ROW(3), atmp3 = ACCESS_ROW(1); + + const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3; + const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602); + + const int az1 = MULTIPLY(bz1, - FIX_0_899976223); + const int az2 = MULTIPLY(bz2, - FIX_2_562915447); + const int az3 = MULTIPLY(bz3, - FIX_1_961570560) + bz5; + const int az4 = MULTIPLY(bz4, - FIX_0_390180644) + bz5; + + const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3; + const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4; + const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3; + const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4; + + int i = DESCALE_ZEROSHIFT(tmp10 + btmp3, CONST_BITS+PASS1_BITS+3); + pDst_ptr[8*0] = (uint8_t)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp10 - btmp3, CONST_BITS+PASS1_BITS+3); + pDst_ptr[8*7] = (uint8_t)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp11 + btmp2, CONST_BITS+PASS1_BITS+3); + pDst_ptr[8*1] = (uint8_t)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp11 - btmp2, CONST_BITS+PASS1_BITS+3); + pDst_ptr[8*6] = (uint8_t)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp12 + btmp1, CONST_BITS+PASS1_BITS+3); + pDst_ptr[8*2] = (uint8_t)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp12 - btmp1, CONST_BITS+PASS1_BITS+3); + pDst_ptr[8*5] = (uint8_t)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp13 + btmp0, CONST_BITS+PASS1_BITS+3); + pDst_ptr[8*3] = (uint8_t)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp13 - btmp0, CONST_BITS+PASS1_BITS+3); + pDst_ptr[8*4] = (uint8_t)CLAMP(i); + } +}; + + +template <> +struct Col<1> +{ + static void idct(uint8_t* pDst_ptr, const int* pTemp) + { + int dcval = DESCALE_ZEROSHIFT(pTemp[0], PASS1_BITS+3); + const uint8_t dcval_clamped = (uint8_t)CLAMP(dcval); + pDst_ptr[0*8] = dcval_clamped; + pDst_ptr[1*8] = dcval_clamped; + pDst_ptr[2*8] = dcval_clamped; + pDst_ptr[3*8] = dcval_clamped; + pDst_ptr[4*8] = dcval_clamped; + pDst_ptr[5*8] = dcval_clamped; + pDst_ptr[6*8] = dcval_clamped; + pDst_ptr[7*8] = dcval_clamped; + } +}; + + +static const uint8_t s_idct_row_table[] = { + 1,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0, 2,1,0,0,0,0,0,0, 2,1,1,0,0,0,0,0, 2,2,1,0,0,0,0,0, 3,2,1,0,0,0,0,0, 4,2,1,0,0,0,0,0, 4,3,1,0,0,0,0,0, + 4,3,2,0,0,0,0,0, 4,3,2,1,0,0,0,0, 4,3,2,1,1,0,0,0, 4,3,2,2,1,0,0,0, 4,3,3,2,1,0,0,0, 4,4,3,2,1,0,0,0, 5,4,3,2,1,0,0,0, 6,4,3,2,1,0,0,0, + 6,5,3,2,1,0,0,0, 6,5,4,2,1,0,0,0, 6,5,4,3,1,0,0,0, 6,5,4,3,2,0,0,0, 6,5,4,3,2,1,0,0, 6,5,4,3,2,1,1,0, 6,5,4,3,2,2,1,0, 6,5,4,3,3,2,1,0, + 6,5,4,4,3,2,1,0, 6,5,5,4,3,2,1,0, 6,6,5,4,3,2,1,0, 7,6,5,4,3,2,1,0, 8,6,5,4,3,2,1,0, 8,7,5,4,3,2,1,0, 8,7,6,4,3,2,1,0, 8,7,6,5,3,2,1,0, + 8,7,6,5,4,2,1,0, 8,7,6,5,4,3,1,0, 8,7,6,5,4,3,2,0, 8,7,6,5,4,3,2,1, 8,7,6,5,4,3,2,2, 8,7,6,5,4,3,3,2, 8,7,6,5,4,4,3,2, 8,7,6,5,5,4,3,2, + 8,7,6,6,5,4,3,2, 8,7,7,6,5,4,3,2, 8,8,7,6,5,4,3,2, 8,8,8,6,5,4,3,2, 8,8,8,7,5,4,3,2, 8,8,8,7,6,4,3,2, 8,8,8,7,6,5,3,2, 8,8,8,7,6,5,4,2, + 8,8,8,7,6,5,4,3, 8,8,8,7,6,5,4,4, 8,8,8,7,6,5,5,4, 8,8,8,7,6,6,5,4, 8,8,8,7,7,6,5,4, 8,8,8,8,7,6,5,4, 8,8,8,8,8,6,5,4, 8,8,8,8,8,7,5,4, + 8,8,8,8,8,7,6,4, 8,8,8,8,8,7,6,5, 8,8,8,8,8,7,6,6, 8,8,8,8,8,7,7,6, 8,8,8,8,8,8,7,6, 8,8,8,8,8,8,8,6, 8,8,8,8,8,8,8,7, 8,8,8,8,8,8,8,8, +}; + + +static const uint8_t s_idct_col_table[] = { 1, 1, 2, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; + + +void idct(const jpgd_block_t* pSrc_ptr, uint8_t* pDst_ptr, int block_max_zag) +{ + JPGD_ASSERT(block_max_zag >= 1); + JPGD_ASSERT(block_max_zag <= 64); + + if (block_max_zag <= 1) { + int k = ((pSrc_ptr[0] + 4) >> 3) + 128; + k = CLAMP(k); + k = k | (k<<8); + k = k | (k<<16); + for (int i = 8; i > 0; i--) { + *(int*)&pDst_ptr[0] = k; + *(int*)&pDst_ptr[4] = k; + pDst_ptr += 8; + } + return; + } + + int temp[64]; + const jpgd_block_t* pSrc = pSrc_ptr; + int* pTemp = temp; + const uint8_t* pRow_tab = &s_idct_row_table[(block_max_zag - 1) * 8]; + int i; + for (i = 8; i > 0; i--, pRow_tab++) { + switch (*pRow_tab) { + case 0: Row<0>::idct(pTemp, pSrc); break; + case 1: Row<1>::idct(pTemp, pSrc); break; + case 2: Row<2>::idct(pTemp, pSrc); break; + case 3: Row<3>::idct(pTemp, pSrc); break; + case 4: Row<4>::idct(pTemp, pSrc); break; + case 5: Row<5>::idct(pTemp, pSrc); break; + case 6: Row<6>::idct(pTemp, pSrc); break; + case 7: Row<7>::idct(pTemp, pSrc); break; + case 8: Row<8>::idct(pTemp, pSrc); break; + } + pSrc += 8; + pTemp += 8; + } + + pTemp = temp; + + const int nonzero_rows = s_idct_col_table[block_max_zag - 1]; + for (i = 8; i > 0; i--) { + switch (nonzero_rows) { + case 1: Col<1>::idct(pDst_ptr, pTemp); break; + case 2: Col<2>::idct(pDst_ptr, pTemp); break; + case 3: Col<3>::idct(pDst_ptr, pTemp); break; + case 4: Col<4>::idct(pDst_ptr, pTemp); break; + case 5: Col<5>::idct(pDst_ptr, pTemp); break; + case 6: Col<6>::idct(pDst_ptr, pTemp); break; + case 7: Col<7>::idct(pDst_ptr, pTemp); break; + case 8: Col<8>::idct(pDst_ptr, pTemp); break; + } + pTemp++; + pDst_ptr++; + } +} + + +void idct_4x4(const jpgd_block_t* pSrc_ptr, uint8_t* pDst_ptr) +{ + int temp[64]; + int* pTemp = temp; + const jpgd_block_t* pSrc = pSrc_ptr; + + for (int i = 4; i > 0; i--) { + Row<4>::idct(pTemp, pSrc); + pSrc += 8; + pTemp += 8; + } + + pTemp = temp; + + for (int i = 8; i > 0; i--) { + Col<4>::idct(pDst_ptr, pTemp); + pTemp++; + pDst_ptr++; + } +} + + +// Retrieve one character from the input stream. +inline uint32_t jpeg_decoder::get_char() +{ + // Any bytes remaining in buffer? + if (!m_in_buf_left) { + // Try to get more bytes. + prep_in_buffer(); + // Still nothing to get? + if (!m_in_buf_left) { + // Pad the end of the stream with 0xFF 0xD9 (EOI marker) + int t = m_tem_flag; + m_tem_flag ^= 1; + if (t) return 0xD9; + else return 0xFF; + } + } + uint32_t c = *m_pIn_buf_ofs++; + m_in_buf_left--; + return c; +} + + +// Same as previous method, except can indicate if the character is a pad character or not. +inline uint32_t jpeg_decoder::get_char(bool *pPadding_flag) +{ + if (!m_in_buf_left) { + prep_in_buffer(); + if (!m_in_buf_left) { + *pPadding_flag = true; + int t = m_tem_flag; + m_tem_flag ^= 1; + if (t) return 0xD9; + else return 0xFF; + } + } + *pPadding_flag = false; + uint32_t c = *m_pIn_buf_ofs++; + m_in_buf_left--; + + return c; +} + + +// Inserts a previously retrieved character back into the input buffer. +inline void jpeg_decoder::stuff_char(uint8_t q) +{ + *(--m_pIn_buf_ofs) = q; + m_in_buf_left++; +} + + +// Retrieves one character from the input stream, but does not read past markers. Will continue to return 0xFF when a marker is encountered. +inline uint8_t jpeg_decoder::get_octet() +{ + bool padding_flag; + int c = get_char(&padding_flag); + + if (c == 0xFF) { + if (padding_flag) return 0xFF; + + c = get_char(&padding_flag); + if (padding_flag) { + stuff_char(0xFF); + return 0xFF; + } + if (c == 0x00) return 0xFF; + else { + stuff_char(static_cast<uint8_t>(c)); + stuff_char(0xFF); + return 0xFF; + } + } + return static_cast<uint8_t>(c); +} + + +// Retrieves a variable number of bits from the input stream. Does not recognize markers. +inline uint32_t jpeg_decoder::get_bits(int num_bits) +{ + if (!num_bits) return 0; + + uint32_t i = m_bit_buf >> (32 - num_bits); + + if ((m_bits_left -= num_bits) <= 0) { + m_bit_buf <<= (num_bits += m_bits_left); + uint32_t c1 = get_char(); + uint32_t c2 = get_char(); + m_bit_buf = (m_bit_buf & 0xFFFF0000) | (c1 << 8) | c2; + m_bit_buf <<= -m_bits_left; + m_bits_left += 16; + JPGD_ASSERT(m_bits_left >= 0); + } + else m_bit_buf <<= num_bits; + + return i; +} + + +// Retrieves a variable number of bits from the input stream. Markers will not be read into the input bit buffer. Instead, an infinite number of all 1's will be returned when a marker is encountered. +inline uint32_t jpeg_decoder::get_bits_no_markers(int num_bits) +{ + if (!num_bits)return 0; + + uint32_t i = m_bit_buf >> (32 - num_bits); + + if ((m_bits_left -= num_bits) <= 0) { + m_bit_buf <<= (num_bits += m_bits_left); + if ((m_in_buf_left < 2) || (m_pIn_buf_ofs[0] == 0xFF) || (m_pIn_buf_ofs[1] == 0xFF)) { + uint32_t c1 = get_octet(); + uint32_t c2 = get_octet(); + m_bit_buf |= (c1 << 8) | c2; + } else { + m_bit_buf |= ((uint32_t)m_pIn_buf_ofs[0] << 8) | m_pIn_buf_ofs[1]; + m_in_buf_left -= 2; + m_pIn_buf_ofs += 2; + } + m_bit_buf <<= -m_bits_left; + m_bits_left += 16; + JPGD_ASSERT(m_bits_left >= 0); + } else m_bit_buf <<= num_bits; + + return i; +} + + +// Decodes a Huffman encoded symbol. +inline int jpeg_decoder::huff_decode(huff_tables *pH) +{ + int symbol; + + // Check first 8-bits: do we have a complete symbol? + if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0) { + // Decode more bits, use a tree traversal to find symbol. + int ofs = 23; + do { + symbol = pH->tree[-(int)(symbol + ((m_bit_buf >> ofs) & 1))]; + ofs--; + } while (symbol < 0); + get_bits_no_markers(8 + (23 - ofs)); + } else get_bits_no_markers(pH->code_size[symbol]); + + return symbol; +} + + +// Decodes a Huffman encoded symbol. +inline int jpeg_decoder::huff_decode(huff_tables *pH, int& extra_bits) +{ + int symbol; + + // Check first 8-bits: do we have a complete symbol? + if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0) { + // Use a tree traversal to find symbol. + int ofs = 23; + do { + symbol = pH->tree[-(int)(symbol + ((m_bit_buf >> ofs) & 1))]; + ofs--; + } while (symbol < 0); + + get_bits_no_markers(8 + (23 - ofs)); + extra_bits = get_bits_no_markers(symbol & 0xF); + } else { + JPGD_ASSERT(((symbol >> 8) & 31) == pH->code_size[symbol & 255] + ((symbol & 0x8000) ? (symbol & 15) : 0)); + + if (symbol & 0x8000) { + get_bits_no_markers((symbol >> 8) & 31); + extra_bits = symbol >> 16; + } else { + int code_size = (symbol >> 8) & 31; + int num_extra_bits = symbol & 0xF; + int bits = code_size + num_extra_bits; + if (bits <= (m_bits_left + 16)) extra_bits = get_bits_no_markers(bits) & ((1 << num_extra_bits) - 1); + else { + get_bits_no_markers(code_size); + extra_bits = get_bits_no_markers(num_extra_bits); + } + } + symbol &= 0xFF; + } + return symbol; +} + + +// Tables and macro used to fully decode the DPCM differences. +static const int s_extend_test[16] = { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; +static const unsigned int s_extend_offset[16] = { 0, ((-1u)<<1) + 1, ((-1u)<<2) + 1, ((-1u)<<3) + 1, ((-1u)<<4) + 1, ((-1u)<<5) + 1, ((-1u)<<6) + 1, ((-1u)<<7) + 1, ((-1u)<<8) + 1, ((-1u)<<9) + 1, ((-1u)<<10) + 1, ((-1u)<<11) + 1, ((-1u)<<12) + 1, ((-1u)<<13) + 1, ((-1u)<<14) + 1, ((-1u)<<15) + 1 }; + +// The logical AND's in this macro are to shut up static code analysis (aren't really necessary - couldn't find another way to do this) +#define JPGD_HUFF_EXTEND(x, s) (((x) < s_extend_test[s & 15]) ? ((x) + s_extend_offset[s & 15]) : (x)) + + +// Clamps a value between 0-255. +inline uint8_t jpeg_decoder::clamp(int i) +{ + if (static_cast<uint32_t>(i) > 255) i = (((~i) >> 31) & 0xFF); + return static_cast<uint8_t>(i); +} + + +namespace DCT_Upsample +{ + struct Matrix44 + { + typedef int Element_Type; + enum { NUM_ROWS = 4, NUM_COLS = 4 }; + + Element_Type v[NUM_ROWS][NUM_COLS]; + + inline int rows() const { return NUM_ROWS; } + inline int cols() const { return NUM_COLS; } + inline const Element_Type & at(int r, int c) const { return v[r][c]; } + inline Element_Type & at(int r, int c) { return v[r][c]; } + + inline Matrix44() {} + + inline Matrix44& operator += (const Matrix44& a) + { + for (int r = 0; r < NUM_ROWS; r++) { + at(r, 0) += a.at(r, 0); + at(r, 1) += a.at(r, 1); + at(r, 2) += a.at(r, 2); + at(r, 3) += a.at(r, 3); + } + return *this; + } + + inline Matrix44& operator -= (const Matrix44& a) + { + for (int r = 0; r < NUM_ROWS; r++) { + at(r, 0) -= a.at(r, 0); + at(r, 1) -= a.at(r, 1); + at(r, 2) -= a.at(r, 2); + at(r, 3) -= a.at(r, 3); + } + return *this; + } + + friend inline Matrix44 operator + (const Matrix44& a, const Matrix44& b) + { + Matrix44 ret; + for (int r = 0; r < NUM_ROWS; r++) { + ret.at(r, 0) = a.at(r, 0) + b.at(r, 0); + ret.at(r, 1) = a.at(r, 1) + b.at(r, 1); + ret.at(r, 2) = a.at(r, 2) + b.at(r, 2); + ret.at(r, 3) = a.at(r, 3) + b.at(r, 3); + } + return ret; + } + + friend inline Matrix44 operator - (const Matrix44& a, const Matrix44& b) + { + Matrix44 ret; + for (int r = 0; r < NUM_ROWS; r++) { + ret.at(r, 0) = a.at(r, 0) - b.at(r, 0); + ret.at(r, 1) = a.at(r, 1) - b.at(r, 1); + ret.at(r, 2) = a.at(r, 2) - b.at(r, 2); + ret.at(r, 3) = a.at(r, 3) - b.at(r, 3); + } + return ret; + } + + static inline void add_and_store(jpgd_block_t* pDst, const Matrix44& a, const Matrix44& b) + { + for (int r = 0; r < 4; r++) { + pDst[0*8 + r] = static_cast<jpgd_block_t>(a.at(r, 0) + b.at(r, 0)); + pDst[1*8 + r] = static_cast<jpgd_block_t>(a.at(r, 1) + b.at(r, 1)); + pDst[2*8 + r] = static_cast<jpgd_block_t>(a.at(r, 2) + b.at(r, 2)); + pDst[3*8 + r] = static_cast<jpgd_block_t>(a.at(r, 3) + b.at(r, 3)); + } + } + + static inline void sub_and_store(jpgd_block_t* pDst, const Matrix44& a, const Matrix44& b) + { + for (int r = 0; r < 4; r++) { + pDst[0*8 + r] = static_cast<jpgd_block_t>(a.at(r, 0) - b.at(r, 0)); + pDst[1*8 + r] = static_cast<jpgd_block_t>(a.at(r, 1) - b.at(r, 1)); + pDst[2*8 + r] = static_cast<jpgd_block_t>(a.at(r, 2) - b.at(r, 2)); + pDst[3*8 + r] = static_cast<jpgd_block_t>(a.at(r, 3) - b.at(r, 3)); + } + } + }; + + const int FRACT_BITS = 10; + const int SCALE = 1 << FRACT_BITS; + + typedef int Temp_Type; + #define D(i) (((i) + (SCALE >> 1)) >> FRACT_BITS) + #define F(i) ((int)((i) * SCALE + .5f)) + + // Any decent C++ compiler will optimize this at compile time to a 0, or an array access. + #define AT(c, r) ((((c)>=NUM_COLS)||((r)>=NUM_ROWS)) ? 0 : pSrc[(c)+(r)*8]) + + // NUM_ROWS/NUM_COLS = # of non-zero rows/cols in input matrix + template<int NUM_ROWS, int NUM_COLS> + struct P_Q + { + static void calc(Matrix44& P, Matrix44& Q, const jpgd_block_t* pSrc) + { + // 4x8 = 4x8 times 8x8, matrix 0 is constant + const Temp_Type X000 = AT(0, 0); + const Temp_Type X001 = AT(0, 1); + const Temp_Type X002 = AT(0, 2); + const Temp_Type X003 = AT(0, 3); + const Temp_Type X004 = AT(0, 4); + const Temp_Type X005 = AT(0, 5); + const Temp_Type X006 = AT(0, 6); + const Temp_Type X007 = AT(0, 7); + const Temp_Type X010 = D(F(0.415735f) * AT(1, 0) + F(0.791065f) * AT(3, 0) + F(-0.352443f) * AT(5, 0) + F(0.277785f) * AT(7, 0)); + const Temp_Type X011 = D(F(0.415735f) * AT(1, 1) + F(0.791065f) * AT(3, 1) + F(-0.352443f) * AT(5, 1) + F(0.277785f) * AT(7, 1)); + const Temp_Type X012 = D(F(0.415735f) * AT(1, 2) + F(0.791065f) * AT(3, 2) + F(-0.352443f) * AT(5, 2) + F(0.277785f) * AT(7, 2)); + const Temp_Type X013 = D(F(0.415735f) * AT(1, 3) + F(0.791065f) * AT(3, 3) + F(-0.352443f) * AT(5, 3) + F(0.277785f) * AT(7, 3)); + const Temp_Type X014 = D(F(0.415735f) * AT(1, 4) + F(0.791065f) * AT(3, 4) + F(-0.352443f) * AT(5, 4) + F(0.277785f) * AT(7, 4)); + const Temp_Type X015 = D(F(0.415735f) * AT(1, 5) + F(0.791065f) * AT(3, 5) + F(-0.352443f) * AT(5, 5) + F(0.277785f) * AT(7, 5)); + const Temp_Type X016 = D(F(0.415735f) * AT(1, 6) + F(0.791065f) * AT(3, 6) + F(-0.352443f) * AT(5, 6) + F(0.277785f) * AT(7, 6)); + const Temp_Type X017 = D(F(0.415735f) * AT(1, 7) + F(0.791065f) * AT(3, 7) + F(-0.352443f) * AT(5, 7) + F(0.277785f) * AT(7, 7)); + const Temp_Type X020 = AT(4, 0); + const Temp_Type X021 = AT(4, 1); + const Temp_Type X022 = AT(4, 2); + const Temp_Type X023 = AT(4, 3); + const Temp_Type X024 = AT(4, 4); + const Temp_Type X025 = AT(4, 5); + const Temp_Type X026 = AT(4, 6); + const Temp_Type X027 = AT(4, 7); + const Temp_Type X030 = D(F(0.022887f) * AT(1, 0) + F(-0.097545f) * AT(3, 0) + F(0.490393f) * AT(5, 0) + F(0.865723f) * AT(7, 0)); + const Temp_Type X031 = D(F(0.022887f) * AT(1, 1) + F(-0.097545f) * AT(3, 1) + F(0.490393f) * AT(5, 1) + F(0.865723f) * AT(7, 1)); + const Temp_Type X032 = D(F(0.022887f) * AT(1, 2) + F(-0.097545f) * AT(3, 2) + F(0.490393f) * AT(5, 2) + F(0.865723f) * AT(7, 2)); + const Temp_Type X033 = D(F(0.022887f) * AT(1, 3) + F(-0.097545f) * AT(3, 3) + F(0.490393f) * AT(5, 3) + F(0.865723f) * AT(7, 3)); + const Temp_Type X034 = D(F(0.022887f) * AT(1, 4) + F(-0.097545f) * AT(3, 4) + F(0.490393f) * AT(5, 4) + F(0.865723f) * AT(7, 4)); + const Temp_Type X035 = D(F(0.022887f) * AT(1, 5) + F(-0.097545f) * AT(3, 5) + F(0.490393f) * AT(5, 5) + F(0.865723f) * AT(7, 5)); + const Temp_Type X036 = D(F(0.022887f) * AT(1, 6) + F(-0.097545f) * AT(3, 6) + F(0.490393f) * AT(5, 6) + F(0.865723f) * AT(7, 6)); + const Temp_Type X037 = D(F(0.022887f) * AT(1, 7) + F(-0.097545f) * AT(3, 7) + F(0.490393f) * AT(5, 7) + F(0.865723f) * AT(7, 7)); + + // 4x4 = 4x8 times 8x4, matrix 1 is constant + P.at(0, 0) = X000; + P.at(0, 1) = D(X001 * F(0.415735f) + X003 * F(0.791065f) + X005 * F(-0.352443f) + X007 * F(0.277785f)); + P.at(0, 2) = X004; + P.at(0, 3) = D(X001 * F(0.022887f) + X003 * F(-0.097545f) + X005 * F(0.490393f) + X007 * F(0.865723f)); + P.at(1, 0) = X010; + P.at(1, 1) = D(X011 * F(0.415735f) + X013 * F(0.791065f) + X015 * F(-0.352443f) + X017 * F(0.277785f)); + P.at(1, 2) = X014; + P.at(1, 3) = D(X011 * F(0.022887f) + X013 * F(-0.097545f) + X015 * F(0.490393f) + X017 * F(0.865723f)); + P.at(2, 0) = X020; + P.at(2, 1) = D(X021 * F(0.415735f) + X023 * F(0.791065f) + X025 * F(-0.352443f) + X027 * F(0.277785f)); + P.at(2, 2) = X024; + P.at(2, 3) = D(X021 * F(0.022887f) + X023 * F(-0.097545f) + X025 * F(0.490393f) + X027 * F(0.865723f)); + P.at(3, 0) = X030; + P.at(3, 1) = D(X031 * F(0.415735f) + X033 * F(0.791065f) + X035 * F(-0.352443f) + X037 * F(0.277785f)); + P.at(3, 2) = X034; + P.at(3, 3) = D(X031 * F(0.022887f) + X033 * F(-0.097545f) + X035 * F(0.490393f) + X037 * F(0.865723f)); + // 40 muls 24 adds + + // 4x4 = 4x8 times 8x4, matrix 1 is constant + Q.at(0, 0) = D(X001 * F(0.906127f) + X003 * F(-0.318190f) + X005 * F(0.212608f) + X007 * F(-0.180240f)); + Q.at(0, 1) = X002; + Q.at(0, 2) = D(X001 * F(-0.074658f) + X003 * F(0.513280f) + X005 * F(0.768178f) + X007 * F(-0.375330f)); + Q.at(0, 3) = X006; + Q.at(1, 0) = D(X011 * F(0.906127f) + X013 * F(-0.318190f) + X015 * F(0.212608f) + X017 * F(-0.180240f)); + Q.at(1, 1) = X012; + Q.at(1, 2) = D(X011 * F(-0.074658f) + X013 * F(0.513280f) + X015 * F(0.768178f) + X017 * F(-0.375330f)); + Q.at(1, 3) = X016; + Q.at(2, 0) = D(X021 * F(0.906127f) + X023 * F(-0.318190f) + X025 * F(0.212608f) + X027 * F(-0.180240f)); + Q.at(2, 1) = X022; + Q.at(2, 2) = D(X021 * F(-0.074658f) + X023 * F(0.513280f) + X025 * F(0.768178f) + X027 * F(-0.375330f)); + Q.at(2, 3) = X026; + Q.at(3, 0) = D(X031 * F(0.906127f) + X033 * F(-0.318190f) + X035 * F(0.212608f) + X037 * F(-0.180240f)); + Q.at(3, 1) = X032; + Q.at(3, 2) = D(X031 * F(-0.074658f) + X033 * F(0.513280f) + X035 * F(0.768178f) + X037 * F(-0.375330f)); + Q.at(3, 3) = X036; + // 40 muls 24 adds + } + }; + + + template<int NUM_ROWS, int NUM_COLS> + struct R_S + { + static void calc(Matrix44& R, Matrix44& S, const jpgd_block_t* pSrc) + { + // 4x8 = 4x8 times 8x8, matrix 0 is constant + const Temp_Type X100 = D(F(0.906127f) * AT(1, 0) + F(-0.318190f) * AT(3, 0) + F(0.212608f) * AT(5, 0) + F(-0.180240f) * AT(7, 0)); + const Temp_Type X101 = D(F(0.906127f) * AT(1, 1) + F(-0.318190f) * AT(3, 1) + F(0.212608f) * AT(5, 1) + F(-0.180240f) * AT(7, 1)); + const Temp_Type X102 = D(F(0.906127f) * AT(1, 2) + F(-0.318190f) * AT(3, 2) + F(0.212608f) * AT(5, 2) + F(-0.180240f) * AT(7, 2)); + const Temp_Type X103 = D(F(0.906127f) * AT(1, 3) + F(-0.318190f) * AT(3, 3) + F(0.212608f) * AT(5, 3) + F(-0.180240f) * AT(7, 3)); + const Temp_Type X104 = D(F(0.906127f) * AT(1, 4) + F(-0.318190f) * AT(3, 4) + F(0.212608f) * AT(5, 4) + F(-0.180240f) * AT(7, 4)); + const Temp_Type X105 = D(F(0.906127f) * AT(1, 5) + F(-0.318190f) * AT(3, 5) + F(0.212608f) * AT(5, 5) + F(-0.180240f) * AT(7, 5)); + const Temp_Type X106 = D(F(0.906127f) * AT(1, 6) + F(-0.318190f) * AT(3, 6) + F(0.212608f) * AT(5, 6) + F(-0.180240f) * AT(7, 6)); + const Temp_Type X107 = D(F(0.906127f) * AT(1, 7) + F(-0.318190f) * AT(3, 7) + F(0.212608f) * AT(5, 7) + F(-0.180240f) * AT(7, 7)); + const Temp_Type X110 = AT(2, 0); + const Temp_Type X111 = AT(2, 1); + const Temp_Type X112 = AT(2, 2); + const Temp_Type X113 = AT(2, 3); + const Temp_Type X114 = AT(2, 4); + const Temp_Type X115 = AT(2, 5); + const Temp_Type X116 = AT(2, 6); + const Temp_Type X117 = AT(2, 7); + const Temp_Type X120 = D(F(-0.074658f) * AT(1, 0) + F(0.513280f) * AT(3, 0) + F(0.768178f) * AT(5, 0) + F(-0.375330f) * AT(7, 0)); + const Temp_Type X121 = D(F(-0.074658f) * AT(1, 1) + F(0.513280f) * AT(3, 1) + F(0.768178f) * AT(5, 1) + F(-0.375330f) * AT(7, 1)); + const Temp_Type X122 = D(F(-0.074658f) * AT(1, 2) + F(0.513280f) * AT(3, 2) + F(0.768178f) * AT(5, 2) + F(-0.375330f) * AT(7, 2)); + const Temp_Type X123 = D(F(-0.074658f) * AT(1, 3) + F(0.513280f) * AT(3, 3) + F(0.768178f) * AT(5, 3) + F(-0.375330f) * AT(7, 3)); + const Temp_Type X124 = D(F(-0.074658f) * AT(1, 4) + F(0.513280f) * AT(3, 4) + F(0.768178f) * AT(5, 4) + F(-0.375330f) * AT(7, 4)); + const Temp_Type X125 = D(F(-0.074658f) * AT(1, 5) + F(0.513280f) * AT(3, 5) + F(0.768178f) * AT(5, 5) + F(-0.375330f) * AT(7, 5)); + const Temp_Type X126 = D(F(-0.074658f) * AT(1, 6) + F(0.513280f) * AT(3, 6) + F(0.768178f) * AT(5, 6) + F(-0.375330f) * AT(7, 6)); + const Temp_Type X127 = D(F(-0.074658f) * AT(1, 7) + F(0.513280f) * AT(3, 7) + F(0.768178f) * AT(5, 7) + F(-0.375330f) * AT(7, 7)); + const Temp_Type X130 = AT(6, 0); + const Temp_Type X131 = AT(6, 1); + const Temp_Type X132 = AT(6, 2); + const Temp_Type X133 = AT(6, 3); + const Temp_Type X134 = AT(6, 4); + const Temp_Type X135 = AT(6, 5); + const Temp_Type X136 = AT(6, 6); + const Temp_Type X137 = AT(6, 7); + // 80 muls 48 adds + + // 4x4 = 4x8 times 8x4, matrix 1 is constant + R.at(0, 0) = X100; + R.at(0, 1) = D(X101 * F(0.415735f) + X103 * F(0.791065f) + X105 * F(-0.352443f) + X107 * F(0.277785f)); + R.at(0, 2) = X104; + R.at(0, 3) = D(X101 * F(0.022887f) + X103 * F(-0.097545f) + X105 * F(0.490393f) + X107 * F(0.865723f)); + R.at(1, 0) = X110; + R.at(1, 1) = D(X111 * F(0.415735f) + X113 * F(0.791065f) + X115 * F(-0.352443f) + X117 * F(0.277785f)); + R.at(1, 2) = X114; + R.at(1, 3) = D(X111 * F(0.022887f) + X113 * F(-0.097545f) + X115 * F(0.490393f) + X117 * F(0.865723f)); + R.at(2, 0) = X120; + R.at(2, 1) = D(X121 * F(0.415735f) + X123 * F(0.791065f) + X125 * F(-0.352443f) + X127 * F(0.277785f)); + R.at(2, 2) = X124; + R.at(2, 3) = D(X121 * F(0.022887f) + X123 * F(-0.097545f) + X125 * F(0.490393f) + X127 * F(0.865723f)); + R.at(3, 0) = X130; + R.at(3, 1) = D(X131 * F(0.415735f) + X133 * F(0.791065f) + X135 * F(-0.352443f) + X137 * F(0.277785f)); + R.at(3, 2) = X134; + R.at(3, 3) = D(X131 * F(0.022887f) + X133 * F(-0.097545f) + X135 * F(0.490393f) + X137 * F(0.865723f)); + // 40 muls 24 adds + // 4x4 = 4x8 times 8x4, matrix 1 is constant + S.at(0, 0) = D(X101 * F(0.906127f) + X103 * F(-0.318190f) + X105 * F(0.212608f) + X107 * F(-0.180240f)); + S.at(0, 1) = X102; + S.at(0, 2) = D(X101 * F(-0.074658f) + X103 * F(0.513280f) + X105 * F(0.768178f) + X107 * F(-0.375330f)); + S.at(0, 3) = X106; + S.at(1, 0) = D(X111 * F(0.906127f) + X113 * F(-0.318190f) + X115 * F(0.212608f) + X117 * F(-0.180240f)); + S.at(1, 1) = X112; + S.at(1, 2) = D(X111 * F(-0.074658f) + X113 * F(0.513280f) + X115 * F(0.768178f) + X117 * F(-0.375330f)); + S.at(1, 3) = X116; + S.at(2, 0) = D(X121 * F(0.906127f) + X123 * F(-0.318190f) + X125 * F(0.212608f) + X127 * F(-0.180240f)); + S.at(2, 1) = X122; + S.at(2, 2) = D(X121 * F(-0.074658f) + X123 * F(0.513280f) + X125 * F(0.768178f) + X127 * F(-0.375330f)); + S.at(2, 3) = X126; + S.at(3, 0) = D(X131 * F(0.906127f) + X133 * F(-0.318190f) + X135 * F(0.212608f) + X137 * F(-0.180240f)); + S.at(3, 1) = X132; + S.at(3, 2) = D(X131 * F(-0.074658f) + X133 * F(0.513280f) + X135 * F(0.768178f) + X137 * F(-0.375330f)); + S.at(3, 3) = X136; + // 40 muls 24 adds + } + }; +} // end namespace DCT_Upsample + + +// Unconditionally frees all allocated m_blocks. +void jpeg_decoder::free_all_blocks() +{ + m_pStream = nullptr; + for (mem_block *b = m_pMem_blocks; b; ) { + mem_block *n = b->m_pNext; + free(b); + b = n; + } + m_pMem_blocks = nullptr; +} + + +// This method handles all errors. It will never return. +// It could easily be changed to use C++ exceptions. +JPGD_NORETURN void jpeg_decoder::stop_decoding(jpgd_status status) +{ + m_error_code = status; + free_all_blocks(); + longjmp(m_jmp_state, status); +} + + +void *jpeg_decoder::alloc(size_t nSize, bool zero) +{ + nSize = (JPGD_MAX(nSize, 1) + 3) & ~3; + char *rv = nullptr; + for (mem_block *b = m_pMem_blocks; b; b = b->m_pNext) { + if ((b->m_used_count + nSize) <= b->m_size) { + rv = b->m_data + b->m_used_count; + b->m_used_count += nSize; + break; + } + } + if (!rv) { + int capacity = JPGD_MAX(32768 - 256, (nSize + 2047) & ~2047); + mem_block *b = (mem_block*)malloc(sizeof(mem_block) + capacity); + if (!b) stop_decoding(JPGD_NOTENOUGHMEM); + b->m_pNext = m_pMem_blocks; m_pMem_blocks = b; + b->m_used_count = nSize; + b->m_size = capacity; + rv = b->m_data; + } + if (zero) memset(rv, 0, nSize); + return rv; +} + + +void jpeg_decoder::word_clear(void *p, uint16_t c, uint32_t n) +{ + uint8_t *pD = (uint8_t*)p; + const uint8_t l = c & 0xFF, h = (c >> 8) & 0xFF; + while (n) { + pD[0] = l; pD[1] = h; pD += 2; + n--; + } +} + + +// Refill the input buffer. +// This method will sit in a loop until (A) the buffer is full or (B) +// the stream's read() method reports and end of file condition. +void jpeg_decoder::prep_in_buffer() +{ + m_in_buf_left = 0; + m_pIn_buf_ofs = m_in_buf; + + if (m_eof_flag) return; + + do { + int bytes_read = m_pStream->read(m_in_buf + m_in_buf_left, JPGD_IN_BUF_SIZE - m_in_buf_left, &m_eof_flag); + if (bytes_read == -1) stop_decoding(JPGD_STREAM_READ); + m_in_buf_left += bytes_read; + } while ((m_in_buf_left < JPGD_IN_BUF_SIZE) && (!m_eof_flag)); + + m_total_bytes_read += m_in_buf_left; + + // Pad the end of the block with M_EOI (prevents the decompressor from going off the rails if the stream is invalid). + // (This dates way back to when this decompressor was written in C/asm, and the all-asm Huffman decoder did some fancy things to increase perf.) + word_clear(m_pIn_buf_ofs + m_in_buf_left, 0xD9FF, 64); +} + + +// Read a Huffman code table. +void jpeg_decoder::read_dht_marker() +{ + int i, index, count; + uint8_t huff_num[17]; + uint8_t huff_val[256]; + uint32_t num_left = get_bits(16); + + if (num_left < 2) stop_decoding(JPGD_BAD_DHT_MARKER); + num_left -= 2; + + while (num_left) { + index = get_bits(8); + huff_num[0] = 0; + count = 0; + + for (i = 1; i <= 16; i++) { + huff_num[i] = static_cast<uint8_t>(get_bits(8)); + count += huff_num[i]; + } + + if (count > 255) stop_decoding(JPGD_BAD_DHT_COUNTS); + + for (i = 0; i < count; i++) + huff_val[i] = static_cast<uint8_t>(get_bits(8)); + + i = 1 + 16 + count; + + if (num_left < (uint32_t)i) stop_decoding(JPGD_BAD_DHT_MARKER); + num_left -= i; + + if ((index & 0x10) > 0x10) stop_decoding(JPGD_BAD_DHT_INDEX); + index = (index & 0x0F) + ((index & 0x10) >> 4) * (JPGD_MAX_HUFF_TABLES >> 1); + if (index >= JPGD_MAX_HUFF_TABLES) stop_decoding(JPGD_BAD_DHT_INDEX); + + if (!m_huff_num[index]) m_huff_num[index] = (uint8_t *)alloc(17); + if (!m_huff_val[index]) m_huff_val[index] = (uint8_t *)alloc(256); + + m_huff_ac[index] = (index & 0x10) != 0; + memcpy(m_huff_num[index], huff_num, 17); + memcpy(m_huff_val[index], huff_val, 256); + } +} + + +// Read a quantization table. +void jpeg_decoder::read_dqt_marker() +{ + int n, i, prec; + uint32_t temp; + uint32_t num_left = get_bits(16); + if (num_left < 2) stop_decoding(JPGD_BAD_DQT_MARKER); + num_left -= 2; + + while (num_left) { + n = get_bits(8); + prec = n >> 4; + n &= 0x0F; + + if (n >= JPGD_MAX_QUANT_TABLES) stop_decoding(JPGD_BAD_DQT_TABLE); + + if (!m_quant[n]) m_quant[n] = (jpgd_quant_t *)alloc(64 * sizeof(jpgd_quant_t)); + + // read quantization entries, in zag order + for (i = 0; i < 64; i++) { + temp = get_bits(8); + if (prec) temp = (temp << 8) + get_bits(8); + m_quant[n][i] = static_cast<jpgd_quant_t>(temp); + } + i = 64 + 1; + if (prec) i += 64; + if (num_left < (uint32_t)i) stop_decoding(JPGD_BAD_DQT_LENGTH); + num_left -= i; + } +} + + +// Read the start of frame (SOF) marker. +void jpeg_decoder::read_sof_marker() +{ + int i; + uint32_t num_left = get_bits(16); + + if (get_bits(8) != 8) stop_decoding(JPGD_BAD_PRECISION); /* precision: sorry, only 8-bit precision is supported right now */ + + m_image_y_size = get_bits(16); + if ((m_image_y_size < 1) || (m_image_y_size > JPGD_MAX_HEIGHT)) stop_decoding(JPGD_BAD_HEIGHT); + + m_image_x_size = get_bits(16); + if ((m_image_x_size < 1) || (m_image_x_size > JPGD_MAX_WIDTH)) stop_decoding(JPGD_BAD_WIDTH); + + m_comps_in_frame = get_bits(8); + if (m_comps_in_frame > JPGD_MAX_COMPONENTS) stop_decoding(JPGD_TOO_MANY_COMPONENTS); + + if (num_left != (uint32_t)(m_comps_in_frame * 3 + 8)) stop_decoding(JPGD_BAD_SOF_LENGTH); + + for (i = 0; i < m_comps_in_frame; i++) { + m_comp_ident[i] = get_bits(8); + m_comp_h_samp[i] = get_bits(4); + m_comp_v_samp[i] = get_bits(4); + m_comp_quant[i] = get_bits(8); + } +} + + +// Used to skip unrecognized markers. +void jpeg_decoder::skip_variable_marker() +{ + uint32_t num_left = get_bits(16); + if (num_left < 2) stop_decoding(JPGD_BAD_VARIABLE_MARKER); + num_left -= 2; + + while (num_left) { + get_bits(8); + num_left--; + } +} + + +// Read a define restart interval (DRI) marker. +void jpeg_decoder::read_dri_marker() +{ + if (get_bits(16) != 4) stop_decoding(JPGD_BAD_DRI_LENGTH); + m_restart_interval = get_bits(16); +} + + +// Read a start of scan (SOS) marker. +void jpeg_decoder::read_sos_marker() +{ + int i, ci, c, cc; + uint32_t num_left = get_bits(16); + int n = get_bits(8); + + m_comps_in_scan = n; + num_left -= 3; + + if ( (num_left != (uint32_t)(n * 2 + 3)) || (n < 1) || (n > JPGD_MAX_COMPS_IN_SCAN) ) stop_decoding(JPGD_BAD_SOS_LENGTH); + + for (i = 0; i < n; i++) { + cc = get_bits(8); + c = get_bits(8); + num_left -= 2; + + for (ci = 0; ci < m_comps_in_frame; ci++) + if (cc == m_comp_ident[ci]) break; + + if (ci >= m_comps_in_frame) stop_decoding(JPGD_BAD_SOS_COMP_ID); + + m_comp_list[i] = ci; + m_comp_dc_tab[ci] = (c >> 4) & 15; + m_comp_ac_tab[ci] = (c & 15) + (JPGD_MAX_HUFF_TABLES >> 1); + } + m_spectral_start = get_bits(8); + m_spectral_end = get_bits(8); + m_successive_high = get_bits(4); + m_successive_low = get_bits(4); + + if (!m_progressive_flag) { + m_spectral_start = 0; + m_spectral_end = 63; + } + num_left -= 3; + + while (num_left) { /* read past whatever is num_left */ + get_bits(8); + num_left--; + } +} + + +// Finds the next marker. +int jpeg_decoder::next_marker() +{ + uint32_t c, bytes = 0; + + do { + do { + bytes++; + c = get_bits(8); + } while (c != 0xFF); + + do { + c = get_bits(8); + } while (c == 0xFF); + } while (c == 0); + + // If bytes > 0 here, there where extra bytes before the marker (not good). + return c; +} + + +// Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is +// encountered. +int jpeg_decoder::process_markers() +{ + int c; + + for ( ; ; ) { + c = next_marker(); + switch (c) { + case M_SOF0: + case M_SOF1: + case M_SOF2: + case M_SOF3: + case M_SOF5: + case M_SOF6: + case M_SOF7: + // case M_JPG: + case M_SOF9: + case M_SOF10: + case M_SOF11: + case M_SOF13: + case M_SOF14: + case M_SOF15: + case M_SOI: + case M_EOI: + case M_SOS: return c; + case M_DHT: { + read_dht_marker(); + break; + } + // No arithmitic support - dumb patents! + case M_DAC: { + stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT); + break; + } + case M_DQT: { + read_dqt_marker(); + break; + } + case M_DRI: { + read_dri_marker(); + break; + } + //case M_APP0: /* no need to read the JFIF marker */ + case M_JPG: + case M_RST0: /* no parameters */ + case M_RST1: + case M_RST2: + case M_RST3: + case M_RST4: + case M_RST5: + case M_RST6: + case M_RST7: + case M_TEM: { + stop_decoding(JPGD_UNEXPECTED_MARKER); + break; + } + default: { /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */ + skip_variable_marker(); + break; + } + } + } +} + + +// Finds the start of image (SOI) marker. +// This code is rather defensive: it only checks the first 512 bytes to avoid +// false positives. +void jpeg_decoder::locate_soi_marker() +{ + uint32_t lastchar = get_bits(8); + uint32_t thischar = get_bits(8); + + /* ok if it's a normal JPEG file without a special header */ + if ((lastchar == 0xFF) && (thischar == M_SOI)) return; + + uint32_t bytesleft = 4096; //512; + + while (true) { + if (--bytesleft == 0) stop_decoding(JPGD_NOT_JPEG); + + lastchar = thischar; + thischar = get_bits(8); + + if (lastchar == 0xFF) { + if (thischar == M_SOI) break; + else if (thischar == M_EOI) stop_decoding(JPGD_NOT_JPEG); // get_bits will keep returning M_EOI if we read past the end + } + } + + // Check the next character after marker: if it's not 0xFF, it can't be the start of the next marker, so the file is bad. + thischar = (m_bit_buf >> 24) & 0xFF; + if (thischar != 0xFF) stop_decoding(JPGD_NOT_JPEG); +} + + +// Find a start of frame (SOF) marker. +void jpeg_decoder::locate_sof_marker() +{ + locate_soi_marker(); + int c = process_markers(); + + switch (c) { + case M_SOF2: m_progressive_flag = true; + case M_SOF0: /* baseline DCT */ + case M_SOF1: { /* extended sequential DCT */ + read_sof_marker(); + break; + } + case M_SOF9: { /* Arithmitic coding */ + stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT); + break; + } + default: { + stop_decoding(JPGD_UNSUPPORTED_MARKER); + break; + } + } +} + + +// Find a start of scan (SOS) marker. +int jpeg_decoder::locate_sos_marker() +{ + int c = process_markers(); + if (c == M_EOI) return false; + else if (c != M_SOS) stop_decoding(JPGD_UNEXPECTED_MARKER); + read_sos_marker(); + return true; +} + + +// Reset everything to default/uninitialized state. +void jpeg_decoder::init(jpeg_decoder_stream *pStream) +{ + m_pMem_blocks = nullptr; + m_error_code = JPGD_SUCCESS; + m_ready_flag = false; + m_image_x_size = m_image_y_size = 0; + m_pStream = pStream; + m_progressive_flag = false; + + memset(m_huff_ac, 0, sizeof(m_huff_ac)); + memset(m_huff_num, 0, sizeof(m_huff_num)); + memset(m_huff_val, 0, sizeof(m_huff_val)); + memset(m_quant, 0, sizeof(m_quant)); + + m_scan_type = 0; + m_comps_in_frame = 0; + + memset(m_comp_h_samp, 0, sizeof(m_comp_h_samp)); + memset(m_comp_v_samp, 0, sizeof(m_comp_v_samp)); + memset(m_comp_quant, 0, sizeof(m_comp_quant)); + memset(m_comp_ident, 0, sizeof(m_comp_ident)); + memset(m_comp_h_blocks, 0, sizeof(m_comp_h_blocks)); + memset(m_comp_v_blocks, 0, sizeof(m_comp_v_blocks)); + + m_comps_in_scan = 0; + memset(m_comp_list, 0, sizeof(m_comp_list)); + memset(m_comp_dc_tab, 0, sizeof(m_comp_dc_tab)); + memset(m_comp_ac_tab, 0, sizeof(m_comp_ac_tab)); + + m_spectral_start = 0; + m_spectral_end = 0; + m_successive_low = 0; + m_successive_high = 0; + m_max_mcu_x_size = 0; + m_max_mcu_y_size = 0; + m_blocks_per_mcu = 0; + m_max_blocks_per_row = 0; + m_mcus_per_row = 0; + m_mcus_per_col = 0; + m_expanded_blocks_per_component = 0; + m_expanded_blocks_per_mcu = 0; + m_expanded_blocks_per_row = 0; + m_freq_domain_chroma_upsample = false; + + memset(m_mcu_org, 0, sizeof(m_mcu_org)); + + m_total_lines_left = 0; + m_mcu_lines_left = 0; + m_real_dest_bytes_per_scan_line = 0; + m_dest_bytes_per_scan_line = 0; + m_dest_bytes_per_pixel = 0; + + memset(m_pHuff_tabs, 0, sizeof(m_pHuff_tabs)); + + memset(m_dc_coeffs, 0, sizeof(m_dc_coeffs)); + memset(m_ac_coeffs, 0, sizeof(m_ac_coeffs)); + memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu)); + + m_eob_run = 0; + + memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu)); + + m_pIn_buf_ofs = m_in_buf; + m_in_buf_left = 0; + m_eof_flag = false; + m_tem_flag = 0; + + memset(m_in_buf_pad_start, 0, sizeof(m_in_buf_pad_start)); + memset(m_in_buf, 0, sizeof(m_in_buf)); + memset(m_in_buf_pad_end, 0, sizeof(m_in_buf_pad_end)); + + m_restart_interval = 0; + m_restarts_left = 0; + m_next_restart_num = 0; + + m_max_mcus_per_row = 0; + m_max_blocks_per_mcu = 0; + m_max_mcus_per_col = 0; + + memset(m_last_dc_val, 0, sizeof(m_last_dc_val)); + m_pMCU_coefficients = nullptr; + m_pSample_buf = nullptr; + + m_total_bytes_read = 0; + + m_pScan_line_0 = nullptr; + m_pScan_line_1 = nullptr; + + // Ready the input buffer. + prep_in_buffer(); + + // Prime the bit buffer. + m_bits_left = 16; + m_bit_buf = 0; + + get_bits(16); + get_bits(16); + + for (int i = 0; i < JPGD_MAX_BLOCKS_PER_MCU; i++) { + m_mcu_block_max_zag[i] = 64; + } +} + +#define SCALEBITS 16 +#define ONE_HALF ((int) 1 << (SCALEBITS-1)) +#define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5f)) + + +// Create a few tables that allow us to quickly convert YCbCr to RGB. +void jpeg_decoder::create_look_ups() +{ + for (int i = 0; i <= 255; i++) { + int k = i - 128; + m_crr[i] = ( FIX(1.40200f) * k + ONE_HALF) >> SCALEBITS; + m_cbb[i] = ( FIX(1.77200f) * k + ONE_HALF) >> SCALEBITS; + m_crg[i] = (-FIX(0.71414f)) * k; + m_cbg[i] = (-FIX(0.34414f)) * k + ONE_HALF; + } +} + + +// This method throws back into the stream any bytes that where read +// into the bit buffer during initial marker scanning. +void jpeg_decoder::fix_in_buffer() +{ + // In case any 0xFF's where pulled into the buffer during marker scanning. + JPGD_ASSERT((m_bits_left & 7) == 0); + + if (m_bits_left == 16) stuff_char( (uint8_t)(m_bit_buf & 0xFF)); + if (m_bits_left >= 8) stuff_char( (uint8_t)((m_bit_buf >> 8) & 0xFF)); + + stuff_char((uint8_t)((m_bit_buf >> 16) & 0xFF)); + stuff_char((uint8_t)((m_bit_buf >> 24) & 0xFF)); + + m_bits_left = 16; + get_bits_no_markers(16); + get_bits_no_markers(16); +} + + +void jpeg_decoder::transform_mcu(int mcu_row) +{ + jpgd_block_t* pSrc_ptr = m_pMCU_coefficients; + uint8_t* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64; + + for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) { + idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block]); + pSrc_ptr += 64; + pDst_ptr += 64; + } +} + + +static const uint8_t s_max_rc[64] = +{ + 17, 18, 34, 50, 50, 51, 52, 52, 52, 68, 84, 84, 84, 84, 85, 86, 86, 86, 86, 86, + 102, 118, 118, 118, 118, 118, 118, 119, 120, 120, 120, 120, 120, 120, 120, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136 +}; + + +void jpeg_decoder::transform_mcu_expand(int mcu_row) +{ + jpgd_block_t* pSrc_ptr = m_pMCU_coefficients; + uint8_t* pDst_ptr = m_pSample_buf + mcu_row * m_expanded_blocks_per_mcu * 64; + + // Y IDCT + int mcu_block; + for (mcu_block = 0; mcu_block < m_expanded_blocks_per_component; mcu_block++) { + idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block]); + pSrc_ptr += 64; + pDst_ptr += 64; + } + + // Chroma IDCT, with upsampling + jpgd_block_t temp_block[64]; + + for (int i = 0; i < 2; i++) { + DCT_Upsample::Matrix44 P, Q, R, S; + JPGD_ASSERT(m_mcu_block_max_zag[mcu_block] >= 1); + JPGD_ASSERT(m_mcu_block_max_zag[mcu_block] <= 64); + + int max_zag = m_mcu_block_max_zag[mcu_block++] - 1; + if (max_zag <= 0) max_zag = 0; // should never happen, only here to shut up static analysis + + switch (s_max_rc[max_zag]) { + case 1*16+1: + DCT_Upsample::P_Q<1, 1>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<1, 1>::calc(R, S, pSrc_ptr); + break; + case 1*16+2: + DCT_Upsample::P_Q<1, 2>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<1, 2>::calc(R, S, pSrc_ptr); + break; + case 2*16+2: + DCT_Upsample::P_Q<2, 2>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<2, 2>::calc(R, S, pSrc_ptr); + break; + case 3*16+2: + DCT_Upsample::P_Q<3, 2>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<3, 2>::calc(R, S, pSrc_ptr); + break; + case 3*16+3: + DCT_Upsample::P_Q<3, 3>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<3, 3>::calc(R, S, pSrc_ptr); + break; + case 3*16+4: + DCT_Upsample::P_Q<3, 4>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<3, 4>::calc(R, S, pSrc_ptr); + break; + case 4*16+4: + DCT_Upsample::P_Q<4, 4>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<4, 4>::calc(R, S, pSrc_ptr); + break; + case 5*16+4: + DCT_Upsample::P_Q<5, 4>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<5, 4>::calc(R, S, pSrc_ptr); + break; + case 5*16+5: + DCT_Upsample::P_Q<5, 5>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<5, 5>::calc(R, S, pSrc_ptr); + break; + case 5*16+6: + DCT_Upsample::P_Q<5, 6>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<5, 6>::calc(R, S, pSrc_ptr); + break; + case 6*16+6: + DCT_Upsample::P_Q<6, 6>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<6, 6>::calc(R, S, pSrc_ptr); + break; + case 7*16+6: + DCT_Upsample::P_Q<7, 6>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<7, 6>::calc(R, S, pSrc_ptr); + break; + case 7*16+7: + DCT_Upsample::P_Q<7, 7>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<7, 7>::calc(R, S, pSrc_ptr); + break; + case 7*16+8: + DCT_Upsample::P_Q<7, 8>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<7, 8>::calc(R, S, pSrc_ptr); + break; + case 8*16+8: + DCT_Upsample::P_Q<8, 8>::calc(P, Q, pSrc_ptr); + DCT_Upsample::R_S<8, 8>::calc(R, S, pSrc_ptr); + break; + default: + JPGD_ASSERT(false); + } + DCT_Upsample::Matrix44 a(P + Q); P -= Q; + DCT_Upsample::Matrix44& b = P; + DCT_Upsample::Matrix44 c(R + S); R -= S; + DCT_Upsample::Matrix44& d = R; + + DCT_Upsample::Matrix44::add_and_store(temp_block, a, c); + idct_4x4(temp_block, pDst_ptr); + pDst_ptr += 64; + + DCT_Upsample::Matrix44::sub_and_store(temp_block, a, c); + idct_4x4(temp_block, pDst_ptr); + pDst_ptr += 64; + + DCT_Upsample::Matrix44::add_and_store(temp_block, b, d); + idct_4x4(temp_block, pDst_ptr); + pDst_ptr += 64; + + DCT_Upsample::Matrix44::sub_and_store(temp_block, b, d); + idct_4x4(temp_block, pDst_ptr); + pDst_ptr += 64; + pSrc_ptr += 64; + } +} + + +// Loads and dequantizes the next row of (already decoded) coefficients. +// Progressive images only. +void jpeg_decoder::load_next_row() +{ + int i; + jpgd_block_t *p; + jpgd_quant_t *q; + int mcu_row, mcu_block, row_block = 0; + int component_num, component_id; + int block_x_mcu[JPGD_MAX_COMPONENTS]; + + memset(block_x_mcu, 0, JPGD_MAX_COMPONENTS * sizeof(int)); + + for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) { + int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0; + + for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) { + component_id = m_mcu_org[mcu_block]; + q = m_quant[m_comp_quant[component_id]]; + p = m_pMCU_coefficients + 64 * mcu_block; + + jpgd_block_t* pAC = coeff_buf_getp(m_ac_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); + jpgd_block_t* pDC = coeff_buf_getp(m_dc_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); + p[0] = pDC[0]; + memcpy(&p[1], &pAC[1], 63 * sizeof(jpgd_block_t)); + + for (i = 63; i > 0; i--) { + if (p[g_ZAG[i]]) break; + } + + m_mcu_block_max_zag[mcu_block] = i + 1; + + for ( ; i >= 0; i--) { + if (p[g_ZAG[i]]) { + p[g_ZAG[i]] = static_cast<jpgd_block_t>(p[g_ZAG[i]] * q[i]); + } + } + + row_block++; + + if (m_comps_in_scan == 1) block_x_mcu[component_id]++; + else { + if (++block_x_mcu_ofs == m_comp_h_samp[component_id]) block_x_mcu_ofs = 0; + if (++block_y_mcu_ofs == m_comp_v_samp[component_id]) { + block_y_mcu_ofs = 0; + block_x_mcu[component_id] += m_comp_h_samp[component_id]; + } + } + } + if (m_freq_domain_chroma_upsample) transform_mcu_expand(mcu_row); + else transform_mcu(mcu_row); + } + if (m_comps_in_scan == 1) m_block_y_mcu[m_comp_list[0]]++; + else { + for (component_num = 0; component_num < m_comps_in_scan; component_num++) { + component_id = m_comp_list[component_num]; + m_block_y_mcu[component_id] += m_comp_v_samp[component_id]; + } + } +} + + +// Restart interval processing. +void jpeg_decoder::process_restart() +{ + int i; + int c = 0; + + // Align to a byte boundry + // FIXME: Is this really necessary? get_bits_no_markers() never reads in markers! + //get_bits_no_markers(m_bits_left & 7); + + // Let's scan a little bit to find the marker, but not _too_ far. + // 1536 is a "fudge factor" that determines how much to scan. + for (i = 1536; i > 0; i--) { + if (get_char() == 0xFF) break; + } + if (i == 0) stop_decoding(JPGD_BAD_RESTART_MARKER); + + for ( ; i > 0; i--) { + if ((c = get_char()) != 0xFF) break; + } + if (i == 0) stop_decoding(JPGD_BAD_RESTART_MARKER); + + // Is it the expected marker? If not, something bad happened. + if (c != (m_next_restart_num + M_RST0)) stop_decoding(JPGD_BAD_RESTART_MARKER); + + // Reset each component's DC prediction values. + memset(&m_last_dc_val, 0, m_comps_in_frame * sizeof(uint32_t)); + + m_eob_run = 0; + m_restarts_left = m_restart_interval; + m_next_restart_num = (m_next_restart_num + 1) & 7; + + // Get the bit buffer going again... + m_bits_left = 16; + get_bits_no_markers(16); + get_bits_no_markers(16); +} + + +static inline int dequantize_ac(int c, int q) +{ + c *= q; + return c; +} + +// Decodes and dequantizes the next row of coefficients. +void jpeg_decoder::decode_next_row() +{ + int row_block = 0; + + for (int mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) { + if ((m_restart_interval) && (m_restarts_left == 0)) process_restart(); + + jpgd_block_t* p = m_pMCU_coefficients; + + for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64) { + int component_id = m_mcu_org[mcu_block]; + jpgd_quant_t* q = m_quant[m_comp_quant[component_id]]; + + int r, s; + s = huff_decode(m_pHuff_tabs[m_comp_dc_tab[component_id]], r); + s = JPGD_HUFF_EXTEND(r, s); + + m_last_dc_val[component_id] = (s += m_last_dc_val[component_id]); + + p[0] = static_cast<jpgd_block_t>(s * q[0]); + + int prev_num_set = m_mcu_block_max_zag[mcu_block]; + huff_tables *pH = m_pHuff_tabs[m_comp_ac_tab[component_id]]; + int k; + for (k = 1; k < 64; k++) { + int extra_bits; + s = huff_decode(pH, extra_bits); + r = s >> 4; + s &= 15; + + if (s) { + if (r) { + if ((k + r) > 63) stop_decoding(JPGD_DECODE_ERROR); + if (k < prev_num_set) { + int n = JPGD_MIN(r, prev_num_set - k); + int kt = k; + while (n--) p[g_ZAG[kt++]] = 0; + } + k += r; + } + s = JPGD_HUFF_EXTEND(extra_bits, s); + JPGD_ASSERT(k < 64); + p[g_ZAG[k]] = static_cast<jpgd_block_t>(dequantize_ac(s, q[k])); //s * q[k]; + } else { + if (r == 15) { + if ((k + 16) > 64) stop_decoding(JPGD_DECODE_ERROR); + if (k < prev_num_set) { + int n = JPGD_MIN(16, prev_num_set - k); + int kt = k; + while (n--) { + JPGD_ASSERT(kt <= 63); + p[g_ZAG[kt++]] = 0; + } + } + k += 16 - 1; // - 1 because the loop counter is k + JPGD_ASSERT(p[g_ZAG[k]] == 0); + } else break; + } + } + + if (k < prev_num_set) { + int kt = k; + while (kt < prev_num_set) p[g_ZAG[kt++]] = 0; + } + + m_mcu_block_max_zag[mcu_block] = k; + row_block++; + } + if (m_freq_domain_chroma_upsample) transform_mcu_expand(mcu_row); + else transform_mcu(mcu_row); + m_restarts_left--; + } +} + + +// YCbCr H1V1 (1x1:1:1, 3 m_blocks per MCU) to RGB +void jpeg_decoder::H1V1Convert() +{ + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8_t *d = m_pScan_line_0; + uint8_t *s = m_pSample_buf + row * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) { + for (int j = 0; j < 8; j++) { + int y = s[j]; + int cb = s[64+j]; + int cr = s[128+j]; + + d[0] = clamp(y + m_crr[cr]); + d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16)); + d[2] = clamp(y + m_cbb[cb]); + d[3] = 255; + d += 4; + } + s += 64*3; + } +} + + +// YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB +void jpeg_decoder::H2V1Convert() +{ + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8_t *d0 = m_pScan_line_0; + uint8_t *y = m_pSample_buf + row * 8; + uint8_t *c = m_pSample_buf + 2*64 + row * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) { + for (int l = 0; l < 2; l++) { + for (int j = 0; j < 4; j++) { + int cb = c[0]; + int cr = c[64]; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + int yy = y[j<<1]; + d0[0] = clamp(yy+rc); + d0[1] = clamp(yy+gc); + d0[2] = clamp(yy+bc); + d0[3] = 255; + + yy = y[(j<<1)+1]; + d0[4] = clamp(yy+rc); + d0[5] = clamp(yy+gc); + d0[6] = clamp(yy+bc); + d0[7] = 255; + d0 += 8; + c++; + } + y += 64; + } + y += 64*4 - 64*2; + c += 64*4 - 8; + } +} + + +// YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB +void jpeg_decoder::H1V2Convert() +{ + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8_t *d0 = m_pScan_line_0; + uint8_t *d1 = m_pScan_line_1; + uint8_t *y; + uint8_t *c; + + if (row < 8) y = m_pSample_buf + row * 8; + else y = m_pSample_buf + 64*1 + (row & 7) * 8; + + c = m_pSample_buf + 64*2 + (row >> 1) * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) { + for (int j = 0; j < 8; j++) { + int cb = c[0+j]; + int cr = c[64+j]; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + int yy = y[j]; + d0[0] = clamp(yy+rc); + d0[1] = clamp(yy+gc); + d0[2] = clamp(yy+bc); + d0[3] = 255; + + yy = y[8+j]; + d1[0] = clamp(yy+rc); + d1[1] = clamp(yy+gc); + d1[2] = clamp(yy+bc); + d1[3] = 255; + + d0 += 4; + d1 += 4; + } + y += 64*4; + c += 64*4; + } +} + + +// YCbCr H2V2 (2x2:1:1, 6 m_blocks per MCU) to RGB +void jpeg_decoder::H2V2Convert() +{ + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8_t *d0 = m_pScan_line_0; + uint8_t *d1 = m_pScan_line_1; + uint8_t *y; + uint8_t *c; + + if (row < 8) y = m_pSample_buf + row * 8; + else y = m_pSample_buf + 64*2 + (row & 7) * 8; + + c = m_pSample_buf + 64*4 + (row >> 1) * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) { + for (int l = 0; l < 2; l++) { + for (int j = 0; j < 8; j += 2) { + int cb = c[0]; + int cr = c[64]; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + int yy = y[j]; + d0[0] = clamp(yy+rc); + d0[1] = clamp(yy+gc); + d0[2] = clamp(yy+bc); + d0[3] = 255; + + yy = y[j+1]; + d0[4] = clamp(yy+rc); + d0[5] = clamp(yy+gc); + d0[6] = clamp(yy+bc); + d0[7] = 255; + + yy = y[j+8]; + d1[0] = clamp(yy+rc); + d1[1] = clamp(yy+gc); + d1[2] = clamp(yy+bc); + d1[3] = 255; + + yy = y[j+8+1]; + d1[4] = clamp(yy+rc); + d1[5] = clamp(yy+gc); + d1[6] = clamp(yy+bc); + d1[7] = 255; + + d0 += 8; + d1 += 8; + + c++; + } + y += 64; + } + y += 64*6 - 64*2; + c += 64*6 - 8; + } +} + + +// Y (1 block per MCU) to 8-bit grayscale +void jpeg_decoder::gray_convert() +{ + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8_t *d = m_pScan_line_0; + uint8_t *s = m_pSample_buf + row * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) { + *(uint32_t *)d = *(uint32_t *)s; + *(uint32_t *)(&d[4]) = *(uint32_t *)(&s[4]); + s += 64; + d += 8; + } +} + + +void jpeg_decoder::expanded_convert() +{ + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8_t* Py = m_pSample_buf + (row / 8) * 64 * m_comp_h_samp[0] + (row & 7) * 8; + uint8_t* d = m_pScan_line_0; + + for (int i = m_max_mcus_per_row; i > 0; i--) { + for (int k = 0; k < m_max_mcu_x_size; k += 8) { + const int Y_ofs = k * 8; + const int Cb_ofs = Y_ofs + 64 * m_expanded_blocks_per_component; + const int Cr_ofs = Y_ofs + 64 * m_expanded_blocks_per_component * 2; + for (int j = 0; j < 8; j++) { + int y = Py[Y_ofs + j]; + int cb = Py[Cb_ofs + j]; + int cr = Py[Cr_ofs + j]; + + d[0] = clamp(y + m_crr[cr]); + d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16)); + d[2] = clamp(y + m_cbb[cb]); + d[3] = 255; + + d += 4; + } + } + Py += 64 * m_expanded_blocks_per_mcu; + } +} + + +// Find end of image (EOI) marker, so we can return to the user the exact size of the input stream. +void jpeg_decoder::find_eoi() +{ + if (!m_progressive_flag) { + // Attempt to read the EOI marker. + //get_bits_no_markers(m_bits_left & 7); + + // Prime the bit buffer + m_bits_left = 16; + get_bits(16); + get_bits(16); + + // The next marker _should_ be EOI + process_markers(); + } + m_total_bytes_read -= m_in_buf_left; +} + + +int jpeg_decoder::decode(const void** pScan_line, uint32_t* pScan_line_len) +{ + if ((m_error_code) || (!m_ready_flag)) return JPGD_FAILED; + if (m_total_lines_left == 0) return JPGD_DONE; + if (m_mcu_lines_left == 0) { + if (setjmp(m_jmp_state)) return JPGD_FAILED; + if (m_progressive_flag) load_next_row(); + else decode_next_row(); + // Find the EOI marker if that was the last row. + if (m_total_lines_left <= m_max_mcu_y_size) find_eoi(); + m_mcu_lines_left = m_max_mcu_y_size; + } + + if (m_freq_domain_chroma_upsample) { + expanded_convert(); + *pScan_line = m_pScan_line_0; + } else { + switch (m_scan_type) { + case JPGD_YH2V2: { + if ((m_mcu_lines_left & 1) == 0) { + H2V2Convert(); + *pScan_line = m_pScan_line_0; + } + else *pScan_line = m_pScan_line_1; + break; + } + case JPGD_YH2V1: { + H2V1Convert(); + *pScan_line = m_pScan_line_0; + break; + } + case JPGD_YH1V2: { + if ((m_mcu_lines_left & 1) == 0) { + H1V2Convert(); + *pScan_line = m_pScan_line_0; + } else *pScan_line = m_pScan_line_1; + break; + } + case JPGD_YH1V1: { + H1V1Convert(); + *pScan_line = m_pScan_line_0; + break; + } + case JPGD_GRAYSCALE: { + gray_convert(); + *pScan_line = m_pScan_line_0; + break; + } + } + } + + *pScan_line_len = m_real_dest_bytes_per_scan_line; + m_mcu_lines_left--; + m_total_lines_left--; + + return JPGD_SUCCESS; +} + + +// Creates the tables needed for efficient Huffman decoding. +void jpeg_decoder::make_huff_table(int index, huff_tables *pH) +{ + int p, i, l, si; + uint8_t huffsize[257]; + uint32_t huffcode[257]; + uint32_t code; + uint32_t subtree; + int code_size; + int lastp; + int nextfreeentry; + int currententry; + + pH->ac_table = m_huff_ac[index] != 0; + p = 0; + + for (l = 1; l <= 16; l++) { + for (i = 1; i <= m_huff_num[index][l]; i++) { + huffsize[p++] = static_cast<uint8_t>(l); + } + } + + huffsize[p] = 0; + lastp = p; + code = 0; + si = huffsize[0]; + p = 0; + + while (huffsize[p]) { + while (huffsize[p] == si) { + huffcode[p++] = code; + code++; + } + code <<= 1; + si++; + } + + memset(pH->look_up, 0, sizeof(pH->look_up)); + memset(pH->look_up2, 0, sizeof(pH->look_up2)); + memset(pH->tree, 0, sizeof(pH->tree)); + memset(pH->code_size, 0, sizeof(pH->code_size)); + + nextfreeentry = -1; + p = 0; + + while (p < lastp) { + i = m_huff_val[index][p]; + code = huffcode[p]; + code_size = huffsize[p]; + pH->code_size[i] = static_cast<uint8_t>(code_size); + + if (code_size <= 8) { + code <<= (8 - code_size); + for (l = 1 << (8 - code_size); l > 0; l--) { + JPGD_ASSERT(i < 256); + pH->look_up[code] = i; + bool has_extrabits = false; + int extra_bits = 0; + int num_extra_bits = i & 15; + int bits_to_fetch = code_size; + + if (num_extra_bits) { + int total_codesize = code_size + num_extra_bits; + if (total_codesize <= 8) { + has_extrabits = true; + extra_bits = ((1 << num_extra_bits) - 1) & (code >> (8 - total_codesize)); + JPGD_ASSERT(extra_bits <= 0x7FFF); + bits_to_fetch += num_extra_bits; + } + } + if (!has_extrabits) pH->look_up2[code] = i | (bits_to_fetch << 8); + else pH->look_up2[code] = i | 0x8000 | (extra_bits << 16) | (bits_to_fetch << 8); + code++; + } + } else { + subtree = (code >> (code_size - 8)) & 0xFF; + currententry = pH->look_up[subtree]; + + if (currententry == 0) { + pH->look_up[subtree] = currententry = nextfreeentry; + pH->look_up2[subtree] = currententry = nextfreeentry; + nextfreeentry -= 2; + } + + code <<= (16 - (code_size - 8)); + + for (l = code_size; l > 9; l--) { + if ((code & 0x8000) == 0) currententry--; + if (pH->tree[-currententry - 1] == 0) { + pH->tree[-currententry - 1] = nextfreeentry; + currententry = nextfreeentry; + nextfreeentry -= 2; + } else currententry = pH->tree[-currententry - 1]; + code <<= 1; + } + if ((code & 0x8000) == 0) currententry--; + pH->tree[-currententry - 1] = i; + } + p++; + } +} + + +// Verifies the quantization tables needed for this scan are available. +void jpeg_decoder::check_quant_tables() +{ + for (int i = 0; i < m_comps_in_scan; i++) { + if (m_quant[m_comp_quant[m_comp_list[i]]] == nullptr) stop_decoding(JPGD_UNDEFINED_QUANT_TABLE); + } +} + + +// Verifies that all the Huffman tables needed for this scan are available. +void jpeg_decoder::check_huff_tables() +{ + for (int i = 0; i < m_comps_in_scan; i++) { + if ((m_spectral_start == 0) && (m_huff_num[m_comp_dc_tab[m_comp_list[i]]] == nullptr)) stop_decoding(JPGD_UNDEFINED_HUFF_TABLE); + if ((m_spectral_end > 0) && (m_huff_num[m_comp_ac_tab[m_comp_list[i]]] == nullptr)) stop_decoding(JPGD_UNDEFINED_HUFF_TABLE); + } + + for (int i = 0; i < JPGD_MAX_HUFF_TABLES; i++) { + if (m_huff_num[i]) { + if (!m_pHuff_tabs[i]) m_pHuff_tabs[i] = (huff_tables *)alloc(sizeof(huff_tables)); + make_huff_table(i, m_pHuff_tabs[i]); + } + } +} + + +// Determines the component order inside each MCU. +// Also calcs how many MCU's are on each row, etc. +void jpeg_decoder::calc_mcu_block_order() +{ + int component_num, component_id; + int max_h_samp = 0, max_v_samp = 0; + + for (component_id = 0; component_id < m_comps_in_frame; component_id++) { + if (m_comp_h_samp[component_id] > max_h_samp) { + max_h_samp = m_comp_h_samp[component_id]; + } + if (m_comp_v_samp[component_id] > max_v_samp) { + max_v_samp = m_comp_v_samp[component_id]; + } + } + + for (component_id = 0; component_id < m_comps_in_frame; component_id++) { + m_comp_h_blocks[component_id] = ((((m_image_x_size * m_comp_h_samp[component_id]) + (max_h_samp - 1)) / max_h_samp) + 7) / 8; + m_comp_v_blocks[component_id] = ((((m_image_y_size * m_comp_v_samp[component_id]) + (max_v_samp - 1)) / max_v_samp) + 7) / 8; + } + + if (m_comps_in_scan == 1) { + m_mcus_per_row = m_comp_h_blocks[m_comp_list[0]]; + m_mcus_per_col = m_comp_v_blocks[m_comp_list[0]]; + } else { + m_mcus_per_row = (((m_image_x_size + 7) / 8) + (max_h_samp - 1)) / max_h_samp; + m_mcus_per_col = (((m_image_y_size + 7) / 8) + (max_v_samp - 1)) / max_v_samp; + } + + if (m_comps_in_scan == 1) { + m_mcu_org[0] = m_comp_list[0]; + m_blocks_per_mcu = 1; + } else { + m_blocks_per_mcu = 0; + + for (component_num = 0; component_num < m_comps_in_scan; component_num++) { + int num_blocks; + component_id = m_comp_list[component_num]; + num_blocks = m_comp_h_samp[component_id] * m_comp_v_samp[component_id]; + while (num_blocks--) m_mcu_org[m_blocks_per_mcu++] = component_id; + } + } +} + + +// Starts a new scan. +int jpeg_decoder::init_scan() +{ + if (!locate_sos_marker()) return false; + + calc_mcu_block_order(); + check_huff_tables(); + check_quant_tables(); + + memset(m_last_dc_val, 0, m_comps_in_frame * sizeof(uint32_t)); + + m_eob_run = 0; + + if (m_restart_interval) { + m_restarts_left = m_restart_interval; + m_next_restart_num = 0; + } + fix_in_buffer(); + return true; +} + + +// Starts a frame. Determines if the number of components or sampling factors +// are supported. +void jpeg_decoder::init_frame() +{ + int i; + + if (m_comps_in_frame == 1) { + if ((m_comp_h_samp[0] != 1) || (m_comp_v_samp[0] != 1)) stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); + m_scan_type = JPGD_GRAYSCALE; + m_max_blocks_per_mcu = 1; + m_max_mcu_x_size = 8; + m_max_mcu_y_size = 8; + } else if (m_comps_in_frame == 3) { + if (((m_comp_h_samp[1] != 1) || (m_comp_v_samp[1] != 1)) || ((m_comp_h_samp[2] != 1) || (m_comp_v_samp[2] != 1))) + stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); + + if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 1)) { + m_scan_type = JPGD_YH1V1; + m_max_blocks_per_mcu = 3; + m_max_mcu_x_size = 8; + m_max_mcu_y_size = 8; + } else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 1)) { + m_scan_type = JPGD_YH2V1; + m_max_blocks_per_mcu = 4; + m_max_mcu_x_size = 16; + m_max_mcu_y_size = 8; + } else if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 2)) { + m_scan_type = JPGD_YH1V2; + m_max_blocks_per_mcu = 4; + m_max_mcu_x_size = 8; + m_max_mcu_y_size = 16; + } else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 2)) { + m_scan_type = JPGD_YH2V2; + m_max_blocks_per_mcu = 6; + m_max_mcu_x_size = 16; + m_max_mcu_y_size = 16; + } else stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); + } else stop_decoding(JPGD_UNSUPPORTED_COLORSPACE); + + m_max_mcus_per_row = (m_image_x_size + (m_max_mcu_x_size - 1)) / m_max_mcu_x_size; + m_max_mcus_per_col = (m_image_y_size + (m_max_mcu_y_size - 1)) / m_max_mcu_y_size; + + // These values are for the *destination* pixels: after conversion. + if (m_scan_type == JPGD_GRAYSCALE) m_dest_bytes_per_pixel = 1; + else m_dest_bytes_per_pixel = 4; + + m_dest_bytes_per_scan_line = ((m_image_x_size + 15) & 0xFFF0) * m_dest_bytes_per_pixel; + m_real_dest_bytes_per_scan_line = (m_image_x_size * m_dest_bytes_per_pixel); + + // Initialize two scan line buffers. + m_pScan_line_0 = (uint8_t *)alloc(m_dest_bytes_per_scan_line, true); + if ((m_scan_type == JPGD_YH1V2) || (m_scan_type == JPGD_YH2V2)) { + m_pScan_line_1 = (uint8_t *)alloc(m_dest_bytes_per_scan_line, true); + } + + m_max_blocks_per_row = m_max_mcus_per_row * m_max_blocks_per_mcu; + + // Should never happen + if (m_max_blocks_per_row > JPGD_MAX_BLOCKS_PER_ROW) stop_decoding(JPGD_ASSERTION_ERROR); + + // Allocate the coefficient buffer, enough for one MCU + m_pMCU_coefficients = (jpgd_block_t*)alloc(m_max_blocks_per_mcu * 64 * sizeof(jpgd_block_t)); + + for (i = 0; i < m_max_blocks_per_mcu; i++) { + m_mcu_block_max_zag[i] = 64; + } + + m_expanded_blocks_per_component = m_comp_h_samp[0] * m_comp_v_samp[0]; + m_expanded_blocks_per_mcu = m_expanded_blocks_per_component * m_comps_in_frame; + m_expanded_blocks_per_row = m_max_mcus_per_row * m_expanded_blocks_per_mcu; + // Freq. domain chroma upsampling is only supported for H2V2 subsampling factor (the most common one I've seen). + m_freq_domain_chroma_upsample = false; +#if JPGD_SUPPORT_FREQ_DOMAIN_UPSAMPLING + m_freq_domain_chroma_upsample = (m_expanded_blocks_per_mcu == 4*3); +#endif + + if (m_freq_domain_chroma_upsample) + m_pSample_buf = (uint8_t *)alloc(m_expanded_blocks_per_row * 64); + else + m_pSample_buf = (uint8_t *)alloc(m_max_blocks_per_row * 64); + + m_total_lines_left = m_image_y_size; + m_mcu_lines_left = 0; + create_look_ups(); +} + + +// The coeff_buf series of methods originally stored the coefficients +// into a "virtual" file which was located in EMS, XMS, or a disk file. A cache +// was used to make this process more efficient. Now, we can store the entire +// thing in RAM. +jpeg_decoder::coeff_buf* jpeg_decoder::coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y) +{ + coeff_buf* cb = (coeff_buf*)alloc(sizeof(coeff_buf)); + cb->block_num_x = block_num_x; + cb->block_num_y = block_num_y; + cb->block_len_x = block_len_x; + cb->block_len_y = block_len_y; + cb->block_size = (block_len_x * block_len_y) * sizeof(jpgd_block_t); + cb->pData = (uint8_t *)alloc(cb->block_size * block_num_x * block_num_y, true); + return cb; +} + + +inline jpgd_block_t *jpeg_decoder::coeff_buf_getp(coeff_buf *cb, int block_x, int block_y) +{ + JPGD_ASSERT((block_x < cb->block_num_x) && (block_y < cb->block_num_y)); + return (jpgd_block_t *)(cb->pData + block_x * cb->block_size + block_y * (cb->block_size * cb->block_num_x)); +} + + +// The following methods decode the various types of m_blocks encountered +// in progressively encoded images. +void jpeg_decoder::decode_block_dc_first(jpeg_decoder *pD, int component_id, int block_x, int block_y) +{ + int s, r; + jpgd_block_t *p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y); + + if ((s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_dc_tab[component_id]])) != 0) { + r = pD->get_bits_no_markers(s); + s = JPGD_HUFF_EXTEND(r, s); + } + pD->m_last_dc_val[component_id] = (s += pD->m_last_dc_val[component_id]); + p[0] = static_cast<jpgd_block_t>(s << pD->m_successive_low); +} + + +void jpeg_decoder::decode_block_dc_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y) +{ + if (pD->get_bits_no_markers(1)) { + jpgd_block_t *p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y); + p[0] |= (1 << pD->m_successive_low); + } +} + + +void jpeg_decoder::decode_block_ac_first(jpeg_decoder *pD, int component_id, int block_x, int block_y) +{ + int k, s, r; + + if (pD->m_eob_run) { + pD->m_eob_run--; + return; + } + jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y); + + for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++) { + s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_ac_tab[component_id]]); + r = s >> 4; + s &= 15; + if (s) { + if ((k += r) > 63) pD->stop_decoding(JPGD_DECODE_ERROR); + r = pD->get_bits_no_markers(s); + s = JPGD_HUFF_EXTEND(r, s); + p[g_ZAG[k]] = static_cast<jpgd_block_t>(s << pD->m_successive_low); + } else { + if (r == 15) { + if ((k += 15) > 63) pD->stop_decoding(JPGD_DECODE_ERROR); + } else { + pD->m_eob_run = 1 << r; + if (r) pD->m_eob_run += pD->get_bits_no_markers(r); + pD->m_eob_run--; + break; + } + } + } +} + + +void jpeg_decoder::decode_block_ac_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y) +{ + int s, k, r; + int p1 = 1 << pD->m_successive_low; + int m1 = (-1) << pD->m_successive_low; + jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y); + + JPGD_ASSERT(pD->m_spectral_end <= 63); + + k = pD->m_spectral_start; + + if (pD->m_eob_run == 0) { + for ( ; k <= pD->m_spectral_end; k++) { + s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_ac_tab[component_id]]); + r = s >> 4; + s &= 15; + if (s) { + if (s != 1) pD->stop_decoding(JPGD_DECODE_ERROR); + if (pD->get_bits_no_markers(1)) s = p1; + else s = m1; + } else { + if (r != 15) { + pD->m_eob_run = 1 << r; + if (r) pD->m_eob_run += pD->get_bits_no_markers(r); + break; + } + } + + do { + jpgd_block_t *this_coef = p + g_ZAG[k & 63]; + + if (*this_coef != 0) { + if (pD->get_bits_no_markers(1)) { + if ((*this_coef & p1) == 0) { + if (*this_coef >= 0) *this_coef = static_cast<jpgd_block_t>(*this_coef + p1); + else *this_coef = static_cast<jpgd_block_t>(*this_coef + m1); + } + } + } else { + if (--r < 0) break; + } + k++; + } while (k <= pD->m_spectral_end); + + if ((s) && (k < 64)) { + p[g_ZAG[k]] = static_cast<jpgd_block_t>(s); + } + } + } + + if (pD->m_eob_run > 0) { + for ( ; k <= pD->m_spectral_end; k++) { + jpgd_block_t *this_coef = p + g_ZAG[k & 63]; // logical AND to shut up static code analysis + + if (*this_coef != 0) { + if (pD->get_bits_no_markers(1)) { + if ((*this_coef & p1) == 0) { + if (*this_coef >= 0) *this_coef = static_cast<jpgd_block_t>(*this_coef + p1); + else *this_coef = static_cast<jpgd_block_t>(*this_coef + m1); + } + } + } + } + pD->m_eob_run--; + } +} + + +// Decode a scan in a progressively encoded image. +void jpeg_decoder::decode_scan(pDecode_block_func decode_block_func) +{ + int mcu_row, mcu_col, mcu_block; + int block_x_mcu[JPGD_MAX_COMPONENTS], m_block_y_mcu[JPGD_MAX_COMPONENTS]; + + memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu)); + + for (mcu_col = 0; mcu_col < m_mcus_per_col; mcu_col++) { + int component_num, component_id; + memset(block_x_mcu, 0, sizeof(block_x_mcu)); + + for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) { + int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0; + + if ((m_restart_interval) && (m_restarts_left == 0)) process_restart(); + + for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) { + component_id = m_mcu_org[mcu_block]; + decode_block_func(this, component_id, block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); + + if (m_comps_in_scan == 1) block_x_mcu[component_id]++; + else { + if (++block_x_mcu_ofs == m_comp_h_samp[component_id]) { + block_x_mcu_ofs = 0; + + if (++block_y_mcu_ofs == m_comp_v_samp[component_id]) { + block_y_mcu_ofs = 0; + block_x_mcu[component_id] += m_comp_h_samp[component_id]; + } + } + } + } + m_restarts_left--; + } + + if (m_comps_in_scan == 1) m_block_y_mcu[m_comp_list[0]]++; + else { + for (component_num = 0; component_num < m_comps_in_scan; component_num++) { + component_id = m_comp_list[component_num]; + m_block_y_mcu[component_id] += m_comp_v_samp[component_id]; + } + } + } +} + + +// Decode a progressively encoded image. +void jpeg_decoder::init_progressive() +{ + int i; + + if (m_comps_in_frame == 4) stop_decoding(JPGD_UNSUPPORTED_COLORSPACE); + + // Allocate the coefficient buffers. + for (i = 0; i < m_comps_in_frame; i++) { + m_dc_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 1, 1); + m_ac_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 8, 8); + } + + while (true) { + int dc_only_scan, refinement_scan; + pDecode_block_func decode_block_func; + + if (!init_scan()) break; + + dc_only_scan = (m_spectral_start == 0); + refinement_scan = (m_successive_high != 0); + + if ((m_spectral_start > m_spectral_end) || (m_spectral_end > 63)) stop_decoding(JPGD_BAD_SOS_SPECTRAL); + + if (dc_only_scan) { + if (m_spectral_end) stop_decoding(JPGD_BAD_SOS_SPECTRAL); + } else if (m_comps_in_scan != 1) { /* AC scans can only contain one component */ + stop_decoding(JPGD_BAD_SOS_SPECTRAL); + } + + if ((refinement_scan) && (m_successive_low != m_successive_high - 1)) stop_decoding(JPGD_BAD_SOS_SUCCESSIVE); + + if (dc_only_scan) { + if (refinement_scan) decode_block_func = decode_block_dc_refine; + else decode_block_func = decode_block_dc_first; + } else { + if (refinement_scan) decode_block_func = decode_block_ac_refine; + else decode_block_func = decode_block_ac_first; + } + decode_scan(decode_block_func); + m_bits_left = 16; + get_bits(16); + get_bits(16); + } + + m_comps_in_scan = m_comps_in_frame; + + for (i = 0; i < m_comps_in_frame; i++) { + m_comp_list[i] = i; + } + + calc_mcu_block_order(); +} + + +void jpeg_decoder::init_sequential() +{ + if (!init_scan()) stop_decoding(JPGD_UNEXPECTED_MARKER); +} + + +void jpeg_decoder::decode_start() +{ + init_frame(); + if (m_progressive_flag) init_progressive(); + else init_sequential(); +} + + +void jpeg_decoder::decode_init(jpeg_decoder_stream *pStream) +{ + init(pStream); + locate_sof_marker(); +} + + +jpeg_decoder::jpeg_decoder(jpeg_decoder_stream *pStream) +{ + if (setjmp(m_jmp_state)) return; + decode_init(pStream); +} + + +int jpeg_decoder::begin_decoding() +{ + if (m_ready_flag) return JPGD_SUCCESS; + if (m_error_code) return JPGD_FAILED; + if (setjmp(m_jmp_state)) return JPGD_FAILED; + + decode_start(); + m_ready_flag = true; + + return JPGD_SUCCESS; +} + + +jpeg_decoder::~jpeg_decoder() +{ + free_all_blocks(); + delete(m_pStream); +} + + +void jpeg_decoder_file_stream::close() +{ + if (m_pFile) { + fclose(m_pFile); + m_pFile = nullptr; + } + m_eof_flag = false; + m_error_flag = false; +} + + +jpeg_decoder_file_stream::~jpeg_decoder_file_stream() +{ + close(); +} + + +bool jpeg_decoder_file_stream::open(const char *Pfilename) +{ + close(); + + m_eof_flag = false; + m_error_flag = false; + +#if defined(_MSC_VER) + m_pFile = nullptr; + fopen_s(&m_pFile, Pfilename, "rb"); +#else + m_pFile = fopen(Pfilename, "rb"); +#endif + return m_pFile != nullptr; +} + + +int jpeg_decoder_file_stream::read(uint8_t *pBuf, int max_bytes_to_read, bool *pEOF_flag) +{ + if (!m_pFile) return -1; + + if (m_eof_flag) { + *pEOF_flag = true; + return 0; + } + + if (m_error_flag) return -1; + + int bytes_read = static_cast<int>(fread(pBuf, 1, max_bytes_to_read, m_pFile)); + if (bytes_read < max_bytes_to_read) { + if (ferror(m_pFile)) { + m_error_flag = true; + return -1; + } + m_eof_flag = true; + *pEOF_flag = true; + } + return bytes_read; +} + + +bool jpeg_decoder_mem_stream::open(const uint8_t *pSrc_data, uint32_t size) +{ + close(); + m_pSrc_data = pSrc_data; + m_ofs = 0; + m_size = size; + return true; +} + + +int jpeg_decoder_mem_stream::read(uint8_t *pBuf, int max_bytes_to_read, bool *pEOF_flag) +{ + *pEOF_flag = false; + if (!m_pSrc_data) return -1; + + uint32_t bytes_remaining = m_size - m_ofs; + if ((uint32_t)max_bytes_to_read > bytes_remaining) { + max_bytes_to_read = bytes_remaining; + *pEOF_flag = true; + } + memcpy(pBuf, m_pSrc_data + m_ofs, max_bytes_to_read); + m_ofs += max_bytes_to_read; + + return max_bytes_to_read; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + + +jpeg_decoder* jpgdHeader(const char* data, int size, int* width, int* height) +{ + auto decoder = new jpeg_decoder(new jpeg_decoder_mem_stream((const uint8_t*)data, size)); + if (decoder->get_error_code() != JPGD_SUCCESS) { + delete(decoder); + return nullptr; + } + + if (width) *width = decoder->get_width(); + if (height) *height = decoder->get_height(); + + return decoder; +} + + +jpeg_decoder* jpgdHeader(const char* filename, int* width, int* height) +{ + auto fileStream = new jpeg_decoder_file_stream(); + if (!fileStream->open(filename)) return nullptr; + + auto decoder = new jpeg_decoder(fileStream); + if (decoder->get_error_code() != JPGD_SUCCESS) { + delete(decoder); + return nullptr; + } + + if (width) *width = decoder->get_width(); + if (height) *height = decoder->get_height(); + + return decoder; +} + + +void jpgdDelete(jpeg_decoder* decoder) +{ + delete(decoder); +} + + +unsigned char* jpgdDecompress(jpeg_decoder* decoder) +{ + if (!decoder) return nullptr; + + int req_comps = 4; //TODO: fixed 4 channel components now? + if ((req_comps != 1) && (req_comps != 3) && (req_comps != 4)) return nullptr; + + auto image_width = decoder->get_width(); + auto image_height = decoder->get_height(); + //auto actual_comps = decoder->get_num_components(); + + if (decoder->begin_decoding() != JPGD_SUCCESS) return nullptr; + + const int dst_bpl = image_width * req_comps; + uint8_t *pImage_data = (uint8_t*)malloc(dst_bpl * image_height); + if (!pImage_data) return nullptr; + + for (int y = 0; y < image_height; y++) { + const uint8_t* pScan_line; + uint32_t scan_line_len; + if (decoder->decode((const void**)&pScan_line, &scan_line_len) != JPGD_SUCCESS) { + free(pImage_data); + return nullptr; + } + + uint8_t *pDst = pImage_data + y * dst_bpl; + + //Return as BGRA + if ((req_comps == 4) && (decoder->get_num_components() == 3)) { + for (int x = 0; x < image_width; x++) { + pDst[0] = pScan_line[x*4+2]; + pDst[1] = pScan_line[x*4+1]; + pDst[2] = pScan_line[x*4+0]; + pDst[3] = 255; + pDst += 4; + } + } else if (((req_comps == 1) && (decoder->get_num_components() == 1)) || ((req_comps == 4) && (decoder->get_num_components() == 3))) { + memcpy(pDst, pScan_line, dst_bpl); + } else if (decoder->get_num_components() == 1) { + if (req_comps == 3) { + for (int x = 0; x < image_width; x++) { + uint8_t luma = pScan_line[x]; + pDst[0] = luma; + pDst[1] = luma; + pDst[2] = luma; + pDst += 3; + } + } else { + for (int x = 0; x < image_width; x++) { + uint8_t luma = pScan_line[x]; + pDst[0] = luma; + pDst[1] = luma; + pDst[2] = luma; + pDst[3] = 255; + pDst += 4; + } + } + } else if (decoder->get_num_components() == 3) { + if (req_comps == 1) { + const int YR = 19595, YG = 38470, YB = 7471; + for (int x = 0; x < image_width; x++) { + int r = pScan_line[x*4+0]; + int g = pScan_line[x*4+1]; + int b = pScan_line[x*4+2]; + *pDst++ = static_cast<uint8_t>((r * YR + g * YG + b * YB + 32768) >> 16); + } + } else { + for (int x = 0; x < image_width; x++) { + pDst[0] = pScan_line[x*4+0]; + pDst[1] = pScan_line[x*4+1]; + pDst[2] = pScan_line[x*4+2]; + pDst += 3; + } + } + } + } + return pImage_data; +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h new file mode 100644 index 0000000000..d32ffd99d4 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// jpgd.h - C++ class for JPEG decompression. +// Public domain, Rich Geldreich <richgel99@gmail.com> +#ifndef _TVG_JPGD_H_ +#define _TVG_JPGD_H_ + +class jpeg_decoder; + +jpeg_decoder* jpgdHeader(const char* data, int size, int* width, int* height); +jpeg_decoder* jpgdHeader(const char* filename, int* width, int* height); +unsigned char* jpgdDecompress(jpeg_decoder* decoder); +void jpgdDelete(jpeg_decoder* decoder); + +#endif //_TVG_JPGD_H_ diff --git a/thirdparty/thorvg/src/loaders/png/tvgLodePng.cpp b/thirdparty/thorvg/src/loaders/png/tvgLodePng.cpp new file mode 100644 index 0000000000..f2dfa02875 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/png/tvgLodePng.cpp @@ -0,0 +1,2647 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + LodePNG version 20200306 + + Copyright (c) 2005-2020 Lode Vandevenne + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any sourcedistribution. +*/ + +#include <cstdlib> +#include "tvgLodePng.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +#if defined(_MSC_VER) && (_MSC_VER >= 1310) /*Visual Studio: A few warning types are not desired here.*/ + #pragma warning( disable : 4244 ) /*implicit conversions: not warned by gcc -Wall -Wextra and requires too much casts*/ + #pragma warning( disable : 4996 ) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/ +#endif /*_MSC_VER */ + + +/* convince the compiler to inline a function, for use when this measurably improves performance */ +/* inline is not available in C90, but use it when supported by the compiler */ +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined(__cplusplus) && (__cplusplus >= 199711L)) + #define LODEPNG_INLINE inline +#else + #define LODEPNG_INLINE /* not available */ +#endif + +/* restrict is not available in C90, but use it when supported by the compiler */ +#if (defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) ||\ + (defined(_MSC_VER) && (_MSC_VER >= 1400)) || \ + (defined(__WATCOMC__) && (__WATCOMC__ >= 1250) && !defined(__cplusplus)) + #define LODEPNG_RESTRICT __restrict +#else + #define LODEPNG_RESTRICT /* not available */ +#endif + +#define LODEPNG_MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define LODEPNG_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define LODEPNG_ABS(x) ((x) < 0 ? -(x) : (x)) + + +/* Replacements for C library functions such as memcpy and strlen, to support platforms +where a full C library is not available. The compiler can recognize them and compile +to something as fast. */ + +static void lodepng_memcpy(void* LODEPNG_RESTRICT dst, const void* LODEPNG_RESTRICT src, size_t size) +{ + size_t i; + for (i = 0; i < size; i++) ((char*)dst)[i] = ((const char*)src)[i]; +} + + +static void lodepng_memset(void* LODEPNG_RESTRICT dst, int value, size_t num) +{ + size_t i; + for (i = 0; i < num; i++) ((char*)dst)[i] = (char)value; +} + + +/* does not check memory out of bounds, do not use on untrusted data */ +static size_t lodepng_strlen(const char* a) +{ + const char* orig = a; + /* avoid warning about unused function in case of disabled COMPILE... macros */ + (void)(&lodepng_strlen); + while (*a) a++; + return (size_t)(a - orig); +} + + +/* Safely check if adding two integers will overflow (no undefined +behavior, compiler removing the code, etc...) and output result. */ +static int lodepng_addofl(size_t a, size_t b, size_t* result) +{ + *result = a + b; /* Unsigned addition is well defined and safe in C90 */ + return *result < a; +} + + +/* Safely check if multiplying two integers will overflow (no undefined +behavior, compiler removing the code, etc...) and output result. */ +static int lodepng_mulofl(size_t a, size_t b, size_t* result) +{ + *result = a * b; /* Unsigned multiplication is well defined and safe in C90 */ + return (a != 0 && *result / a != b); +} + + +/* Safely check if a + b > c, even if overflow could happen. */ +static int lodepng_gtofl(size_t a, size_t b, size_t c) +{ + size_t d; + if (lodepng_addofl(a, b, &d)) return 1; + return d > c; +} + + +/* + Often in case of an error a value is assigned to a variable and then it breaks + out of a loop (to go to the cleanup phase of a function). This macro does that. + It makes the error handling code shorter and more readable. + + Example: if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83); +*/ +#define CERROR_BREAK(errorvar, code){\ + errorvar = code;\ + break;\ +} + +/* version of CERROR_BREAK that assumes the common case where the error variable is named "error" */ +#define ERROR_BREAK(code) CERROR_BREAK(error, code) + +/* Set error var to the error code, and return it.*/ +#define CERROR_RETURN_ERROR(errorvar, code){\ + errorvar = code;\ + return code;\ +} + +/* Try the code, if it returns error, also return the error. */ +#define CERROR_TRY_RETURN(call){\ + unsigned error = call;\ + if(error) return error;\ +} + +/* Set error var to the error code, and return from the void function. */ +#define CERROR_RETURN(errorvar, code){\ + errorvar = code;\ + return;\ +} + + +/* dynamic vector of unsigned chars */ +struct ucvector +{ + unsigned char* data; + size_t size; /*used size*/ + size_t allocsize; /*allocated size*/ +}; + + +/* returns 1 if success, 0 if failure ==> nothing done */ +static unsigned ucvector_resize(ucvector* p, size_t size) +{ + if (size > p->allocsize) { + size_t newsize = size + (p->allocsize >> 1u); + void* data = realloc(p->data, newsize); + if(data) { + p->allocsize = newsize; + p->data = (unsigned char*)data; + } + else return 0; /*error: not enough memory*/ + } + p->size = size; + return 1; /*success*/ +} + + +static ucvector ucvector_init(unsigned char* buffer, size_t size) +{ + ucvector v; + v.data = buffer; + v.allocsize = v.size = size; + return v; +} + + +static unsigned lodepng_read32bitInt(const unsigned char* buffer) +{ + return (((unsigned)buffer[0] << 24u) | ((unsigned)buffer[1] << 16u) | ((unsigned)buffer[2] << 8u) | (unsigned)buffer[3]); +} + + +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* // End of common code and tools. Begin of Zlib related code. // */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +struct LodePNGBitReader +{ + const unsigned char* data; + size_t size; /*size of data in bytes*/ + size_t bitsize; /*size of data in bits, end of valid bp values, should be 8*size*/ + size_t bp; + unsigned buffer; /*buffer for reading bits. NOTE: 'unsigned' must support at least 32 bits*/ +}; + + +/* data size argument is in bytes. Returns error if size too large causing overflow */ +static unsigned LodePNGBitReader_init(LodePNGBitReader* reader, const unsigned char* data, size_t size) +{ + size_t temp; + reader->data = data; + reader->size = size; + /* size in bits, return error if overflow (if size_t is 32 bit this supports up to 500MB) */ + if (lodepng_mulofl(size, 8u, &reader->bitsize)) return 105; + /*ensure incremented bp can be compared to bitsize without overflow even when it would be incremented 32 too much and + trying to ensure 32 more bits*/ + if (lodepng_addofl(reader->bitsize, 64u, &temp)) return 105; + reader->bp = 0; + reader->buffer = 0; + return 0; /*ok*/ + } + +/* + ensureBits functions: + Ensures the reader can at least read nbits bits in one or more readBits calls, + safely even if not enough bits are available. + Returns 1 if there are enough bits available, 0 if not. +*/ + +/*See ensureBits documentation above. This one ensures exactly 1 bit */ +/*static unsigned ensureBits1(LodePNGBitReader* reader) { + if(reader->bp >= reader->bitsize) return 0; + reader->buffer = (unsigned)reader->data[reader->bp >> 3u] >> (reader->bp & 7u); + return 1; +}*/ + +/*See ensureBits documentation above. This one ensures up to 9 bits */ +static unsigned ensureBits9(LodePNGBitReader* reader, size_t nbits) +{ + size_t start = reader->bp >> 3u; + size_t size = reader->size; + if (start + 1u < size) { + reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u); + reader->buffer >>= (reader->bp & 7u); + return 1; + } else { + reader->buffer = 0; + if (start + 0u < size) reader->buffer |= reader->data[start + 0]; + reader->buffer >>= (reader->bp & 7u); + return reader->bp + nbits <= reader->bitsize; + } +} + + +/*See ensureBits documentation above. This one ensures up to 17 bits */ +static unsigned ensureBits17(LodePNGBitReader* reader, size_t nbits) +{ + size_t start = reader->bp >> 3u; + size_t size = reader->size; + if (start + 2u < size) { + reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u) | ((unsigned)reader->data[start + 2] << 16u); + reader->buffer >>= (reader->bp & 7u); + return 1; + } else { + reader->buffer = 0; + if (start + 0u < size) reader->buffer |= reader->data[start + 0]; + if (start + 1u < size) reader->buffer |= ((unsigned)reader->data[start + 1] << 8u); + reader->buffer >>= (reader->bp & 7u); + return reader->bp + nbits <= reader->bitsize; + } +} + + +/*See ensureBits documentation above. This one ensures up to 25 bits */ +static LODEPNG_INLINE unsigned ensureBits25(LodePNGBitReader* reader, size_t nbits) +{ + size_t start = reader->bp >> 3u; + size_t size = reader->size; + if (start + 3u < size) { + reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u) | ((unsigned)reader->data[start + 2] << 16u) | ((unsigned)reader->data[start + 3] << 24u); + reader->buffer >>= (reader->bp & 7u); + return 1; + } else { + reader->buffer = 0; + if (start + 0u < size) reader->buffer |= reader->data[start + 0]; + if (start + 1u < size) reader->buffer |= ((unsigned)reader->data[start + 1] << 8u); + if (start + 2u < size) reader->buffer |= ((unsigned)reader->data[start + 2] << 16u); + reader->buffer >>= (reader->bp & 7u); + return reader->bp + nbits <= reader->bitsize; + } +} + + +/*See ensureBits documentation above. This one ensures up to 32 bits */ +static LODEPNG_INLINE unsigned ensureBits32(LodePNGBitReader* reader, size_t nbits) +{ + size_t start = reader->bp >> 3u; + size_t size = reader->size; + if(start + 4u < size) { + reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u) | ((unsigned)reader->data[start + 2] << 16u) | ((unsigned)reader->data[start + 3] << 24u); + reader->buffer >>= (reader->bp & 7u); + reader->buffer |= (((unsigned)reader->data[start + 4] << 24u) << (8u - (reader->bp & 7u))); + return 1; + } else { + reader->buffer = 0; + if (start + 0u < size) reader->buffer |= reader->data[start + 0]; + if (start + 1u < size) reader->buffer |= ((unsigned)reader->data[start + 1] << 8u); + if (start + 2u < size) reader->buffer |= ((unsigned)reader->data[start + 2] << 16u); + if (start + 3u < size) reader->buffer |= ((unsigned)reader->data[start + 3] << 24u); + reader->buffer >>= (reader->bp & 7u); + return reader->bp + nbits <= reader->bitsize; + } +} + + +/* Get bits without advancing the bit pointer. Must have enough bits available with ensureBits. Max nbits is 31. */ +static unsigned peekBits(LodePNGBitReader* reader, size_t nbits) +{ + /* The shift allows nbits to be only up to 31. */ + return reader->buffer & ((1u << nbits) - 1u); +} + + +/* Must have enough bits available with ensureBits */ +static void advanceBits(LodePNGBitReader* reader, size_t nbits) +{ + reader->buffer >>= nbits; + reader->bp += nbits; +} + + +/* Must have enough bits available with ensureBits */ +static unsigned readBits(LodePNGBitReader* reader, size_t nbits) +{ + unsigned result = peekBits(reader, nbits); + advanceBits(reader, nbits); + return result; +} + + +/* Public for testing only. steps and result must have numsteps values. */ +unsigned lode_png_test_bitreader(const unsigned char* data, size_t size, size_t numsteps, const size_t* steps, unsigned* result) +{ + size_t i; + LodePNGBitReader reader; + unsigned error = LodePNGBitReader_init(&reader, data, size); + if (error) return 0; + for (i = 0; i < numsteps; i++) { + size_t step = steps[i]; + unsigned ok; + if (step > 25) ok = ensureBits32(&reader, step); + else if (step > 17) ok = ensureBits25(&reader, step); + else if (step > 9) ok = ensureBits17(&reader, step); + else ok = ensureBits9(&reader, step); + if (!ok) return 0; + result[i] = readBits(&reader, step); + } + return 1; +} + + +static unsigned reverseBits(unsigned bits, unsigned num) +{ + /*TODO: implement faster lookup table based version when needed*/ + unsigned i, result = 0; + for (i = 0; i < num; i++) result |= ((bits >> (num - i - 1u)) & 1u) << i; + return result; +} + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Deflate - Huffman / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#define FIRST_LENGTH_CODE_INDEX 257 +#define LAST_LENGTH_CODE_INDEX 285 +/*256 literals, the end code, some length codes, and 2 unused codes*/ +#define NUM_DEFLATE_CODE_SYMBOLS 288 +/*the distance codes have their own symbols, 30 used, 2 unused*/ +#define NUM_DISTANCE_SYMBOLS 32 +/*the code length codes. 0-15: code lengths, 16: copy previous 3-6 times, 17: 3-10 zeros, 18: 11-138 zeros*/ +#define NUM_CODE_LENGTH_CODES 19 + +/*the base lengths represented by codes 257-285*/ +static const unsigned LENGTHBASE[29] + = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, + 67, 83, 99, 115, 131, 163, 195, 227, 258}; + +/*the extra bits used by codes 257-285 (added to base length)*/ +static const unsigned LENGTHEXTRA[29] + = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 0}; + +/*the base backwards distances (the bits of distance codes appear after length codes and use their own huffman tree)*/ +static const unsigned DISTANCEBASE[30] + = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, + 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; + +/*the extra bits of backwards distances (added to base)*/ +static const unsigned DISTANCEEXTRA[30] + = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; + +/*the order in which "code length alphabet code lengths" are stored as specified by deflate, out of this the huffman +tree of the dynamic huffman tree lengths is generated*/ +static const unsigned CLCL_ORDER[NUM_CODE_LENGTH_CODES] + = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* ////////////////////////////////////////////////////////////////////////// */ + +/* +Huffman tree struct, containing multiple representations of the tree +*/ +struct HuffmanTree +{ + unsigned* codes; /*the huffman codes (bit patterns representing the symbols)*/ + unsigned* lengths; /*the lengths of the huffman codes*/ + unsigned maxbitlen; /*maximum number of bits a single code can get*/ + unsigned numcodes; /*number of symbols in the alphabet = number of codes*/ + /* for reading only */ + unsigned char* table_len; /*length of symbol from lookup table, or max length if secondary lookup needed*/ + unsigned short* table_value; /*value of symbol from lookup table, or pointer to secondary table if needed*/ +}; + + +static void HuffmanTree_init(HuffmanTree* tree) +{ + tree->codes = 0; + tree->lengths = 0; + tree->table_len = 0; + tree->table_value = 0; +} + + +static void HuffmanTree_cleanup(HuffmanTree* tree) +{ + free(tree->codes); + free(tree->lengths); + free(tree->table_len); + free(tree->table_value); +} + + +/* amount of bits for first huffman table lookup (aka root bits), see HuffmanTree_makeTable and huffmanDecodeSymbol.*/ +/* values 8u and 9u work the fastest */ +#define FIRSTBITS 9u + +/* a symbol value too big to represent any valid symbol, to indicate reading disallowed huffman bits combination, +which is possible in case of only 0 or 1 present symbols. */ +#define INVALIDSYMBOL 65535u + +/* make table for huffman decoding */ +static unsigned HuffmanTree_makeTable(HuffmanTree* tree) +{ + static const unsigned headsize = 1u << FIRSTBITS; /*size of the first table*/ + static const unsigned mask = (1u << FIRSTBITS) /*headsize*/ - 1u; + size_t i, numpresent, pointer, size; /*total table size*/ + unsigned* maxlens = (unsigned*)malloc(headsize * sizeof(unsigned)); + if (!maxlens) return 83; /*alloc fail*/ + + /* compute maxlens: max total bit length of symbols sharing prefix in the first table*/ + lodepng_memset(maxlens, 0, headsize * sizeof(*maxlens)); + for (i = 0; i < tree->numcodes; i++) { + unsigned symbol = tree->codes[i]; + unsigned l = tree->lengths[i]; + unsigned index; + if(l <= FIRSTBITS) continue; /*symbols that fit in first table don't increase secondary table size*/ + /*get the FIRSTBITS MSBs, the MSBs of the symbol are encoded first. See later comment about the reversing*/ + index = reverseBits(symbol >> (l - FIRSTBITS), FIRSTBITS); + maxlens[index] = LODEPNG_MAX(maxlens[index], l); + } + /* compute total table size: size of first table plus all secondary tables for symbols longer than FIRSTBITS */ + size = headsize; + for (i = 0; i < headsize; ++i) { + unsigned l = maxlens[i]; + if (l > FIRSTBITS) size += (1u << (l - FIRSTBITS)); + } + tree->table_len = (unsigned char*)malloc(size * sizeof(*tree->table_len)); + tree->table_value = (unsigned short*)malloc(size * sizeof(*tree->table_value)); + if (!tree->table_len || !tree->table_value) { + free(maxlens); + /* freeing tree->table values is done at a higher scope */ + return 83; /*alloc fail*/ + } + /*initialize with an invalid length to indicate unused entries*/ + for (i = 0; i < size; ++i) tree->table_len[i] = 16; + + /*fill in the first table for long symbols: max prefix size and pointer to secondary tables*/ + pointer = headsize; + for (i = 0; i < headsize; ++i) { + unsigned l = maxlens[i]; + if(l <= FIRSTBITS) continue; + tree->table_len[i] = l; + tree->table_value[i] = pointer; + pointer += (1u << (l - FIRSTBITS)); + } + free(maxlens); + + /*fill in the first table for short symbols, or secondary table for long symbols*/ + numpresent = 0; + for (i = 0; i < tree->numcodes; ++i) { + unsigned l = tree->lengths[i]; + unsigned symbol = tree->codes[i]; /*the huffman bit pattern. i itself is the value.*/ + /*reverse bits, because the huffman bits are given in MSB first order but the bit reader reads LSB first*/ + unsigned reverse = reverseBits(symbol, l); + if (l == 0) continue; + numpresent++; + + if (l <= FIRSTBITS) { + /*short symbol, fully in first table, replicated num times if l < FIRSTBITS*/ + unsigned num = 1u << (FIRSTBITS - l); + unsigned j; + for (j = 0; j < num; ++j) { + /*bit reader will read the l bits of symbol first, the remaining FIRSTBITS - l bits go to the MSB's*/ + unsigned index = reverse | (j << l); + if(tree->table_len[index] != 16) return 55; /*invalid tree: long symbol shares prefix with short symbol*/ + tree->table_len[index] = l; + tree->table_value[index] = i; + } + } else { + /*long symbol, shares prefix with other long symbols in first lookup table, needs second lookup*/ + /*the FIRSTBITS MSBs of the symbol are the first table index*/ + unsigned index = reverse & mask; + unsigned maxlen = tree->table_len[index]; + /*log2 of secondary table length, should be >= l - FIRSTBITS*/ + unsigned tablelen = maxlen - FIRSTBITS; + unsigned start = tree->table_value[index]; /*starting index in secondary table*/ + unsigned num = 1u << (tablelen - (l - FIRSTBITS)); /*amount of entries of this symbol in secondary table*/ + unsigned j; + if (maxlen < l) return 55; /*invalid tree: long symbol shares prefix with short symbol*/ + for (j = 0; j < num; ++j) { + unsigned reverse2 = reverse >> FIRSTBITS; /* l - FIRSTBITS bits */ + unsigned index2 = start + (reverse2 | (j << (l - FIRSTBITS))); + tree->table_len[index2] = l; + tree->table_value[index2] = i; + } + } + } + + if (numpresent < 2) { + /* In case of exactly 1 symbol, in theory the huffman symbol needs 0 bits, + but deflate uses 1 bit instead. In case of 0 symbols, no symbols can + appear at all, but such huffman tree could still exist (e.g. if distance + codes are never used). In both cases, not all symbols of the table will be + filled in. Fill them in with an invalid symbol value so returning them from + huffmanDecodeSymbol will cause error. */ + for (i = 0; i < size; ++i) { + if (tree->table_len[i] == 16) { + /* As length, use a value smaller than FIRSTBITS for the head table, + and a value larger than FIRSTBITS for the secondary table, to ensure + valid behavior for advanceBits when reading this symbol. */ + tree->table_len[i] = (i < headsize) ? 1 : (FIRSTBITS + 1); + tree->table_value[i] = INVALIDSYMBOL; + } + } + } else { + /* A good huffman tree has N * 2 - 1 nodes, of which N - 1 are internal nodes. + If that is not the case (due to too long length codes), the table will not + have been fully used, and this is an error (not all bit combinations can be + decoded): an oversubscribed huffman tree, indicated by error 55. */ + for (i = 0; i < size; ++i) { + if (tree->table_len[i] == 16) return 55; + } + } + return 0; +} + + +/* + Second step for the ...makeFromLengths and ...makeFromFrequencies functions. + numcodes, lengths and maxbitlen must already be filled in correctly. return + value is error. +*/ +static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree) +{ + unsigned* blcount; + unsigned* nextcode; + unsigned error = 0; + unsigned bits, n; + + tree->codes = (unsigned*)malloc(tree->numcodes * sizeof(unsigned)); + blcount = (unsigned*)malloc((tree->maxbitlen + 1) * sizeof(unsigned)); + nextcode = (unsigned*)malloc((tree->maxbitlen + 1) * sizeof(unsigned)); + if (!tree->codes || !blcount || !nextcode) error = 83; /*alloc fail*/ + + if (!error) { + for (n = 0; n != tree->maxbitlen + 1; n++) blcount[n] = nextcode[n] = 0; + /*step 1: count number of instances of each code length*/ + for (bits = 0; bits != tree->numcodes; ++bits) ++blcount[tree->lengths[bits]]; + /*step 2: generate the nextcode values*/ + for(bits = 1; bits <= tree->maxbitlen; ++bits) { + nextcode[bits] = (nextcode[bits - 1] + blcount[bits - 1]) << 1u; + } + /*step 3: generate all the codes*/ + for (n = 0; n != tree->numcodes; ++n) { + if (tree->lengths[n] != 0) { + tree->codes[n] = nextcode[tree->lengths[n]]++; + /*remove superfluous bits from the code*/ + tree->codes[n] &= ((1u << tree->lengths[n]) - 1u); + } + } + } + + free(blcount); + free(nextcode); + + if (!error) error = HuffmanTree_makeTable(tree); + return error; +} + + +/* + given the code lengths (as stored in the PNG file), generate the tree as defined + by Deflate. maxbitlen is the maximum bits that a code in the tree can have. + return value is error. +*/ +static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* bitlen, size_t numcodes, unsigned maxbitlen) +{ + unsigned i; + tree->lengths = (unsigned*)malloc(numcodes * sizeof(unsigned)); + if (!tree->lengths) return 83; /*alloc fail*/ + for (i = 0; i != numcodes; ++i) tree->lengths[i] = bitlen[i]; + tree->numcodes = (unsigned)numcodes; /*number of symbols*/ + tree->maxbitlen = maxbitlen; + return HuffmanTree_makeFromLengths2(tree); +} + + +/*get the literal and length code tree of a deflated block with fixed tree, as per the deflate specification*/ +static unsigned generateFixedLitLenTree(HuffmanTree* tree) +{ + unsigned i, error = 0; + unsigned* bitlen = (unsigned*)malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); + if (!bitlen) return 83; /*alloc fail*/ + + /*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/ + for (i = 0; i <= 143; ++i) bitlen[i] = 8; + for (i = 144; i <= 255; ++i) bitlen[i] = 9; + for (i = 256; i <= 279; ++i) bitlen[i] = 7; + for (i = 280; i <= 287; ++i) bitlen[i] = 8; + + error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DEFLATE_CODE_SYMBOLS, 15); + + free(bitlen); + return error; +} + + +/*get the distance code tree of a deflated block with fixed tree, as specified in the deflate specification*/ +static unsigned generateFixedDistanceTree(HuffmanTree* tree) +{ + unsigned i, error = 0; + unsigned* bitlen = (unsigned*)malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); + if (!bitlen) return 83; /*alloc fail*/ + + /*there are 32 distance codes, but 30-31 are unused*/ + for (i = 0; i != NUM_DISTANCE_SYMBOLS; ++i) bitlen[i] = 5; + error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DISTANCE_SYMBOLS, 15); + + free(bitlen); + return error; +} + + +/* + returns the code. The bit reader must already have been ensured at least 15 bits +*/ +static unsigned huffmanDecodeSymbol(LodePNGBitReader* reader, const HuffmanTree* codetree) +{ + unsigned short code = peekBits(reader, FIRSTBITS); + unsigned short l = codetree->table_len[code]; + unsigned short value = codetree->table_value[code]; + if (l <= FIRSTBITS) { + advanceBits(reader, l); + return value; + } else { + unsigned index2; + advanceBits(reader, FIRSTBITS); + index2 = value + peekBits(reader, l - FIRSTBITS); + advanceBits(reader, codetree->table_len[index2] - FIRSTBITS); + return codetree->table_value[index2]; + } +} + + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Inflator (Decompressor) / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/*get the tree of a deflated block with fixed tree, as specified in the deflate specification +Returns error code.*/ +static unsigned getTreeInflateFixed(HuffmanTree* tree_ll, HuffmanTree* tree_d) +{ + unsigned error = generateFixedLitLenTree(tree_ll); + if (error) return error; + return generateFixedDistanceTree(tree_d); +} + + +/*get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree*/ +static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d, LodePNGBitReader* reader) +{ + /*make sure that length values that aren't filled in will be 0, or a wrong tree will be generated*/ + unsigned error = 0; + unsigned n, HLIT, HDIST, HCLEN, i; + + /*see comments in deflateDynamic for explanation of the context and these variables, it is analogous*/ + unsigned* bitlen_ll = 0; /*lit,len code lengths*/ + unsigned* bitlen_d = 0; /*dist code lengths*/ + /*code length code lengths ("clcl"), the bit lengths of the huffman tree used to compress bitlen_ll and bitlen_d*/ + unsigned* bitlen_cl = 0; + HuffmanTree tree_cl; /*the code tree for code length codes (the huffman tree for compressed huffman trees)*/ + + if (!ensureBits17(reader, 14)) return 49; /*error: the bit pointer is or will go past the memory*/ + + /*number of literal/length codes + 257. Unlike the spec, the value 257 is added to it here already*/ + HLIT = readBits(reader, 5) + 257; + /*number of distance codes. Unlike the spec, the value 1 is added to it here already*/ + HDIST = readBits(reader, 5) + 1; + /*number of code length codes. Unlike the spec, the value 4 is added to it here already*/ + HCLEN = readBits(reader, 4) + 4; + + bitlen_cl = (unsigned*)malloc(NUM_CODE_LENGTH_CODES * sizeof(unsigned)); + if(!bitlen_cl) return 83 /*alloc fail*/; + + HuffmanTree_init(&tree_cl); + + while (!error) { + /*read the code length codes out of 3 * (amount of code length codes) bits*/ + if (lodepng_gtofl(reader->bp, HCLEN * 3, reader->bitsize)) { + ERROR_BREAK(50); /*error: the bit pointer is or will go past the memory*/ + } + for (i = 0; i != HCLEN; ++i) { + ensureBits9(reader, 3); /*out of bounds already checked above */ + bitlen_cl[CLCL_ORDER[i]] = readBits(reader, 3); + } + for (i = HCLEN; i != NUM_CODE_LENGTH_CODES; ++i) { + bitlen_cl[CLCL_ORDER[i]] = 0; + } + + error = HuffmanTree_makeFromLengths(&tree_cl, bitlen_cl, NUM_CODE_LENGTH_CODES, 7); + if(error) break; + + /*now we can use this tree to read the lengths for the tree that this function will return*/ + bitlen_ll = (unsigned*)malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); + bitlen_d = (unsigned*)malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); + if (!bitlen_ll || !bitlen_d) ERROR_BREAK(83 /*alloc fail*/); + lodepng_memset(bitlen_ll, 0, NUM_DEFLATE_CODE_SYMBOLS * sizeof(*bitlen_ll)); + lodepng_memset(bitlen_d, 0, NUM_DISTANCE_SYMBOLS * sizeof(*bitlen_d)); + + /*i is the current symbol we're reading in the part that contains the code lengths of lit/len and dist codes*/ + i = 0; + while (i < HLIT + HDIST) { + unsigned code; + ensureBits25(reader, 22); /* up to 15 bits for huffman code, up to 7 extra bits below*/ + code = huffmanDecodeSymbol(reader, &tree_cl); + if (code <= 15) /*a length code*/ { + if (i < HLIT) bitlen_ll[i] = code; + else bitlen_d[i - HLIT] = code; + ++i; + } else if (code == 16) /*repeat previous*/ { + unsigned replength = 3; /*read in the 2 bits that indicate repeat length (3-6)*/ + unsigned value; /*set value to the previous code*/ + + if (i == 0) ERROR_BREAK(54); /*can't repeat previous if i is 0*/ + + replength += readBits(reader, 2); + + if (i < HLIT + 1) value = bitlen_ll[i - 1]; + else value = bitlen_d[i - HLIT - 1]; + /*repeat this value in the next lengths*/ + for (n = 0; n < replength; ++n) { + if (i >= HLIT + HDIST) ERROR_BREAK(13); /*error: i is larger than the amount of codes*/ + if (i < HLIT) bitlen_ll[i] = value; + else bitlen_d[i - HLIT] = value; + ++i; + } + } else if(code == 17) /*repeat "0" 3-10 times*/ { + unsigned replength = 3; /*read in the bits that indicate repeat length*/ + replength += readBits(reader, 3); + + /*repeat this value in the next lengths*/ + for (n = 0; n < replength; ++n) { + if (i >= HLIT + HDIST) ERROR_BREAK(14); /*error: i is larger than the amount of codes*/ + + if (i < HLIT) bitlen_ll[i] = 0; + else bitlen_d[i - HLIT] = 0; + ++i; + } + } else if(code == 18) /*repeat "0" 11-138 times*/ { + unsigned replength = 11; /*read in the bits that indicate repeat length*/ + replength += readBits(reader, 7); + + /*repeat this value in the next lengths*/ + for (n = 0; n < replength; ++n) { + if(i >= HLIT + HDIST) ERROR_BREAK(15); /*error: i is larger than the amount of codes*/ + + if(i < HLIT) bitlen_ll[i] = 0; + else bitlen_d[i - HLIT] = 0; + ++i; + } + } else /*if(code == INVALIDSYMBOL)*/ { + ERROR_BREAK(16); /*error: tried to read disallowed huffman symbol*/ + } + /*check if any of the ensureBits above went out of bounds*/ + if (reader->bp > reader->bitsize) { + /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol + (10=no endcode, 11=wrong jump outside of tree)*/ + /* TODO: revise error codes 10,11,50: the above comment is no longer valid */ + ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ + } + } + if (error) break; + + if (bitlen_ll[256] == 0) ERROR_BREAK(64); /*the length of the end code 256 must be larger than 0*/ + + /*now we've finally got HLIT and HDIST, so generate the code trees, and the function is done*/ + error = HuffmanTree_makeFromLengths(tree_ll, bitlen_ll, NUM_DEFLATE_CODE_SYMBOLS, 15); + if (error) break; + error = HuffmanTree_makeFromLengths(tree_d, bitlen_d, NUM_DISTANCE_SYMBOLS, 15); + + break; /*end of error-while*/ + } + + free(bitlen_cl); + free(bitlen_ll); + free(bitlen_d); + HuffmanTree_cleanup(&tree_cl); + + return error; +} + + +/*inflate a block with dynamic of fixed Huffman tree. btype must be 1 or 2.*/ +static unsigned inflateHuffmanBlock(ucvector* out, LodePNGBitReader* reader, unsigned btype) +{ + unsigned error = 0; + HuffmanTree tree_ll; /*the huffman tree for literal and length codes*/ + HuffmanTree tree_d; /*the huffman tree for distance codes*/ + + HuffmanTree_init(&tree_ll); + HuffmanTree_init(&tree_d); + + if (btype == 1) error = getTreeInflateFixed(&tree_ll, &tree_d); + else /*if(btype == 2)*/ error = getTreeInflateDynamic(&tree_ll, &tree_d, reader); + + while (!error) /*decode all symbols until end reached, breaks at end code*/ { + /*code_ll is literal, length or end code*/ + unsigned code_ll; + ensureBits25(reader, 20); /* up to 15 for the huffman symbol, up to 5 for the length extra bits */ + code_ll = huffmanDecodeSymbol(reader, &tree_ll); + if (code_ll <= 255) /*literal symbol*/ { + if (!ucvector_resize(out, out->size + 1)) ERROR_BREAK(83 /*alloc fail*/); + out->data[out->size - 1] = (unsigned char)code_ll; + } else if (code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX) /*length code*/ { + unsigned code_d, distance; + unsigned numextrabits_l, numextrabits_d; /*extra bits for length and distance*/ + size_t start, backward, length; + + /*part 1: get length base*/ + length = LENGTHBASE[code_ll - FIRST_LENGTH_CODE_INDEX]; + + /*part 2: get extra bits and add the value of that to length*/ + numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX]; + if (numextrabits_l != 0) { + /* bits already ensured above */ + length += readBits(reader, numextrabits_l); + } + + /*part 3: get distance code*/ + ensureBits32(reader, 28); /* up to 15 for the huffman symbol, up to 13 for the extra bits */ + code_d = huffmanDecodeSymbol(reader, &tree_d); + if (code_d > 29) { + if (code_d <= 31) { + ERROR_BREAK(18); /*error: invalid distance code (30-31 are never used)*/ + } else /* if(code_d == INVALIDSYMBOL) */{ + ERROR_BREAK(16); /*error: tried to read disallowed huffman symbol*/ + } + } + distance = DISTANCEBASE[code_d]; + + /*part 4: get extra bits from distance*/ + numextrabits_d = DISTANCEEXTRA[code_d]; + if (numextrabits_d != 0) { + /* bits already ensured above */ + distance += readBits(reader, numextrabits_d); + } + + /*part 5: fill in all the out[n] values based on the length and dist*/ + start = out->size; + if (distance > start) ERROR_BREAK(52); /*too long backward distance*/ + backward = start - distance; + + if (!ucvector_resize(out, out->size + length)) ERROR_BREAK(83 /*alloc fail*/); + if (distance < length) { + size_t forward; + lodepng_memcpy(out->data + start, out->data + backward, distance); + start += distance; + for (forward = distance; forward < length; ++forward) { + out->data[start++] = out->data[backward++]; + } + } else { + lodepng_memcpy(out->data + start, out->data + backward, length); + } + } else if (code_ll == 256) { + break; /*end code, break the loop*/ + } else /*if(code_ll == INVALIDSYMBOL)*/ { + ERROR_BREAK(16); /*error: tried to read disallowed huffman symbol*/ + } + /*check if any of the ensureBits above went out of bounds*/ + if (reader->bp > reader->bitsize) { + /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol + (10=no endcode, 11=wrong jump outside of tree)*/ + /* TODO: revise error codes 10,11,50: the above comment is no longer valid */ + ERROR_BREAK(51); /*error, bit pointer jumps past memory*/ + } + } + + HuffmanTree_cleanup(&tree_ll); + HuffmanTree_cleanup(&tree_d); + + return error; +} + + +static unsigned inflateNoCompression(ucvector* out, LodePNGBitReader* reader, const LodePNGDecompressSettings* settings) +{ + size_t bytepos; + size_t size = reader->size; + unsigned LEN, NLEN, error = 0; + + /*go to first boundary of byte*/ + bytepos = (reader->bp + 7u) >> 3u; + + /*read LEN (2 bytes) and NLEN (2 bytes)*/ + if (bytepos + 4 >= size) return 52; /*error, bit pointer will jump past memory*/ + LEN = (unsigned)reader->data[bytepos] + ((unsigned)reader->data[bytepos + 1] << 8u); bytepos += 2; + NLEN = (unsigned)reader->data[bytepos] + ((unsigned)reader->data[bytepos + 1] << 8u); bytepos += 2; + + /*check if 16-bit NLEN is really the one's complement of LEN*/ + if (!settings->ignore_nlen && LEN + NLEN != 65535) { + return 21; /*error: NLEN is not one's complement of LEN*/ + } + + if (!ucvector_resize(out, out->size + LEN)) return 83; /*alloc fail*/ + + /*read the literal data: LEN bytes are now stored in the out buffer*/ + if (bytepos + LEN > size) return 23; /*error: reading outside of in buffer*/ + + lodepng_memcpy(out->data + out->size - LEN, reader->data + bytepos, LEN); + bytepos += LEN; + + reader->bp = bytepos << 3u; + + return error; +} + + +static unsigned lodepng_inflatev(ucvector* out, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) +{ + unsigned BFINAL = 0; + LodePNGBitReader reader; + unsigned error = LodePNGBitReader_init(&reader, in, insize); + + if (error) return error; + + while (!BFINAL) { + unsigned BTYPE; + if (!ensureBits9(&reader, 3)) return 52; /*error, bit pointer will jump past memory*/ + BFINAL = readBits(&reader, 1); + BTYPE = readBits(&reader, 2); + + if (BTYPE == 3) return 20; /*error: invalid BTYPE*/ + else if (BTYPE == 0) error = inflateNoCompression(out, &reader, settings); /*no compression*/ + else error = inflateHuffmanBlock(out, &reader, BTYPE); /*compression, BTYPE 01 or 10*/ + + if (error) return error; + } + + return error; +} + + +static unsigned inflatev(ucvector* out, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) +{ + if (settings->custom_inflate) { + unsigned error = settings->custom_inflate(&out->data, &out->size, in, insize, settings); + out->allocsize = out->size; + return error; + } else { + return lodepng_inflatev(out, in, insize, settings); + } +} + + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Adler32 / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +static unsigned update_adler32(unsigned adler, const unsigned char* data, unsigned len) +{ + unsigned s1 = adler & 0xffffu; + unsigned s2 = (adler >> 16u) & 0xffffu; + + while (len != 0u) { + unsigned i; + /*at least 5552 sums can be done before the sums overflow, saving a lot of module divisions*/ + unsigned amount = len > 5552u ? 5552u : len; + len -= amount; + for (i = 0; i != amount; ++i) { + s1 += (*data++); + s2 += s1; + } + s1 %= 65521u; + s2 %= 65521u; + } + + return (s2 << 16u) | s1; +} + +/*Return the adler32 of the bytes data[0..len-1]*/ +static unsigned adler32(const unsigned char* data, unsigned len) +{ + return update_adler32(1u, data, len); +} + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Zlib / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +static unsigned lodepng_zlib_decompressv(ucvector* out, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) +{ + unsigned error = 0; + unsigned CM, CINFO, FDICT; + + if (insize < 2) return 53; /*error, size of zlib data too small*/ + /*read information from zlib header*/ + if ((in[0] * 256 + in[1]) % 31 != 0) { + /*error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way*/ + return 24; + } + + CM = in[0] & 15; + CINFO = (in[0] >> 4) & 15; + /*FCHECK = in[1] & 31;*/ /*FCHECK is already tested above*/ + FDICT = (in[1] >> 5) & 1; + /*FLEVEL = (in[1] >> 6) & 3;*/ /*FLEVEL is not used here*/ + + if (CM != 8 || CINFO > 7) { + /*error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec*/ + return 25; + } + if (FDICT != 0) { + /*error: the specification of PNG says about the zlib stream: + "The additional flags shall not specify a preset dictionary."*/ + return 26; + } + + error = inflatev(out, in + 2, insize - 2, settings); + if (error) return error; + + if (!settings->ignore_adler32) { + unsigned ADLER32 = lodepng_read32bitInt(&in[insize - 4]); + unsigned checksum = adler32(out->data, (unsigned)(out->size)); + if(checksum != ADLER32) return 58; /*error, adler checksum not correct, data must be corrupted*/ + } + + return 0; /*no error*/ +} + + +/*expected_size is expected output size, to avoid intermediate allocations. Set to 0 if not known. */ +static unsigned zlib_decompress(unsigned char** out, size_t* outsize, size_t expected_size, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) +{ + if(settings->custom_zlib) { + return settings->custom_zlib(out, outsize, in, insize, settings); + } else { + unsigned error; + ucvector v = ucvector_init(*out, *outsize); + if (expected_size) { + /*reserve the memory to avoid intermediate reallocations*/ + ucvector_resize(&v, *outsize + expected_size); + v.size = *outsize; + } + error = lodepng_zlib_decompressv(&v, in, insize, settings); + *out = v.data; + *outsize = v.size; + return error; + } +} + + +static void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings) +{ + settings->ignore_adler32 = 0; + settings->ignore_nlen = 0; + settings->custom_zlib = 0; + settings->custom_inflate = 0; + settings->custom_context = 0; +} + + +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* // End of Zlib related code. Begin of PNG related code. // */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + + +#if 0 //thorvg don't use crc +/* CRC polynomial: 0xedb88320 */ +static unsigned lodepng_crc32_table[256] = { + 0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u, + 249268274u, 2044508324u, 3772115230u, 2547177864u, 162941995u, 2125561021u, 3887607047u, 2428444049u, + 498536548u, 1789927666u, 4089016648u, 2227061214u, 450548861u, 1843258603u, 4107580753u, 2211677639u, + 325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u, 4195302755u, 2366115317u, + 997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u, + 901097722u, 1119000684u, 3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u, + 651767980u, 1373503546u, 3369554304u, 3218104598u, 565507253u, 1454621731u, 3485111705u, 3099436303u, + 671266974u, 1594198024u, 3322730930u, 2970347812u, 795835527u, 1483230225u, 3244367275u, 3060149565u, + 1994146192u, 31158534u, 2563907772u, 4023717930u, 1907459465u, 112637215u, 2680153253u, 3904427059u, + 2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u, 2439277719u, 3865271297u, + 1802195444u, 476864866u, 2238001368u, 4066508878u, 1812370925u, 453092731u, 2181625025u, 4111451223u, + 1706088902u, 314042704u, 2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u, + 1303535960u, 984961486u, 2747007092u, 3569037538u, 1256170817u, 1037604311u, 2765210733u, 3554079995u, + 1131014506u, 879679996u, 2909243462u, 3663771856u, 1141124467u, 855842277u, 2852801631u, 3708648649u, + 1342533948u, 654459306u, 3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u, + 1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u, 3082640443u, 3233442989u, + 3988292384u, 2596254646u, 62317068u, 1957810842u, 3939845945u, 2647816111u, 81470997u, 1943803523u, + 3814918930u, 2489596804u, 225274430u, 2053790376u, 3826175755u, 2466906013u, 167816743u, 2097651377u, + 4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u, 426522225u, 1852507879u, + 4275313526u, 2312317920u, 282753626u, 1742555852u, 4189708143u, 2394877945u, 397917763u, 1622183637u, + 3604390888u, 2714866558u, 953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u, + 3624741850u, 2936675148u, 906185462u, 1090812512u, 3747672003u, 2825379669u, 829329135u, 1181335161u, + 3412177804u, 3160834842u, 628085408u, 1382605366u, 3423369109u, 3138078467u, 570562233u, 1426400815u, + 3317316542u, 2998733608u, 733239954u, 1555261956u, 3268935591u, 3050360625u, 752459403u, 1541320221u, + 2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u, 1913087877u, 83908371u, + 2512341634u, 3803740692u, 2075208622u, 213261112u, 2463272603u, 3855990285u, 2094854071u, 198958881u, + 2262029012u, 4057260610u, 1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u, + 2282248934u, 4279200368u, 1711684554u, 285281116u, 2405801727u, 4167216745u, 1634467795u, 376229701u, + 2685067896u, 3608007406u, 1308918612u, 956543938u, 2808555105u, 3495958263u, 1231636301u, 1047427035u, + 2932959818u, 3654703836u, 1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u, + 3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u, 1423857449u, 601450431u, + 3009837614u, 3294710456u, 1567103746u, 711928724u, 3020668471u, 3272380065u, 1510334235u, 755167117u +}; + + +/* Calculate CRC32 of buffer + Return the CRC of the bytes buf[0..len-1]. */ +static unsigned lodepng_crc32(const unsigned char* data, size_t length) +{ + unsigned r = 0xffffffffu; + size_t i; + for (i = 0; i < length; ++i) { + r = lodepng_crc32_table[(r ^ data[i]) & 0xffu] ^ (r >> 8u); + } + return r ^ 0xffffffffu; +} +#endif + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Reading and writing PNG color channel bits / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/* The color channel bits of less-than-8-bit pixels are read with the MSB of bytes first, +so LodePNGBitWriter and LodePNGBitReader can't be used for those. */ + +static unsigned char readBitFromReversedStream(size_t* bitpointer, const unsigned char* bitstream) +{ + unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1); + ++(*bitpointer); + return result; +} + + +/* TODO: make this faster */ +static unsigned readBitsFromReversedStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits) +{ + unsigned result = 0; + size_t i; + for (i = 0 ; i < nbits; ++i) { + result <<= 1u; + result |= (unsigned)readBitFromReversedStream(bitpointer, bitstream); + } + return result; +} + + +static void setBitOfReversedStream(size_t* bitpointer, unsigned char* bitstream, unsigned char bit) +{ + /*the current bit in bitstream may be 0 or 1 for this to work*/ + if (bit == 0) bitstream[(*bitpointer) >> 3u] &= (unsigned char)(~(1u << (7u - ((*bitpointer) & 7u)))); + else bitstream[(*bitpointer) >> 3u] |= (1u << (7u - ((*bitpointer) & 7u))); + ++(*bitpointer); +} + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / PNG chunks / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/* + The lodepng_chunk functions are normally not needed, except to traverse the + unknown chunks stored in the LodePNGInfo struct, or add new ones to it. + It also allows traversing the chunks of an encoded PNG file yourself. + + The chunk pointer always points to the beginning of the chunk itself, that is + the first byte of the 4 length bytes. + + In the PNG file format, chunks have the following format: + -4 bytes length: length of the data of the chunk in bytes (chunk itself is 12 bytes longer) + -4 bytes chunk type (ASCII a-z,A-Z only, see below) + -length bytes of data (may be 0 bytes if length was 0) + -4 bytes of CRC, computed on chunk name + data + + The first chunk starts at the 8th byte of the PNG file, the entire rest of the file + exists out of concatenated chunks with the above format. + + PNG standard chunk ASCII naming conventions: + -First byte: uppercase = critical, lowercase = ancillary + -Second byte: uppercase = public, lowercase = private + -Third byte: must be uppercase + -Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy +*/ + + +/* + Gets the length of the data of the chunk. Total chunk length has 12 bytes more. + There must be at least 4 bytes to read from. If the result value is too large, + it may be corrupt data. +*/ +static unsigned lodepng_chunk_length(const unsigned char* chunk) +{ + return lodepng_read32bitInt(&chunk[0]); +} + + +/* check if the type is the given type */ +static unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type) +{ + if (lodepng_strlen(type) != 4) return 0; + return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]); +} + + +/* 0: it's one of the critical chunk types, 1: it's an ancillary chunk (see PNG standard) */ +static unsigned char lodepng_chunk_ancillary(const unsigned char* chunk) +{ + return ((chunk[4] & 32) != 0); +} + + +static const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk) +{ + return &chunk[8]; +} + +#if 0 //thorvg don't use crc +/* returns 0 if the crc is correct, 1 if it's incorrect (0 for OK as usual!) */ +static unsigned lodepng_chunk_check_crc(const unsigned char* chunk) +{ + unsigned length = lodepng_chunk_length(chunk); + unsigned CRC = lodepng_read32bitInt(&chunk[length + 8]); + /*the CRC is taken of the data and the 4 chunk type letters, not the length*/ + unsigned checksum = lodepng_crc32(&chunk[4], length + 4); + if (CRC != checksum) return 1; + else return 0; +} +#endif + +static const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk, const unsigned char* end) +{ + if (chunk >= end || end - chunk < 12) return end; /*too small to contain a chunk*/ + if (chunk[0] == 0x89 && chunk[1] == 0x50 && chunk[2] == 0x4e && chunk[3] == 0x47 + && chunk[4] == 0x0d && chunk[5] == 0x0a && chunk[6] == 0x1a && chunk[7] == 0x0a) { + /* Is PNG magic header at start of PNG file. Jump to first actual chunk. */ + return chunk + 8; + } else { + size_t total_chunk_length; + const unsigned char* result; + if (lodepng_addofl(lodepng_chunk_length(chunk), 12, &total_chunk_length)) return end; + result = chunk + total_chunk_length; + if (result < chunk) return end; /*pointer overflow*/ + return result; + } +} + + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Color types, channels, bits / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/*checks if the colortype is valid and the bitdepth bd is allowed for this colortype. +Return value is a LodePNG error code.*/ +static unsigned checkColorValidity(LodePNGColorType colortype, unsigned bd) +{ + switch(colortype) { + case LCT_GREY: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; break; + case LCT_RGB: if(!( bd == 8 || bd == 16)) return 37; break; + case LCT_PALETTE: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 )) return 37; break; + case LCT_GREY_ALPHA: if(!( bd == 8 || bd == 16)) return 37; break; + case LCT_RGBA: if(!( bd == 8 || bd == 16)) return 37; break; + case LCT_MAX_OCTET_VALUE: return 31; /* invalid color type */ + default: return 31; /* invalid color type */ + } + return 0; /*allowed color type / bits combination*/ +} + + +static unsigned getNumColorChannels(LodePNGColorType colortype) +{ + switch(colortype) { + case LCT_GREY: return 1; + case LCT_RGB: return 3; + case LCT_PALETTE: return 1; + case LCT_GREY_ALPHA: return 2; + case LCT_RGBA: return 4; + case LCT_MAX_OCTET_VALUE: return 0; /* invalid color type */ + default: return 0; /*invalid color type*/ + } +} + + +static unsigned lodepng_get_bpp_lct(LodePNGColorType colortype, unsigned bitdepth) +{ + /*bits per pixel is amount of channels * bits per channel*/ + return getNumColorChannels(colortype) * bitdepth; +} + + +static void lodepng_color_mode_init(LodePNGColorMode* info) +{ + info->key_defined = 0; + info->key_r = info->key_g = info->key_b = 0; + info->colortype = LCT_RGBA; + info->bitdepth = 8; + info->palette = 0; + info->palettesize = 0; +} + + +/*allocates palette memory if needed, and initializes all colors to black*/ +static void lodepng_color_mode_alloc_palette(LodePNGColorMode* info) +{ + size_t i; + /*if the palette is already allocated, it will have size 1024 so no reallocation needed in that case*/ + /*the palette must have room for up to 256 colors with 4 bytes each.*/ + if (!info->palette) info->palette = (unsigned char*)malloc(1024); + if (!info->palette) return; /*alloc fail*/ + for (i = 0; i != 256; ++i) { + /*Initialize all unused colors with black, the value used for invalid palette indices. + This is an error according to the PNG spec, but common PNG decoders make it black instead. + That makes color conversion slightly faster due to no error handling needed.*/ + info->palette[i * 4 + 0] = 0; + info->palette[i * 4 + 1] = 0; + info->palette[i * 4 + 2] = 0; + info->palette[i * 4 + 3] = 255; + } +} + +static void lodepng_palette_clear(LodePNGColorMode* info) +{ + if (info->palette) free(info->palette); + info->palette = 0; + info->palettesize = 0; +} + + +static void lodepng_color_mode_cleanup(LodePNGColorMode* info) +{ + lodepng_palette_clear(info); +} + + +/*return value is error code (0 means no error)*/ +static unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source) +{ + lodepng_color_mode_cleanup(dest); + lodepng_memcpy(dest, source, sizeof(LodePNGColorMode)); + if (source->palette) { + dest->palette = (unsigned char*)malloc(1024); + if (!dest->palette && source->palettesize) return 83; /*alloc fail*/ + lodepng_memcpy(dest->palette, source->palette, source->palettesize * 4); + } + return 0; +} + + +static int lodepng_color_mode_equal(const LodePNGColorMode* a, const LodePNGColorMode* b) +{ + size_t i; + if (a->colortype != b->colortype) return 0; + if (a->bitdepth != b->bitdepth) return 0; + if (a->key_defined != b->key_defined) return 0; + if (a->key_defined) { + if(a->key_r != b->key_r) return 0; + if(a->key_g != b->key_g) return 0; + if(a->key_b != b->key_b) return 0; + } + if (a->palettesize != b->palettesize) return 0; + for (i = 0; i != a->palettesize * 4; ++i) { + if (a->palette[i] != b->palette[i]) return 0; + } + return 1; +} + + +static size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) +{ + size_t bpp = lodepng_get_bpp_lct(colortype, bitdepth); + size_t n = (size_t)w * (size_t)h; + return ((n / 8u) * bpp) + ((n & 7u) * bpp + 7u) / 8u; +} + + +/* Returns the byte size of a raw image buffer with given width, height and color mode */ +static size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color) +{ + return lodepng_get_raw_size_lct(w, h, color->colortype, color->bitdepth); +} + + +/*in an idat chunk, each scanline is a multiple of 8 bits, unlike the lodepng output buffer, +and in addition has one extra byte per line: the filter byte. So this gives a larger +result than lodepng_get_raw_size. Set h to 1 to get the size of 1 row including filter byte. */ +static size_t lodepng_get_raw_size_idat(unsigned w, unsigned h, unsigned bpp) +{ + /* + 1 for the filter byte, and possibly plus padding bits per line. */ + /* Ignoring casts, the expression is equal to (w * bpp + 7) / 8 + 1, but avoids overflow of w * bpp */ + size_t line = ((size_t)(w / 8u) * bpp) + 1u + ((w & 7u) * bpp + 7u) / 8u; + return (size_t)h * line; +} + + +/* Safely checks whether size_t overflow can be caused due to amount of pixels. + This check is overcautious rather than precise. If this check indicates no overflow, + you can safely compute in a size_t (but not an unsigned): + -(size_t)w * (size_t)h * 8 + -amount of bytes in IDAT (including filter, padding and Adam7 bytes) + -amount of bytes in raw color model + Returns 1 if overflow possible, 0 if not. */ +static int lodepng_pixel_overflow(unsigned w, unsigned h, const LodePNGColorMode* pngcolor, const LodePNGColorMode* rawcolor) +{ + size_t bpp = LODEPNG_MAX(lodepng_get_bpp_lct(pngcolor->colortype, pngcolor->bitdepth), lodepng_get_bpp_lct(rawcolor->colortype, rawcolor->bitdepth)); + size_t numpixels, total; + size_t line; /* bytes per line in worst case */ + + if (lodepng_mulofl((size_t)w, (size_t)h, &numpixels)) return 1; + if (lodepng_mulofl(numpixels, 8, &total)) return 1; /* bit pointer with 8-bit color, or 8 bytes per channel color */ + + /* Bytes per scanline with the expression "(w / 8u) * bpp) + ((w & 7u) * bpp + 7u) / 8u" */ + if (lodepng_mulofl((size_t)(w / 8u), bpp, &line)) return 1; + if (lodepng_addofl(line, ((w & 7u) * bpp + 7u) / 8u, &line)) return 1; + + if (lodepng_addofl(line, 5, &line)) return 1; /* 5 bytes overhead per line: 1 filterbyte, 4 for Adam7 worst case */ + if (lodepng_mulofl(line, h, &total)) return 1; /* Total bytes in worst case */ + + return 0; /* no overflow */ +} + + +static void lodepng_info_init(LodePNGInfo* info) +{ + lodepng_color_mode_init(&info->color); + info->interlace_method = 0; + info->compression_method = 0; + info->filter_method = 0; +} + + +static void lodepng_info_cleanup(LodePNGInfo* info) +{ + lodepng_color_mode_cleanup(&info->color); +} + + +/* index: bitgroup index, bits: bitgroup size(1, 2 or 4), in: bitgroup value, out: octet array to add bits to */ +static void addColorBits(unsigned char* out, size_t index, unsigned bits, unsigned in) +{ + unsigned m = bits == 1 ? 7 : bits == 2 ? 3 : 1; /*8 / bits - 1*/ + /*p = the partial index in the byte, e.g. with 4 palettebits it is 0 for first half or 1 for second half*/ + unsigned p = index & m; + in &= (1u << bits) - 1u; /*filter out any other bits of the input value*/ + in = in << (bits * (m - p)); + if(p == 0) out[index * bits / 8u] = in; + else out[index * bits / 8u] |= in; +} + +/* + One node of a color tree + This is the data structure used to count the number of unique colors and to get a palette + index for a color. It's like an octree, but because the alpha channel is used too, each + node has 16 instead of 8 children. +*/ +struct ColorTree +{ + ColorTree* children[16]; /* up to 16 pointers to ColorTree of next level */ + int index; /* the payload. Only has a meaningful value if this is in the last level */ +}; + +static void color_tree_init(ColorTree* tree) +{ + lodepng_memset(tree->children, 0, 16 * sizeof(*tree->children)); + tree->index = -1; +} + +static void color_tree_cleanup(ColorTree* tree) +{ + int i; + for (i = 0; i != 16; ++i) { + if(tree->children[i]) { + color_tree_cleanup(tree->children[i]); + free(tree->children[i]); + } + } +} + + +/* returns -1 if color not present, its index otherwise */ +static int color_tree_get(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + int bit = 0; + for (bit = 0; bit < 8; ++bit) { + int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); + if (!tree->children[i]) return -1; + else tree = tree->children[i]; + } + return tree ? tree->index : -1; +} + + +/* color is not allowed to already exist. + Index should be >= 0 (it's signed to be compatible with using -1 for "doesn't exist") + Returns error code, or 0 if ok */ +static unsigned color_tree_add(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned index) +{ + int bit; + for (bit = 0; bit < 8; ++bit) { + int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); + if (!tree->children[i]) { + tree->children[i] = (ColorTree*)malloc(sizeof(ColorTree)); + if (!tree->children[i]) return 83; /*alloc fail*/ + color_tree_init(tree->children[i]); + } + tree = tree->children[i]; + } + tree->index = (int)index; + return 0; +} + +/* put a pixel, given its RGBA color, into image of any color type */ +static unsigned rgba8ToPixel(unsigned char* out, size_t i, const LodePNGColorMode* mode, ColorTree* tree /*for palette*/, unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + if (mode->colortype == LCT_GREY) { + unsigned char gray = r; /*((unsigned short)r + g + b) / 3u;*/ + if (mode->bitdepth == 8) out[i] = gray; + else if (mode->bitdepth == 16) out[i * 2 + 0] = out[i * 2 + 1] = gray; + else { + /*take the most significant bits of gray*/ + gray = ((unsigned)gray >> (8u - mode->bitdepth)) & ((1u << mode->bitdepth) - 1u); + addColorBits(out, i, mode->bitdepth, gray); + } + } else if (mode->colortype == LCT_RGB) { + if (mode->bitdepth == 8) { + out[i * 3 + 0] = r; + out[i * 3 + 1] = g; + out[i * 3 + 2] = b; + } else { + out[i * 6 + 0] = out[i * 6 + 1] = r; + out[i * 6 + 2] = out[i * 6 + 3] = g; + out[i * 6 + 4] = out[i * 6 + 5] = b; + } + } else if(mode->colortype == LCT_PALETTE) { + int index = color_tree_get(tree, r, g, b, a); + if (index < 0) return 82; /*color not in palette*/ + if (mode->bitdepth == 8) out[i] = index; + else addColorBits(out, i, mode->bitdepth, (unsigned)index); + } else if (mode->colortype == LCT_GREY_ALPHA) { + unsigned char gray = r; /*((unsigned short)r + g + b) / 3u;*/ + if (mode->bitdepth == 8) { + out[i * 2 + 0] = gray; + out[i * 2 + 1] = a; + } else if (mode->bitdepth == 16) { + out[i * 4 + 0] = out[i * 4 + 1] = gray; + out[i * 4 + 2] = out[i * 4 + 3] = a; + } + } else if (mode->colortype == LCT_RGBA) { + if (mode->bitdepth == 8) { + out[i * 4 + 0] = r; + out[i * 4 + 1] = g; + out[i * 4 + 2] = b; + out[i * 4 + 3] = a; + } else { + out[i * 8 + 0] = out[i * 8 + 1] = r; + out[i * 8 + 2] = out[i * 8 + 3] = g; + out[i * 8 + 4] = out[i * 8 + 5] = b; + out[i * 8 + 6] = out[i * 8 + 7] = a; + } + } + return 0; /*no error*/ +} + + +/* put a pixel, given its RGBA16 color, into image of any color 16-bitdepth type */ +static void rgba16ToPixel(unsigned char* out, size_t i, const LodePNGColorMode* mode, unsigned short r, unsigned short g, unsigned short b, unsigned short a) +{ + if (mode->colortype == LCT_GREY) { + unsigned short gray = r; /*((unsigned)r + g + b) / 3u;*/ + out[i * 2 + 0] = (gray >> 8) & 255; + out[i * 2 + 1] = gray & 255; + } else if (mode->colortype == LCT_RGB) { + out[i * 6 + 0] = (r >> 8) & 255; + out[i * 6 + 1] = r & 255; + out[i * 6 + 2] = (g >> 8) & 255; + out[i * 6 + 3] = g & 255; + out[i * 6 + 4] = (b >> 8) & 255; + out[i * 6 + 5] = b & 255; + } else if (mode->colortype == LCT_GREY_ALPHA) { + unsigned short gray = r; /*((unsigned)r + g + b) / 3u;*/ + out[i * 4 + 0] = (gray >> 8) & 255; + out[i * 4 + 1] = gray & 255; + out[i * 4 + 2] = (a >> 8) & 255; + out[i * 4 + 3] = a & 255; + } else if (mode->colortype == LCT_RGBA) { + out[i * 8 + 0] = (r >> 8) & 255; + out[i * 8 + 1] = r & 255; + out[i * 8 + 2] = (g >> 8) & 255; + out[i * 8 + 3] = g & 255; + out[i * 8 + 4] = (b >> 8) & 255; + out[i * 8 + 5] = b & 255; + out[i * 8 + 6] = (a >> 8) & 255; + out[i * 8 + 7] = a & 255; + } +} + + +/* Get RGBA8 color of pixel with index i (y * width + x) from the raw image with given color type. */ +static void getPixelColorRGBA8(unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a, const unsigned char* in, size_t i, const LodePNGColorMode* mode) +{ + if (mode->colortype == LCT_GREY) { + if (mode->bitdepth == 8) { + *r = *g = *b = in[i]; + if (mode->key_defined && *r == mode->key_r) *a = 0; + else *a = 255; + } else if (mode->bitdepth == 16) { + *r = *g = *b = in[i * 2 + 0]; + if (mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0; + else *a = 255; + } else { + unsigned highest = ((1U << mode->bitdepth) - 1U); /* highest possible value for this bit depth */ + size_t j = i * mode->bitdepth; + unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); + *r = *g = *b = (value * 255) / highest; + if (mode->key_defined && value == mode->key_r) *a = 0; + else *a = 255; + } + } else if (mode->colortype == LCT_RGB) { + if (mode->bitdepth == 8) { + *r = in[i * 3 + 0]; *g = in[i * 3 + 1]; *b = in[i * 3 + 2]; + if (mode->key_defined && *r == mode->key_r && *g == mode->key_g && *b == mode->key_b) *a = 0; + else *a = 255; + } else { + *r = in[i * 6 + 0]; + *g = in[i * 6 + 2]; + *b = in[i * 6 + 4]; + if (mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r + && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g + && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; + else *a = 255; + } + } else if (mode->colortype == LCT_PALETTE) { + unsigned index; + if (mode->bitdepth == 8) index = in[i]; + else { + size_t j = i * mode->bitdepth; + index = readBitsFromReversedStream(&j, in, mode->bitdepth); + } + /* out of bounds of palette not checked: see lodepng_color_mode_alloc_palette. */ + *r = mode->palette[index * 4 + 0]; + *g = mode->palette[index * 4 + 1]; + *b = mode->palette[index * 4 + 2]; + *a = mode->palette[index * 4 + 3]; + } else if (mode->colortype == LCT_GREY_ALPHA) { + if (mode->bitdepth == 8) { + *r = *g = *b = in[i * 2 + 0]; + *a = in[i * 2 + 1]; + } else { + *r = *g = *b = in[i * 4 + 0]; + *a = in[i * 4 + 2]; + } + } else if (mode->colortype == LCT_RGBA) { + if (mode->bitdepth == 8) { + *r = in[i * 4 + 0]; + *g = in[i * 4 + 1]; + *b = in[i * 4 + 2]; + *a = in[i * 4 + 3]; + } else { + *r = in[i * 8 + 0]; + *g = in[i * 8 + 2]; + *b = in[i * 8 + 4]; + *a = in[i * 8 + 6]; + } + } +} + + +/* Similar to getPixelColorRGBA8, but with all the for loops inside of the color + mode test cases, optimized to convert the colors much faster, when converting + to the common case of RGBA with 8 bit per channel. buffer must be RGBA with + enough memory.*/ +static void getPixelColorsRGBA8(unsigned char* LODEPNG_RESTRICT buffer, size_t numpixels, const unsigned char* LODEPNG_RESTRICT in, const LodePNGColorMode* mode) +{ + unsigned num_channels = 4; + size_t i; + if (mode->colortype == LCT_GREY) { + if (mode->bitdepth == 8) { + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i]; + buffer[3] = 255; + } + if (mode->key_defined) { + buffer -= numpixels * num_channels; + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + if(buffer[0] == mode->key_r) buffer[3] = 0; + } + } + } else if (mode->bitdepth == 16) { + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i * 2]; + buffer[3] = mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r ? 0 : 255; + } + } else { + unsigned highest = ((1U << mode->bitdepth) - 1U); /* highest possible value for this bit depth */ + size_t j = 0; + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); + buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest; + buffer[3] = mode->key_defined && value == mode->key_r ? 0 : 255; + } + } + } else if (mode->colortype == LCT_RGB) { + if (mode->bitdepth == 8) { + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + //lodepng_memcpy(buffer, &in[i * 3], 3); + //Convert colortype to LCT_BGR? + buffer[0] = in[i * 3 + 2]; + buffer[1] = in[i * 3 + 1]; + buffer[2] = in[i * 3 + 0]; + buffer[3] = 255; + } + if (mode->key_defined) { + buffer -= numpixels * num_channels; + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + if (buffer[0] == mode->key_r && buffer[1]== mode->key_g && buffer[2] == mode->key_b) buffer[3] = 0; + } + } + } else { + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = in[i * 6 + 0]; + buffer[1] = in[i * 6 + 2]; + buffer[2] = in[i * 6 + 4]; + buffer[3] = mode->key_defined + && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r + && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g + && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b ? 0 : 255; + } + } + } else if (mode->colortype == LCT_PALETTE) { + if (mode->bitdepth == 8) { + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + unsigned index = in[i]; + /* out of bounds of palette not checked: see lodepng_color_mode_alloc_palette. */ + lodepng_memcpy(buffer, &mode->palette[index * 4], 4); + } + } else { + size_t j = 0; + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + unsigned index = readBitsFromReversedStream(&j, in, mode->bitdepth); + /* out of bounds of palette not checked: see lodepng_color_mode_alloc_palette. */ + lodepng_memcpy(buffer, &mode->palette[index * 4], 4); + } + } + } else if (mode->colortype == LCT_GREY_ALPHA) { + if (mode->bitdepth == 8) { + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0]; + buffer[3] = in[i * 2 + 1]; + } + } else { + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0]; + buffer[3] = in[i * 4 + 2]; + } + } + } else if (mode->colortype == LCT_RGBA) { + if (mode->bitdepth == 8) { + lodepng_memcpy(buffer, in, numpixels * 4); + } else { + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = in[i * 8 + 0]; + buffer[1] = in[i * 8 + 2]; + buffer[2] = in[i * 8 + 4]; + buffer[3] = in[i * 8 + 6]; + } + } + } +} + + +/* Similar to getPixelColorsRGBA8, but with 3-channel RGB output. */ +static void getPixelColorsRGB8(unsigned char* LODEPNG_RESTRICT buffer, size_t numpixels, const unsigned char* LODEPNG_RESTRICT in, const LodePNGColorMode* mode) +{ + const unsigned num_channels = 3; + size_t i; + if (mode->colortype == LCT_GREY) { + if (mode->bitdepth == 8) { + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i]; + } + } else if (mode->bitdepth == 16) { + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i * 2]; + } + } else { + unsigned highest = ((1U << mode->bitdepth) - 1U); /* highest possible value for this bit depth */ + size_t j = 0; + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); + buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest; + } + } + } else if (mode->colortype == LCT_RGB) { + if (mode->bitdepth == 8) { + lodepng_memcpy(buffer, in, numpixels * 3); + } else { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = in[i * 6 + 0]; + buffer[1] = in[i * 6 + 2]; + buffer[2] = in[i * 6 + 4]; + } + } + } else if (mode->colortype == LCT_PALETTE) { + if (mode->bitdepth == 8) { + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + unsigned index = in[i]; + /* out of bounds of palette not checked: see lodepng_color_mode_alloc_palette. */ + lodepng_memcpy(buffer, &mode->palette[index * 4], 3); + } + } else { + size_t j = 0; + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + unsigned index = readBitsFromReversedStream(&j, in, mode->bitdepth); + /* out of bounds of palette not checked: see lodepng_color_mode_alloc_palette. */ + lodepng_memcpy(buffer, &mode->palette[index * 4], 3); + } + } + } else if (mode->colortype == LCT_GREY_ALPHA) { + if (mode->bitdepth == 8) { + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0]; + } + } else { + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0]; + } + } + } else if (mode->colortype == LCT_RGBA) { + if (mode->bitdepth == 8) { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + lodepng_memcpy(buffer, &in[i * 4], 3); + } + } else { + for (i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = in[i * 8 + 0]; + buffer[1] = in[i * 8 + 2]; + buffer[2] = in[i * 8 + 4]; + } + } + } +} + + +/* Get RGBA16 color of pixel with index i (y * width + x) from the raw image with + given color type, but the given color type must be 16-bit itself. */ +static void getPixelColorRGBA16(unsigned short* r, unsigned short* g, unsigned short* b, unsigned short* a, const unsigned char* in, size_t i, const LodePNGColorMode* mode) +{ + if (mode->colortype == LCT_GREY) { + *r = *g = *b = 256 * in[i * 2 + 0] + in[i * 2 + 1]; + if (mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0; + else *a = 65535; + } else if (mode->colortype == LCT_RGB) { + *r = 256u * in[i * 6 + 0] + in[i * 6 + 1]; + *g = 256u * in[i * 6 + 2] + in[i * 6 + 3]; + *b = 256u * in[i * 6 + 4] + in[i * 6 + 5]; + if (mode->key_defined + && 256u * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r + && 256u * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g + && 256u * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; + else *a = 65535; + } else if (mode->colortype == LCT_GREY_ALPHA) { + *r = *g = *b = 256u * in[i * 4 + 0] + in[i * 4 + 1]; + *a = 256u * in[i * 4 + 2] + in[i * 4 + 3]; + } else if (mode->colortype == LCT_RGBA) { + *r = 256u * in[i * 8 + 0] + in[i * 8 + 1]; + *g = 256u * in[i * 8 + 2] + in[i * 8 + 3]; + *b = 256u * in[i * 8 + 4] + in[i * 8 + 5]; + *a = 256u * in[i * 8 + 6] + in[i * 8 + 7]; + } +} + +/* + Converts raw buffer from one color type to another color type, based on + LodePNGColorMode structs to describe the input and output color type. + See the reference manual at the end of this header file to see which color conversions are supported. + return value = LodePNG error code (0 if all went ok, an error if the conversion isn't supported) + The out buffer must have size (w * h * bpp + 7) / 8, where bpp is the bits per pixel + of the output color type (lodepng_get_bpp). + For < 8 bpp images, there should not be padding bits at the end of scanlines. + For 16-bit per channel colors, uses big endian format like PNG does. + Return value is LodePNG error code +*/ +static unsigned lodepng_convert(unsigned char* out, const unsigned char* in, const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, unsigned w, unsigned h) +{ + size_t i; + ColorTree tree; + size_t numpixels = (size_t)w * (size_t)h; + unsigned error = 0; + + if (mode_in->colortype == LCT_PALETTE && !mode_in->palette) { + return 107; /* error: must provide palette if input mode is palette */ + } + + if (lodepng_color_mode_equal(mode_out, mode_in)) { + size_t numbytes = lodepng_get_raw_size(w, h, mode_in); + lodepng_memcpy(out, in, numbytes); + return 0; + } + + if (mode_out->colortype == LCT_PALETTE) { + size_t palettesize = mode_out->palettesize; + const unsigned char* palette = mode_out->palette; + size_t palsize = (size_t)1u << mode_out->bitdepth; + /* if the user specified output palette but did not give the values, assume + they want the values of the input color type (assuming that one is palette). + Note that we never create a new palette ourselves.*/ + if (palettesize == 0) { + palettesize = mode_in->palettesize; + palette = mode_in->palette; + /* if the input was also palette with same bitdepth, then the color types are also + equal, so copy literally. This to preserve the exact indices that were in the PNG + even in case there are duplicate colors in the palette.*/ + if (mode_in->colortype == LCT_PALETTE && mode_in->bitdepth == mode_out->bitdepth) { + size_t numbytes = lodepng_get_raw_size(w, h, mode_in); + lodepng_memcpy(out, in, numbytes); + return 0; + } + } + if (palettesize < palsize) palsize = palettesize; + color_tree_init(&tree); + for (i = 0; i != palsize; ++i) { + const unsigned char* p = &palette[i * 4]; + error = color_tree_add(&tree, p[0], p[1], p[2], p[3], (unsigned)i); + if (error) break; + } + } + + if (!error) { + if (mode_in->bitdepth == 16 && mode_out->bitdepth == 16) { + for (i = 0; i != numpixels; ++i) { + unsigned short r = 0, g = 0, b = 0, a = 0; + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); + rgba16ToPixel(out, i, mode_out, r, g, b, a); + } + } else if (mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGBA) { + getPixelColorsRGBA8(out, numpixels, in, mode_in); + } else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGB) { + getPixelColorsRGB8(out, numpixels, in, mode_in); + } else { + unsigned char r = 0, g = 0, b = 0, a = 0; + for (i = 0; i != numpixels; ++i) { + getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); + error = rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a); + if (error) break; + } + } + } + + if (mode_out->colortype == LCT_PALETTE) { + color_tree_cleanup(&tree); + } + + return error; +} + + +/* Paeth predictor, used by PNG filter type 4 + The parameters are of type short, but should come from unsigned chars, the shorts + are only needed to make the paeth calculation correct. +*/ +static unsigned char paethPredictor(short a, short b, short c) +{ + short pa = LODEPNG_ABS(b - c); + short pb = LODEPNG_ABS(a - c); + short pc = LODEPNG_ABS(a + b - c - c); + /* return input value associated with smallest of pa, pb, pc (with certain priority if equal) */ + if (pb < pa) { a = b; pa = pb; } + return (pc < pa) ? c : a; +} + + +/*shared values used by multiple Adam7 related functions*/ +static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 }; /*x start values*/ +static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 }; /*y start values*/ +static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 }; /*x delta values*/ +static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 }; /*y delta values*/ + +/* Outputs various dimensions and positions in the image related to the Adam7 reduced images. + passw: output containing the width of the 7 passes + passh: output containing the height of the 7 passes + filter_passstart: output containing the index of the start and end of each + reduced image with filter bytes + padded_passstart output containing the index of the start and end of each + reduced image when without filter bytes but with padded scanlines + passstart: output containing the index of the start and end of each reduced + image without padding between scanlines, but still padding between the images + w, h: width and height of non-interlaced image + bpp: bits per pixel + "padded" is only relevant if bpp is less than 8 and a scanline or image does not + end at a full byte */ +static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t filter_passstart[8], size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp) +{ + /* the passstart values have 8 values: the 8th one indicates the byte after the end of the 7th (= last) pass */ + unsigned i; + + /* calculate width and height in pixels of each pass */ + for (i = 0; i != 7; ++i) { + passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i]; + passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i]; + if(passw[i] == 0) passh[i] = 0; + if(passh[i] == 0) passw[i] = 0; + } + + filter_passstart[0] = padded_passstart[0] = passstart[0] = 0; + for (i = 0; i != 7; ++i) { + /* if passw[i] is 0, it's 0 bytes, not 1 (no filtertype-byte) */ + filter_passstart[i + 1] = filter_passstart[i] + + ((passw[i] && passh[i]) ? passh[i] * (1u + (passw[i] * bpp + 7u) / 8u) : 0); + /* bits padded if needed to fill full byte at end of each scanline */ + padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7u) / 8u); + /* only padded at end of reduced image */ + passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7u) / 8u; + } +} + + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / PNG Decoder / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon, size_t bytewidth, unsigned char filterType, size_t length) +{ + /* For PNG filter method 0 + unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte, + the filter works byte per byte (bytewidth = 1) + precon is the previous unfiltered scanline, recon the result, scanline the current one + the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead + recon and scanline MAY be the same memory address! precon must be disjoint. */ + + size_t i; + switch (filterType) { + case 0: { + if (bytewidth == 4) { + for (i = 0; i < length; i += 4) { + //RGBA -> BGRA + recon[i + 0] = scanline[i + 2]; + recon[i + 1] = scanline[i + 1]; + recon[i + 2] = scanline[i + 0]; + recon[i + 3] = scanline[i + 3]; + } + } else { + for (i = 0; i != length; ++i) recon[i] = scanline[i]; + } + break; + } + case 1: { + for (i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; + for (i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth]; + break; + } + case 2: { + if (precon) { + for (i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i]; + } else { + for (i = 0; i != length; ++i) recon[i] = scanline[i]; + } + break; + } + case 3: { + if (precon) { + for (i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1u); + for (i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1u); + } else { + for (i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; + for (i = bytewidth; i < length; ++i) recon[i] = scanline[i] + (recon[i - bytewidth] >> 1u); + } + break; + } + case 4: { + if (precon) { + for (i = 0; i != bytewidth; ++i) { + recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/ + } + + /* Unroll independent paths of the paeth predictor. A 6x and 8x version would also be possible but that + adds too much code. Whether this actually speeds anything up at all depends on compiler and settings. */ + if (bytewidth >= 4) { + for (; i + 3 < length; i += 4) { + size_t j = i - bytewidth; + unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2], s3 = scanline[i + 3]; + unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2], r3 = recon[j + 3]; + unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2], p3 = precon[i + 3]; + unsigned char q0 = precon[j + 0], q1 = precon[j + 1], q2 = precon[j + 2], q3 = precon[j + 3]; + recon[i + 0] = s0 + paethPredictor(r0, p0, q0); + recon[i + 1] = s1 + paethPredictor(r1, p1, q1); + recon[i + 2] = s2 + paethPredictor(r2, p2, q2); + recon[i + 3] = s3 + paethPredictor(r3, p3, q3); + } + } else if (bytewidth >= 3) { + for (; i + 2 < length; i += 3) { + size_t j = i - bytewidth; + unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2]; + unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2]; + unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2]; + unsigned char q0 = precon[j + 0], q1 = precon[j + 1], q2 = precon[j + 2]; + recon[i + 0] = s0 + paethPredictor(r0, p0, q0); + recon[i + 1] = s1 + paethPredictor(r1, p1, q1); + recon[i + 2] = s2 + paethPredictor(r2, p2, q2); + } + } else if (bytewidth >= 2) { + for (; i + 1 < length; i += 2) { + size_t j = i - bytewidth; + unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1]; + unsigned char r0 = recon[j + 0], r1 = recon[j + 1]; + unsigned char p0 = precon[i + 0], p1 = precon[i + 1]; + unsigned char q0 = precon[j + 0], q1 = precon[j + 1]; + recon[i + 0] = s0 + paethPredictor(r0, p0, q0); + recon[i + 1] = s1 + paethPredictor(r1, p1, q1); + } + } + + for (; i != length; ++i) { + recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth])); + } + } else { + for (i = 0; i != bytewidth; ++i) { + recon[i] = scanline[i]; + } + for (i = bytewidth; i < length; ++i) { + /* paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth] */ + recon[i] = (scanline[i] + recon[i - bytewidth]); + } + } + break; + } + default: return 36; /* error: invalid filter type given */ + } + return 0; +} + + +static unsigned unfilter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) +{ + /* For PNG filter method 0 + this function unfilters a single image (e.g. without interlacing this is called once, with Adam7 seven times) + out must have enough bytes allocated already, in must have the scanlines + 1 filtertype byte per scanline + w and h are image dimensions or dimensions of reduced image, bpp is bits per pixel + in and out are allowed to be the same memory address (but aren't the same size since in has the extra filter bytes) */ + + unsigned y; + unsigned char* prevline = 0; + + /* bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise */ + size_t bytewidth = (bpp + 7u) / 8u; + /* the width of a scanline in bytes, not including the filter type */ + size_t linebytes = lodepng_get_raw_size_idat(w, 1, bpp) - 1u; + + for (y = 0; y < h; ++y) { + size_t outindex = linebytes * y; + size_t inindex = (1 + linebytes) * y; /* the extra filterbyte added to each row */ + unsigned char filterType = in[inindex]; + CERROR_TRY_RETURN(unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes)); + prevline = &out[outindex]; + } + + return 0; +} + +/* in: Adam7 interlaced image, with no padding bits between scanlines, but between + reduced images so that each reduced image starts at a byte. + out: the same pixels, but re-ordered so that they're now a non-interlaced image with size w*h + bpp: bits per pixel + out has the following size in bits: w * h * bpp. + in is possibly bigger due to padding bits between reduced images. + out must be big enough AND must be 0 everywhere if bpp < 8 in the current implementation + (because that's likely a little bit faster) + NOTE: comments about padding bits are only relevant if bpp < 8 */ +static void Adam7_deinterlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) +{ + unsigned passw[7], passh[7]; + size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned i; + + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + + if (bpp >= 8) { + for(i = 0; i != 7; ++i) { + unsigned x, y, b; + size_t bytewidth = bpp / 8u; + for (y = 0; y < passh[i]; ++y) + for (x = 0; x < passw[i]; ++x) { + size_t pixelinstart = passstart[i] + (y * passw[i] + x) * bytewidth; + size_t pixeloutstart = ((ADAM7_IY[i] + (size_t)y * ADAM7_DY[i]) * (size_t)w + ADAM7_IX[i] + (size_t)x * ADAM7_DX[i]) * bytewidth; + for (b = 0; b < bytewidth; ++b) { + out[pixeloutstart + b] = in[pixelinstart + b]; + } + } + } + } else /* bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers */ { + for (i = 0; i != 7; ++i) { + unsigned x, y, b; + unsigned ilinebits = bpp * passw[i]; + unsigned olinebits = bpp * w; + size_t obp, ibp; /* bit pointers (for out and in buffer) */ + for (y = 0; y < passh[i]; ++y) + for (x = 0; x < passw[i]; ++x) { + ibp = (8 * passstart[i]) + (y * ilinebits + x * bpp); + obp = (ADAM7_IY[i] + (size_t)y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + (size_t)x * ADAM7_DX[i]) * bpp; + for (b = 0; b < bpp; ++b) { + unsigned char bit = readBitFromReversedStream(&ibp, in); + setBitOfReversedStream(&obp, out, bit); + } + } + } + } +} + + +static void removePaddingBits(unsigned char* out, const unsigned char* in, size_t olinebits, size_t ilinebits, unsigned h) +{ + /* After filtering there are still padding bits if scanlines have non multiple of 8 bit amounts. They need + to be removed (except at last scanline of (Adam7-reduced) image) before working with pure image buffers + for the Adam7 code, the color convert code and the output to the user. + in and out are allowed to be the same buffer, in may also be higher but still overlapping; in must + have >= ilinebits*h bits, out must have >= olinebits*h bits, olinebits must be <= ilinebits + also used to move bits after earlier such operations happened, e.g. in a sequence of reduced images from Adam7 + only useful if (ilinebits - olinebits) is a value in the range 1..7 */ + unsigned y; + size_t diff = ilinebits - olinebits; + size_t ibp = 0, obp = 0; /*input and output bit pointers*/ + for (y = 0; y < h; ++y) { + size_t x; + for (x = 0; x < olinebits; ++x) { + unsigned char bit = readBitFromReversedStream(&ibp, in); + setBitOfReversedStream(&obp, out, bit); + } + ibp += diff; + } +} + + +/* out must be buffer big enough to contain full image, and in must contain the full decompressed data from + the IDAT chunks (with filter index bytes and possible padding bits) + return value is error */ +static unsigned postProcessScanlines(unsigned char* out, unsigned char* in, unsigned w, unsigned h, const LodePNGInfo* info_png) +{ + /* This function converts the filtered-padded-interlaced data into pure 2D image buffer with the PNG's colortype. + Steps: + *) if no Adam7: 1) unfilter 2) remove padding bits (= possible extra bits per scanline if bpp < 8) + *) if adam7: 1) 7x unfilter 2) 7x remove padding bits 3) Adam7_deinterlace + NOTE: the in buffer will be overwritten with intermediate data! */ + unsigned bpp = lodepng_get_bpp_lct(info_png->color.colortype, info_png->color.bitdepth); + if (bpp == 0) return 31; /* error: invalid colortype */ + + if (info_png->interlace_method == 0) { + if (bpp < 8 && w * bpp != ((w * bpp + 7u) / 8u) * 8u) { + CERROR_TRY_RETURN(unfilter(in, in, w, h, bpp)); + removePaddingBits(out, in, w * bpp, ((w * bpp + 7u) / 8u) * 8u, h); + } + /* we can immediately filter into the out buffer, no other steps needed */ + else CERROR_TRY_RETURN(unfilter(out, in, w, h, bpp)); + } else /* interlace_method is 1 (Adam7) */ { + unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned i; + + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + + for (i = 0; i != 7; ++i) { + CERROR_TRY_RETURN(unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp)); + /* TODO: possible efficiency improvement: if in this reduced image the bits fit nicely in 1 scanline, + move bytes instead of bits or move not at all */ + if (bpp < 8) { + /* remove padding bits in scanlines; after this there still may be padding + bits between the different reduced images: each reduced image still starts nicely at a byte */ + removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp, ((passw[i] * bpp + 7u) / 8u) * 8u, passh[i]); + } + } + Adam7_deinterlace(out, in, w, h, bpp); + } + return 0; +} + + +static unsigned readChunk_PLTE(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) +{ + unsigned pos = 0, i; + color->palettesize = chunkLength / 3u; + if (color->palettesize == 0 || color->palettesize > 256) return 38; /* error: palette too small or big */ + lodepng_color_mode_alloc_palette(color); + if (!color->palette && color->palettesize) { + color->palettesize = 0; + return 83; /* alloc fail */ + } + + for (i = 0; i != color->palettesize; ++i) { + color->palette[4 * i + 0] = data[pos++]; /*R*/ + color->palette[4 * i + 1] = data[pos++]; /*G*/ + color->palette[4 * i + 2] = data[pos++]; /*B*/ + color->palette[4 * i + 3] = 255; /*alpha*/ + } + + return 0; /* OK */ +} + + +static unsigned readChunk_tRNS(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) +{ + unsigned i; + if (color->colortype == LCT_PALETTE) { + /* error: more alpha values given than there are palette entries */ + if (chunkLength > color->palettesize) return 39; + + for (i = 0; i != chunkLength; ++i) color->palette[4 * i + 3] = data[i]; + } else if (color->colortype == LCT_GREY) { + /* error: this chunk must be 2 bytes for grayscale image */ + if (chunkLength != 2) return 30; + + color->key_defined = 1; + color->key_r = color->key_g = color->key_b = 256u * data[0] + data[1]; + } else if (color->colortype == LCT_RGB) { + /* error: this chunk must be 6 bytes for RGB image */ + if (chunkLength != 6) return 41; + + color->key_defined = 1; + color->key_r = 256u * data[0] + data[1]; + color->key_g = 256u * data[2] + data[3]; + color->key_b = 256u * data[4] + data[5]; + } + else return 42; /* error: tRNS chunk not allowed for other color models */ + + return 0; /* OK */ +} + + +/* read a PNG, the result will be in the same color type as the PNG (hence "generic") */ +static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize) +{ + unsigned char IEND = 0; + const unsigned char* chunk; + unsigned char* idat; /*the data from idat chunks, zlib compressed*/ + size_t idatsize = 0; + unsigned char* scanlines = 0; + size_t scanlines_size = 0, expected_size = 0; + size_t outsize = 0; + + /* safe output values in case error happens */ + *out = 0; + *w = *h = 0; + + state->error = lodepng_inspect(w, h, state, in, insize); /*reads header and resets other parameters in state->info_png*/ + if (state->error) return; + + if (lodepng_pixel_overflow(*w, *h, &state->info_png.color, &state->info_raw)) { + CERROR_RETURN(state->error, 92); /*overflow possible due to amount of pixels*/ + } + + /*the input filesize is a safe upper bound for the sum of idat chunks size*/ + idat = (unsigned char*)malloc(insize); + if (!idat) CERROR_RETURN(state->error, 83); /*alloc fail*/ + + chunk = &in[33]; /*first byte of the first chunk after the header*/ + + /*loop through the chunks, ignoring unknown chunks and stopping at IEND chunk. + IDAT data is put at the start of the in buffer*/ + while (!IEND && !state->error) { + unsigned chunkLength; + const unsigned char* data; /*the data in the chunk*/ + + /*error: size of the in buffer too small to contain next chunk*/ + if ((size_t)((chunk - in) + 12) > insize || chunk < in) { + if (state->decoder.ignore_end) break; /*other errors may still happen though*/ + CERROR_BREAK(state->error, 30); + } + + /*length of the data of the chunk, excluding the length bytes, chunk type and CRC bytes*/ + chunkLength = lodepng_chunk_length(chunk); + /*error: chunk length larger than the max PNG chunk size*/ + if (chunkLength > 2147483647) { + if (state->decoder.ignore_end) break; /*other errors may still happen though*/ + CERROR_BREAK(state->error, 63); + } + + if ((size_t)((chunk - in) + chunkLength + 12) > insize || (chunk + chunkLength + 12) < in) { + CERROR_BREAK(state->error, 64); /*error: size of the in buffer too small to contain next chunk*/ + } + + data = lodepng_chunk_data_const(chunk); + + /*for unknown chunk order*/ + //unsigned unknown = 0; + + /*IDAT chunk, containing compressed image data*/ + if (lodepng_chunk_type_equals(chunk, "IDAT")) { + size_t newsize; + if (lodepng_addofl(idatsize, chunkLength, &newsize)) CERROR_BREAK(state->error, 95); + if (newsize > insize) CERROR_BREAK(state->error, 95); + lodepng_memcpy(idat + idatsize, data, chunkLength); + idatsize += chunkLength; + } else if (lodepng_chunk_type_equals(chunk, "IEND")) { + /*IEND chunk*/ + IEND = 1; + } else if (lodepng_chunk_type_equals(chunk, "PLTE")) { + /*palette chunk (PLTE)*/ + state->error = readChunk_PLTE(&state->info_png.color, data, chunkLength); + if (state->error) break; + } else if (lodepng_chunk_type_equals(chunk, "tRNS")) { + /*palette transparency chunk (tRNS). Even though this one is an ancillary chunk , it is still compiled + in without 'LODEPNG_COMPILE_ANCILLARY_CHUNKS' because it contains essential color information that + affects the alpha channel of pixels. */ + state->error = readChunk_tRNS(&state->info_png.color, data, chunkLength); + if (state->error) break; + } else /*it's not an implemented chunk type, so ignore it: skip over the data*/ { + /*error: unknown critical chunk (5th bit of first byte of chunk type is 0)*/ + if (!state->decoder.ignore_critical && !lodepng_chunk_ancillary(chunk)) { + CERROR_BREAK(state->error, 69); + } + //unknown = 1; + } + +#if 0 //We don't use CRC + if (!state->decoder.ignore_crc && !unknown) /*check CRC if wanted, only on known chunk types*/ { + if (lodepng_chunk_check_crc(chunk)) CERROR_BREAK(state->error, 57); /*invalid CRC*/ + } +#endif + if (!IEND) chunk = lodepng_chunk_next_const(chunk, in + insize); + } + + if (state->info_png.color.colortype == LCT_PALETTE && !state->info_png.color.palette) { + state->error = 106; /* error: PNG file must have PLTE chunk if color type is palette */ + } + + if (!state->error) { + /*predict output size, to allocate exact size for output buffer to avoid more dynamic allocation. + If the decompressed size does not match the prediction, the image must be corrupt.*/ + if (state->info_png.interlace_method == 0) { + size_t bpp = lodepng_get_bpp_lct(state->info_png.color.colortype, state->info_png.color.bitdepth); + expected_size = lodepng_get_raw_size_idat(*w, *h, bpp); + } else { + size_t bpp = lodepng_get_bpp_lct(state->info_png.color.colortype, state->info_png.color.bitdepth); + /*Adam-7 interlaced: expected size is the sum of the 7 sub-images sizes*/ + expected_size = 0; + expected_size += lodepng_get_raw_size_idat((*w + 7) >> 3, (*h + 7) >> 3, bpp); + if (*w > 4) expected_size += lodepng_get_raw_size_idat((*w + 3) >> 3, (*h + 7) >> 3, bpp); + expected_size += lodepng_get_raw_size_idat((*w + 3) >> 2, (*h + 3) >> 3, bpp); + if (*w > 2) expected_size += lodepng_get_raw_size_idat((*w + 1) >> 2, (*h + 3) >> 2, bpp); + expected_size += lodepng_get_raw_size_idat((*w + 1) >> 1, (*h + 1) >> 2, bpp); + if (*w > 1) expected_size += lodepng_get_raw_size_idat((*w + 0) >> 1, (*h + 1) >> 1, bpp); + expected_size += lodepng_get_raw_size_idat((*w + 0), (*h + 0) >> 1, bpp); + } + state->error = zlib_decompress(&scanlines, &scanlines_size, expected_size, idat, idatsize, &state->decoder.zlibsettings); + } + + if (!state->error && scanlines_size != expected_size) state->error = 91; /*decompressed size doesn't match prediction*/ + free(idat); + + if (!state->error) { + outsize = lodepng_get_raw_size(*w, *h, &state->info_png.color); + *out = (unsigned char*)malloc(outsize); + if (!*out) state->error = 83; /*alloc fail*/ + } + if (!state->error) { + lodepng_memset(*out, 0, outsize); + state->error = postProcessScanlines(*out, scanlines, *w, *h, &state->info_png); + } + free(scanlines); +} + + +static void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings) +{ + settings->color_convert = 1; + settings->ignore_crc = 0; + settings->ignore_critical = 0; + settings->ignore_end = 0; + lodepng_decompress_settings_init(&settings->zlibsettings); +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +/*read the information from the header and store it in the LodePNGInfo. return value is error*/ +unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize) +{ + unsigned width, height; + LodePNGInfo* info = &state->info_png; + if (insize == 0 || in == 0) { + CERROR_RETURN_ERROR(state->error, 48); /*error: the given data is empty*/ + } + if (insize < 33) { + CERROR_RETURN_ERROR(state->error, 27); /*error: the data length is smaller than the length of a PNG header*/ + } + + /* when decoding a new PNG image, make sure all parameters created after previous decoding are reset */ + /* TODO: remove this. One should use a new LodePNGState for new sessions */ + lodepng_info_cleanup(info); + lodepng_info_init(info); + + if (in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71 || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) { + CERROR_RETURN_ERROR(state->error, 28); /*error: the first 8 bytes are not the correct PNG signature*/ + } + if (lodepng_chunk_length(in + 8) != 13) { + CERROR_RETURN_ERROR(state->error, 94); /*error: header size must be 13 bytes*/ + } + if (!lodepng_chunk_type_equals(in + 8, "IHDR")) { + CERROR_RETURN_ERROR(state->error, 29); /*error: it doesn't start with a IHDR chunk!*/ + } + + /*read the values given in the header*/ + width = lodepng_read32bitInt(&in[16]); + height = lodepng_read32bitInt(&in[20]); + /*TODO: remove the undocumented feature that allows to give null pointers to width or height*/ + if (w) *w = width; + if (h) *h = height; + info->color.bitdepth = in[24]; + info->color.colortype = (LodePNGColorType)in[25]; + info->compression_method = in[26]; + info->filter_method = in[27]; + info->interlace_method = in[28]; + + /*errors returned only after the parsing so other values are still output*/ + + /*error: invalid image size*/ + if (width == 0 || height == 0) CERROR_RETURN_ERROR(state->error, 93); + /*error: invalid colortype or bitdepth combination*/ + state->error = checkColorValidity(info->color.colortype, info->color.bitdepth); + if (state->error) return state->error; + /*error: only compression method 0 is allowed in the specification*/ + if (info->compression_method != 0) CERROR_RETURN_ERROR(state->error, 32); + /*error: only filter method 0 is allowed in the specification*/ + if (info->filter_method != 0) CERROR_RETURN_ERROR(state->error, 33); + /*error: only interlace methods 0 and 1 exist in the specification*/ + if (info->interlace_method > 1) CERROR_RETURN_ERROR(state->error, 34); + +#if 0 //thorvg don't use crc + if (!state->decoder.ignore_crc) { + unsigned CRC = lodepng_read32bitInt(&in[29]); + unsigned checksum = lodepng_crc32(&in[12], 17); + if (CRC != checksum) { + CERROR_RETURN_ERROR(state->error, 57); /*invalid CRC*/ + } + } +#endif + return state->error; +} + + +unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize) +{ + *out = 0; + decodeGeneric(out, w, h, state, in, insize); + if (state->error) return state->error; + if (!state->decoder.color_convert || lodepng_color_mode_equal(&state->info_raw, &state->info_png.color)) { + /*same color type, no copying or converting of data needed*/ + /*store the info_png color settings on the info_raw so that the info_raw still reflects what colortype + the raw image has to the end user*/ + if (!state->decoder.color_convert) { + state->error = lodepng_color_mode_copy(&state->info_raw, &state->info_png.color); + if (state->error) return state->error; + } + } else { /*color conversion needed*/ + unsigned char* data = *out; + size_t outsize; + + /*TODO: check if this works according to the statement in the documentation: "The converter can convert + from grayscale input color type, to 8-bit grayscale or grayscale with alpha"*/ + if (!(state->info_raw.colortype == LCT_RGB || state->info_raw.colortype == LCT_RGBA) && !(state->info_raw.bitdepth == 8)) { + return 56; /*unsupported color mode conversion*/ + } + + outsize = lodepng_get_raw_size(*w, *h, &state->info_raw); + *out = (unsigned char*)malloc(outsize); + if (!(*out)) { + state->error = 83; /*alloc fail*/ + } + else state->error = lodepng_convert(*out, data, &state->info_raw, &state->info_png.color, *w, *h); + free(data); + } + return state->error; +} + + +void lodepng_state_init(LodePNGState* state) +{ + lodepng_decoder_settings_init(&state->decoder); + lodepng_color_mode_init(&state->info_raw); + lodepng_info_init(&state->info_png); + state->error = 1; +} + + +void lodepng_state_cleanup(LodePNGState* state) +{ + lodepng_color_mode_cleanup(&state->info_raw); + lodepng_info_cleanup(&state->info_png); +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/loaders/png/tvgLodePng.h b/thirdparty/thorvg/src/loaders/png/tvgLodePng.h new file mode 100644 index 0000000000..02e1feeec5 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/png/tvgLodePng.h @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + LodePNG version 20200306 + + Copyright (c) 2005-2020 Lode Vandevenne + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#ifndef _TVG_LODEPNG_H_ +#define _TVG_LODEPNG_H_ + +#include <stddef.h> + +/*The PNG color types (also used for raw image).*/ +enum LodePNGColorType +{ + LCT_GREY = 0, /*grayscale: 1,2,4,8,16 bit*/ + LCT_RGB = 2, /*RGB: 8,16 bit*/ + LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/ + LCT_GREY_ALPHA = 4, /*grayscale with alpha: 8,16 bit*/ + LCT_RGBA = 6, /*RGB with alpha: 8,16 bit*/ + /*LCT_MAX_OCTET_VALUE lets the compiler allow this enum to represent any invalid + byte value from 0 to 255 that could be present in an invalid PNG file header. Do + not use, compare with or set the name LCT_MAX_OCTET_VALUE, instead either use + the valid color type names above, or numeric values like 1 or 7 when checking for + particular disallowed color type byte values, or cast to integer to print it.*/ + LCT_MAX_OCTET_VALUE = 255 +}; + +/*Settings for zlib decompression*/ +struct LodePNGDecompressSettings +{ + /* Check LodePNGDecoderSettings for more ignorable errors such as ignore_crc */ + unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/ + unsigned ignore_nlen; /*ignore complement of len checksum in uncompressed blocks*/ + + /*use custom zlib decoder instead of built in one (default: null)*/ + unsigned (*custom_zlib)(unsigned char**, size_t*, const unsigned char*, size_t, const LodePNGDecompressSettings*); + /*use custom deflate decoder instead of built in one (default: null) if custom_zlib is not null, custom_inflate is ignored (the zlib format uses deflate)*/ + unsigned (*custom_inflate)(unsigned char**, size_t*, const unsigned char*, size_t, const LodePNGDecompressSettings*); + + const void* custom_context; /*optional custom settings for custom functions*/ +}; + +/* + Color mode of an image. Contains all information required to decode the pixel + bits to RGBA colors. This information is the same as used in the PNG file + format, and is used both for PNG and raw image data in LodePNG. +*/ +struct LodePNGColorMode +{ + /*header (IHDR)*/ + LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/ + unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/ + + /* + palette (PLTE and tRNS) + + Dynamically allocated with the colors of the palette, including alpha. + This field may not be allocated directly, use lodepng_color_mode_init first, + then lodepng_palette_add per color to correctly initialize it (to ensure size + of exactly 1024 bytes). + + The alpha channels must be set as well, set them to 255 for opaque images. + + When decoding, by default you can ignore this palette, since LodePNG already + fills the palette colors in the pixels of the raw RGBA output. + + The palette is only supported for color type 3. + */ + unsigned char* palette; /*palette in RGBARGBA... order. Must be either 0, or when allocated must have 1024 bytes*/ + size_t palettesize; /*palette size in number of colors (amount of used bytes is 4 * palettesize)*/ + + /* + transparent color key (tRNS) + + This color uses the same bit depth as the bitdepth value in this struct, which can be 1-bit to 16-bit. + For grayscale PNGs, r, g and b will all 3 be set to the same. + + When decoding, by default you can ignore this information, since LodePNG sets + pixels with this key to transparent already in the raw RGBA output. + + The color key is only supported for color types 0 and 2. + */ + unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/ + unsigned key_r; /*red/grayscale component of color key*/ + unsigned key_g; /*green component of color key*/ + unsigned key_b; /*blue component of color key*/ +}; + +/*Information about the PNG image, except pixels, width and height.*/ +struct LodePNGInfo +{ + /*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/ + unsigned compression_method;/*compression method of the original file. Always 0.*/ + unsigned filter_method; /*filter method of the original file*/ + unsigned interlace_method; /*interlace method of the original file: 0=none, 1=Adam7*/ + LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/ +}; + +/* + Settings for the decoder. This contains settings for the PNG and the Zlib + decoder, but not the Info settings from the Info structs. +*/ +struct LodePNGDecoderSettings +{ + LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/ + + /* Check LodePNGDecompressSettings for more ignorable errors such as ignore_adler32 */ + unsigned ignore_crc; /*ignore CRC checksums*/ + unsigned ignore_critical; /*ignore unknown critical chunks*/ + unsigned ignore_end; /*ignore issues at end of file if possible (missing IEND chunk, too large chunk, ...)*/ + /* TODO: make a system involving warnings with levels and a strict mode instead. Other potentially recoverable + errors: srgb rendering intent value, size of content of ancillary chunks, more than 79 characters for some + strings, placement/combination rules for ancillary chunks, crc of unknown chunks, allowed characters + in string keys, etc... */ + + unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/ +}; + +/*The settings, state and information for extended encoding and decoding.*/ +struct LodePNGState +{ + LodePNGDecoderSettings decoder; /*the decoding settings*/ + LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/ + LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/ + unsigned error; +}; + +void lodepng_state_init(LodePNGState* state); +void lodepng_state_cleanup(LodePNGState* state); +unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize); +unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize); + +#endif //_TVG_LODEPNG_H_
\ No newline at end of file diff --git a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp new file mode 100644 index 0000000000..c6d95be5ba --- /dev/null +++ b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include <memory.h> +#include "tvgLoader.h" +#include "tvgPngLoader.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + + +static inline uint32_t PREMULTIPLY(uint32_t c) +{ + auto a = (c >> 24); + return (c & 0xff000000) + ((((c >> 8) & 0xff) * a) & 0xff00) + ((((c & 0x00ff00ff) * a) >> 8) & 0x00ff00ff); +} + + +static void _premultiply(uint32_t* data, uint32_t w, uint32_t h) +{ + auto buffer = data; + for (uint32_t y = 0; y < h; ++y, buffer += w) { + auto src = buffer; + for (uint32_t x = 0; x < w; ++x, ++src) { + *src = PREMULTIPLY(*src); + } + } +} + + +void PngLoader::clear() +{ + lodepng_state_cleanup(&state); + + if (freeData) free(data); + data = nullptr; + size = 0; + freeData = false; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +PngLoader::PngLoader() +{ + lodepng_state_init(&state); +} + + +PngLoader::~PngLoader() +{ + if (freeData) free(data); +} + + +bool PngLoader::open(const string& path) +{ + clear(); + + auto pngFile = fopen(path.c_str(), "rb"); + if (!pngFile) return false; + + auto ret = false; + + //determine size + if (fseek(pngFile, 0, SEEK_END) < 0) goto finalize; + if (((size = ftell(pngFile)) < 1)) goto finalize; + if (fseek(pngFile, 0, SEEK_SET)) goto finalize; + + data = (unsigned char *) malloc(size); + if (!data) goto finalize; + + freeData = true; + + if (fread(data, size, 1, pngFile) < 1) goto failure; + + lodepng_state_init(&state); + + unsigned int width, height; + if (lodepng_inspect(&width, &height, &state, data, size) > 0) goto failure; + + w = static_cast<float>(width); + h = static_cast<float>(height); + ret = true; + + goto finalize; + +failure: + clear(); + +finalize: + fclose(pngFile); + return ret; +} + + +bool PngLoader::open(const char* data, uint32_t size, bool copy) +{ + clear(); + + lodepng_state_init(&state); + + unsigned int width, height; + if (lodepng_inspect(&width, &height, &state, (unsigned char*)(data), size) > 0) return false; + + if (copy) { + this->data = (unsigned char *) malloc(size); + if (!this->data) return false; + memcpy((unsigned char *)this->data, data, size); + freeData = true; + } else { + this->data = (unsigned char *) data; + freeData = false; + } + + w = static_cast<float>(width); + h = static_cast<float>(height); + this->size = size; + + return true; +} + + +bool PngLoader::read() +{ + if (!data || w <= 0 || h <= 0) return false; + + TaskScheduler::request(this); + + return true; +} + + +bool PngLoader::close() +{ + this->done(); + clear(); + return true; +} + + +unique_ptr<Surface> PngLoader::bitmap() +{ + this->done(); + + if (!image) return nullptr; + + auto surface = static_cast<Surface*>(malloc(sizeof(Surface))); + surface->buffer = (uint32_t*)(image); + surface->stride = w; + surface->w = w; + surface->h = h; + surface->cs = SwCanvas::ARGB8888; + + return unique_ptr<Surface>(surface); +} + + +void PngLoader::run(unsigned tid) +{ + auto width = static_cast<unsigned>(w); + auto height = static_cast<unsigned>(h); + + lodepng_decode(&image, &width, &height, &state, data, size); + + _premultiply((uint32_t*)(image), width, height); +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.h b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.h new file mode 100644 index 0000000000..34dbeed012 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_PNG_LOADER_H_ +#define _TVG_PNG_LOADER_H_ + +#include "tvgLodePng.h" +#include "tvgTaskScheduler.h" + + +class PngLoader : public LoadModule, public Task +{ +private: + LodePNGState state; + unsigned char* data = nullptr; + unsigned char *image = nullptr; + unsigned long size = 0; + bool freeData = false; + + void clear(); + +public: + PngLoader(); + ~PngLoader(); + + using LoadModule::open; + bool open(const string& path) override; + bool open(const char* data, uint32_t size, bool copy) override; + bool read() override; + bool close() override; + + unique_ptr<Surface> bitmap() override; + void run(unsigned tid) override; +}; + +#endif //_TVG_PNG_LOADER_H_ diff --git a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp new file mode 100644 index 0000000000..d7d425b119 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include <fstream> +#include <string.h> +#include "tvgLoader.h" +#include "tvgRawLoader.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +RawLoader::~RawLoader() +{ + if (copy && content) { + free((void*)content); + content = nullptr; + } +} + + +bool RawLoader::open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) +{ + if (!data || w == 0 || h == 0) return false; + + this->w = (float)w; + this->h = (float)h; + this->copy = copy; + + if (copy) { + content = (uint32_t*)malloc(sizeof(uint32_t) * w * h); + if (!content) return false; + memcpy((void*)content, data, sizeof(uint32_t) * w * h); + } + else content = data; + + return true; +} + + +bool RawLoader::read() +{ + return true; +} + + +bool RawLoader::close() +{ + return true; +} + + +unique_ptr<Surface> RawLoader::bitmap() +{ + if (!content) return nullptr; + + auto surface = static_cast<Surface*>(malloc(sizeof(Surface))); + surface->buffer = (uint32_t*)(content); + surface->stride = w; + surface->w = w; + surface->h = h; + surface->cs = SwCanvas::ARGB8888; + + return unique_ptr<Surface>(surface); +} diff --git a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h new file mode 100644 index 0000000000..20fa332981 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_RAW_LOADER_H_ +#define _TVG_RAW_LOADER_H_ + +class RawLoader : public LoadModule +{ +public: + const uint32_t* content = nullptr; + bool copy = false; + + ~RawLoader(); + + using LoadModule::open; + bool open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) override; + bool read() override; + bool close() override; + + unique_ptr<Surface> bitmap() override; +}; + + +#endif //_TVG_RAW_LOADER_H_ diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp new file mode 100644 index 0000000000..def8ae169a --- /dev/null +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp @@ -0,0 +1,3007 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Copyright notice for the EFL: + + * Copyright (C) EFL developers (see AUTHORS) + + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#define _USE_MATH_DEFINES //Math Constants are not defined in Standard C/C++. + +#include <fstream> +#include <float.h> +#include <math.h> +#include "tvgLoader.h" +#include "tvgXmlParser.h" +#include "tvgSvgLoader.h" +#include "tvgSvgSceneBuilder.h" +#include "tvgSvgUtil.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +/* + * According to: https://www.w3.org/TR/SVG2/coords.html#Units + * and: https://www.w3.org/TR/css-values-4/#absolute-lengths + */ +#define PX_PER_IN 96 //1 in = 96 px +#define PX_PER_PC 16 //1 pc = 1/6 in -> PX_PER_IN/6 +#define PX_PER_PT 1.333333f //1 pt = 1/72 in -> PX_PER_IN/72 +#define PX_PER_MM 3.779528f //1 in = 25.4 mm -> PX_PER_IN/25.4 +#define PX_PER_CM 37.79528f //1 in = 2.54 cm -> PX_PER_IN/2.54 + + +typedef SvgNode* (*FactoryMethod)(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength); +typedef SvgStyleGradient* (*GradientFactoryMethod)(SvgLoaderData* loader, const char* buf, unsigned bufLength); + + +static char* _skipSpace(const char* str, const char* end) +{ + while (((end && str < end) || (!end && *str != '\0')) && isspace(*str)) { + ++str; + } + return (char*) str; +} + + +static char* _copyId(const char* str) +{ + if (!str) return nullptr; + + return strdup(str); +} + + +static const char* _skipComma(const char* content) +{ + content = _skipSpace(content, nullptr); + if (*content == ',') return content + 1; + return content; +} + + +static bool _parseNumber(const char** content, float* number) +{ + char* end = nullptr; + + *number = svgUtilStrtof(*content, &end); + //If the start of string is not number + if ((*content) == end) return false; + //Skip comma if any + *content = _skipComma(end); + return true; +} + +/** + * According to https://www.w3.org/TR/SVG/coords.html#Units + */ +static float _toFloat(const SvgParser* svgParse, const char* str, SvgParserLengthType type) +{ + float parsedValue = svgUtilStrtof(str, nullptr); + + if (strstr(str, "cm")) parsedValue *= PX_PER_CM; + else if (strstr(str, "mm")) parsedValue *= PX_PER_MM; + else if (strstr(str, "pt")) parsedValue *= PX_PER_PT; + else if (strstr(str, "pc")) parsedValue *= PX_PER_PC; + else if (strstr(str, "in")) parsedValue *= PX_PER_IN; + else if (strstr(str, "%")) { + if (type == SvgParserLengthType::Vertical) parsedValue = (parsedValue / 100.0) * svgParse->global.h; + else if (type == SvgParserLengthType::Horizontal) parsedValue = (parsedValue / 100.0) * svgParse->global.w; + else //if other then it's radius + { + float max = (float)svgParse->global.w; + if (max < svgParse->global.h) + max = (float)svgParse->global.h; + parsedValue = (parsedValue / 100.0) * max; + } + } + //TODO: Implement 'em', 'ex' attributes + + return parsedValue; +} + + +static float _gradientToFloat(const SvgParser* svgParse, const char* str, bool& isPercentage) +{ + char* end = nullptr; + + float parsedValue = svgUtilStrtof(str, &end); + isPercentage = false; + + if (strstr(str, "%")) { + parsedValue = parsedValue / 100.0; + isPercentage = true; + } + else if (strstr(str, "cm")) parsedValue *= PX_PER_CM; + else if (strstr(str, "mm")) parsedValue *= PX_PER_MM; + else if (strstr(str, "pt")) parsedValue *= PX_PER_PT; + else if (strstr(str, "pc")) parsedValue *= PX_PER_PC; + else if (strstr(str, "in")) parsedValue *= PX_PER_IN; + //TODO: Implement 'em', 'ex' attributes + + return parsedValue; +} + + +static float _toOffset(const char* str) +{ + char* end = nullptr; + auto strEnd = str + strlen(str); + + float parsedValue = svgUtilStrtof(str, &end); + + end = _skipSpace(end, nullptr); + auto ptr = strstr(str, "%"); + + if (ptr) { + parsedValue = parsedValue / 100.0; + if (end != ptr || (end + 1) != strEnd) return 0; + } else if (end != strEnd) return 0; + + return parsedValue; +} + + +static int _toOpacity(const char* str) +{ + char* end = nullptr; + float opacity = svgUtilStrtof(str, &end); + + if (end) { + if (end[0] == '%' && end[1] == '\0') return lrint(opacity * 2.55f); + else if (*end == '\0') return lrint(opacity * 255); + } + return 255; +} + + +#define _PARSE_TAG(Type, Name, Name1, Tags_Array, Default) \ + static Type _to##Name1(const char* str) \ + { \ + unsigned int i; \ + \ + for (i = 0; i < sizeof(Tags_Array) / sizeof(Tags_Array[0]); i++) { \ + if (!strcmp(str, Tags_Array[i].tag)) return Tags_Array[i].Name; \ + } \ + return Default; \ + } + + +/* parse the line cap used during stroking a path. + * Value: butt | round | square | inherit + * Initial: butt + * https://www.w3.org/TR/SVG/painting.html + */ +static constexpr struct +{ + StrokeCap lineCap; + const char* tag; +} lineCapTags[] = { + { StrokeCap::Butt, "butt" }, + { StrokeCap::Round, "round" }, + { StrokeCap::Square, "square" } +}; + + +_PARSE_TAG(StrokeCap, lineCap, LineCap, lineCapTags, StrokeCap::Butt) + + +/* parse the line join used during stroking a path. + * Value: miter | round | bevel | inherit + * Initial: miter + * https://www.w3.org/TR/SVG/painting.html + */ +static constexpr struct +{ + StrokeJoin lineJoin; + const char* tag; +} lineJoinTags[] = { + { StrokeJoin::Miter, "miter" }, + { StrokeJoin::Round, "round" }, + { StrokeJoin::Bevel, "bevel" } +}; + + +_PARSE_TAG(StrokeJoin, lineJoin, LineJoin, lineJoinTags, StrokeJoin::Miter) + + +/* parse the fill rule used during filling a path. + * Value: nonzero | evenodd | inherit + * Initial: nonzero + * https://www.w3.org/TR/SVG/painting.html + */ +static constexpr struct +{ + FillRule fillRule; + const char* tag; +} fillRuleTags[] = { + { FillRule::EvenOdd, "evenodd" } +}; + + +_PARSE_TAG(FillRule, fillRule, FillRule, fillRuleTags, FillRule::Winding) + + +/* parse the dash pattern used during stroking a path. + * Value: none | <dasharray> | inherit + * Initial: none + * https://www.w3.org/TR/SVG/painting.html + */ +static void _parseDashArray(SvgLoaderData* loader, const char *str, SvgDash* dash) +{ + if (!strncmp(str, "none", 4)) return; + + char *end = nullptr; + + while (*str) { + str = _skipComma(str); + float parsedValue = svgUtilStrtof(str, &end); + if (str == end) break; + if (parsedValue <= 0.0f) break; + if (*end == '%') { + ++end; + //Refers to the diagonal length of the viewport. + //https://www.w3.org/TR/SVG2/coords.html#Units + parsedValue = (sqrtf(pow(loader->svgParse->global.w, 2) + pow(loader->svgParse->global.h, 2)) / sqrtf(2.0f)) * (parsedValue / 100.0f); + } + (*dash).array.push(parsedValue); + str = end; + } + //If dash array size is 1, it means that dash and gap size are the same. + if ((*dash).array.count == 1) (*dash).array.push((*dash).array.data[0]); +} + + +static char* _idFromUrl(const char* url) +{ + url = _skipSpace(url, nullptr); + if ((*url) == '(') { + ++url; + url = _skipSpace(url, nullptr); + } + + if ((*url) == '\'') ++url; + if ((*url) == '#') ++url; + + int i = 0; + while (url[i] > ' ' && url[i] != ')' && url[i] != '\'') ++i; + + //custom strndup() for portability + int len = strlen(url); + if (i < len) len = i; + + auto ret = (char*) malloc(len + 1); + if (!ret) return 0; + ret[len] = '\0'; + return (char*) memcpy(ret, url, len); +} + + +static unsigned char _parserColor(const char* value, char** end) +{ + float r; + + r = svgUtilStrtof(value, end); + *end = _skipSpace(*end, nullptr); + if (**end == '%') r = 255 * r / 100; + *end = _skipSpace(*end, nullptr); + + if (r < 0 || r > 255) { + *end = nullptr; + return 0; + } + + return lrint(r); +} + + +static constexpr struct +{ + const char* name; + unsigned int value; +} colors[] = { + { "aliceblue", 0xfff0f8ff }, + { "antiquewhite", 0xfffaebd7 }, + { "aqua", 0xff00ffff }, + { "aquamarine", 0xff7fffd4 }, + { "azure", 0xfff0ffff }, + { "beige", 0xfff5f5dc }, + { "bisque", 0xffffe4c4 }, + { "black", 0xff000000 }, + { "blanchedalmond", 0xffffebcd }, + { "blue", 0xff0000ff }, + { "blueviolet", 0xff8a2be2 }, + { "brown", 0xffa52a2a }, + { "burlywood", 0xffdeb887 }, + { "cadetblue", 0xff5f9ea0 }, + { "chartreuse", 0xff7fff00 }, + { "chocolate", 0xffd2691e }, + { "coral", 0xffff7f50 }, + { "cornflowerblue", 0xff6495ed }, + { "cornsilk", 0xfffff8dc }, + { "crimson", 0xffdc143c }, + { "cyan", 0xff00ffff }, + { "darkblue", 0xff00008b }, + { "darkcyan", 0xff008b8b }, + { "darkgoldenrod", 0xffb8860b }, + { "darkgray", 0xffa9a9a9 }, + { "darkgrey", 0xffa9a9a9 }, + { "darkgreen", 0xff006400 }, + { "darkkhaki", 0xffbdb76b }, + { "darkmagenta", 0xff8b008b }, + { "darkolivegreen", 0xff556b2f }, + { "darkorange", 0xffff8c00 }, + { "darkorchid", 0xff9932cc }, + { "darkred", 0xff8b0000 }, + { "darksalmon", 0xffe9967a }, + { "darkseagreen", 0xff8fbc8f }, + { "darkslateblue", 0xff483d8b }, + { "darkslategray", 0xff2f4f4f }, + { "darkslategrey", 0xff2f4f4f }, + { "darkturquoise", 0xff00ced1 }, + { "darkviolet", 0xff9400d3 }, + { "deeppink", 0xffff1493 }, + { "deepskyblue", 0xff00bfff }, + { "dimgray", 0xff696969 }, + { "dimgrey", 0xff696969 }, + { "dodgerblue", 0xff1e90ff }, + { "firebrick", 0xffb22222 }, + { "floralwhite", 0xfffffaf0 }, + { "forestgreen", 0xff228b22 }, + { "fuchsia", 0xffff00ff }, + { "gainsboro", 0xffdcdcdc }, + { "ghostwhite", 0xfff8f8ff }, + { "gold", 0xffffd700 }, + { "goldenrod", 0xffdaa520 }, + { "gray", 0xff808080 }, + { "grey", 0xff808080 }, + { "green", 0xff008000 }, + { "greenyellow", 0xffadff2f }, + { "honeydew", 0xfff0fff0 }, + { "hotpink", 0xffff69b4 }, + { "indianred", 0xffcd5c5c }, + { "indigo", 0xff4b0082 }, + { "ivory", 0xfffffff0 }, + { "khaki", 0xfff0e68c }, + { "lavender", 0xffe6e6fa }, + { "lavenderblush", 0xfffff0f5 }, + { "lawngreen", 0xff7cfc00 }, + { "lemonchiffon", 0xfffffacd }, + { "lightblue", 0xffadd8e6 }, + { "lightcoral", 0xfff08080 }, + { "lightcyan", 0xffe0ffff }, + { "lightgoldenrodyellow", 0xfffafad2 }, + { "lightgray", 0xffd3d3d3 }, + { "lightgrey", 0xffd3d3d3 }, + { "lightgreen", 0xff90ee90 }, + { "lightpink", 0xffffb6c1 }, + { "lightsalmon", 0xffffa07a }, + { "lightseagreen", 0xff20b2aa }, + { "lightskyblue", 0xff87cefa }, + { "lightslategray", 0xff778899 }, + { "lightslategrey", 0xff778899 }, + { "lightsteelblue", 0xffb0c4de }, + { "lightyellow", 0xffffffe0 }, + { "lime", 0xff00ff00 }, + { "limegreen", 0xff32cd32 }, + { "linen", 0xfffaf0e6 }, + { "magenta", 0xffff00ff }, + { "maroon", 0xff800000 }, + { "mediumaquamarine", 0xff66cdaa }, + { "mediumblue", 0xff0000cd }, + { "mediumorchid", 0xffba55d3 }, + { "mediumpurple", 0xff9370d8 }, + { "mediumseagreen", 0xff3cb371 }, + { "mediumslateblue", 0xff7b68ee }, + { "mediumspringgreen", 0xff00fa9a }, + { "mediumturquoise", 0xff48d1cc }, + { "mediumvioletred", 0xffc71585 }, + { "midnightblue", 0xff191970 }, + { "mintcream", 0xfff5fffa }, + { "mistyrose", 0xffffe4e1 }, + { "moccasin", 0xffffe4b5 }, + { "navajowhite", 0xffffdead }, + { "navy", 0xff000080 }, + { "oldlace", 0xfffdf5e6 }, + { "olive", 0xff808000 }, + { "olivedrab", 0xff6b8e23 }, + { "orange", 0xffffa500 }, + { "orangered", 0xffff4500 }, + { "orchid", 0xffda70d6 }, + { "palegoldenrod", 0xffeee8aa }, + { "palegreen", 0xff98fb98 }, + { "paleturquoise", 0xffafeeee }, + { "palevioletred", 0xffd87093 }, + { "papayawhip", 0xffffefd5 }, + { "peachpuff", 0xffffdab9 }, + { "peru", 0xffcd853f }, + { "pink", 0xffffc0cb }, + { "plum", 0xffdda0dd }, + { "powderblue", 0xffb0e0e6 }, + { "purple", 0xff800080 }, + { "red", 0xffff0000 }, + { "rosybrown", 0xffbc8f8f }, + { "royalblue", 0xff4169e1 }, + { "saddlebrown", 0xff8b4513 }, + { "salmon", 0xfffa8072 }, + { "sandybrown", 0xfff4a460 }, + { "seagreen", 0xff2e8b57 }, + { "seashell", 0xfffff5ee }, + { "sienna", 0xffa0522d }, + { "silver", 0xffc0c0c0 }, + { "skyblue", 0xff87ceeb }, + { "slateblue", 0xff6a5acd }, + { "slategray", 0xff708090 }, + { "slategrey", 0xff708090 }, + { "snow", 0xfffffafa }, + { "springgreen", 0xff00ff7f }, + { "steelblue", 0xff4682b4 }, + { "tan", 0xffd2b48c }, + { "teal", 0xff008080 }, + { "thistle", 0xffd8bfd8 }, + { "tomato", 0xffff6347 }, + { "turquoise", 0xff40e0d0 }, + { "violet", 0xffee82ee }, + { "wheat", 0xfff5deb3 }, + { "white", 0xffffffff }, + { "whitesmoke", 0xfff5f5f5 }, + { "yellow", 0xffffff00 }, + { "yellowgreen", 0xff9acd32 } +}; + + +static void _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char** ref) +{ + unsigned int len = strlen(str); + char *red, *green, *blue; + unsigned char tr, tg, tb; + + if (len == 4 && str[0] == '#') { + //Case for "#456" should be interprete as "#445566" + if (isxdigit(str[1]) && isxdigit(str[2]) && isxdigit(str[3])) { + char tmp[3] = { '\0', '\0', '\0' }; + tmp[0] = str[1]; + tmp[1] = str[1]; + *r = strtol(tmp, nullptr, 16); + tmp[0] = str[2]; + tmp[1] = str[2]; + *g = strtol(tmp, nullptr, 16); + tmp[0] = str[3]; + tmp[1] = str[3]; + *b = strtol(tmp, nullptr, 16); + } + } else if (len == 7 && str[0] == '#') { + if (isxdigit(str[1]) && isxdigit(str[2]) && isxdigit(str[3]) && isxdigit(str[4]) && isxdigit(str[5]) && isxdigit(str[6])) { + char tmp[3] = { '\0', '\0', '\0' }; + tmp[0] = str[1]; + tmp[1] = str[2]; + *r = strtol(tmp, nullptr, 16); + tmp[0] = str[3]; + tmp[1] = str[4]; + *g = strtol(tmp, nullptr, 16); + tmp[0] = str[5]; + tmp[1] = str[6]; + *b = strtol(tmp, nullptr, 16); + } + } else if (len >= 10 && (str[0] == 'r' || str[0] == 'R') && (str[1] == 'g' || str[1] == 'G') && (str[2] == 'b' || str[2] == 'B') && str[3] == '(' && str[len - 1] == ')') { + tr = _parserColor(str + 4, &red); + if (red && *red == ',') { + tg = _parserColor(red + 1, &green); + if (green && *green == ',') { + tb = _parserColor(green + 1, &blue); + if (blue && blue[0] == ')' && blue[1] == '\0') { + *r = tr; + *g = tg; + *b = tb; + } + } + } + } else if (len >= 3 && !strncmp(str, "url", 3)) { + *ref = _idFromUrl((const char*)(str + 3)); + } else { + //Handle named color + for (unsigned int i = 0; i < (sizeof(colors) / sizeof(colors[0])); i++) { + if (!strcasecmp(colors[i].name, str)) { + *r = (((uint8_t*)(&(colors[i].value)))[2]); + *g = (((uint8_t*)(&(colors[i].value)))[1]); + *b = (((uint8_t*)(&(colors[i].value)))[0]); + return; + } + } + } +} + + +static char* _parseNumbersArray(char* str, float* points, int* ptCount, int len) +{ + int count = 0; + char* end = nullptr; + + str = _skipSpace(str, nullptr); + while ((count < len) && (isdigit(*str) || *str == '-' || *str == '+' || *str == '.')) { + points[count++] = svgUtilStrtof(str, &end); + str = end; + str = _skipSpace(str, nullptr); + if (*str == ',') ++str; + //Eat the rest of space + str = _skipSpace(str, nullptr); + } + *ptCount = count; + return str; +} + + +enum class MatrixState { + Unknown, + Matrix, + Translate, + Rotate, + Scale, + SkewX, + SkewY +}; + + +#define MATRIX_DEF(Name, Value) \ + { \ +#Name, sizeof(#Name), Value \ + } + + +static constexpr struct +{ + const char* tag; + int sz; + MatrixState state; +} matrixTags[] = { + MATRIX_DEF(matrix, MatrixState::Matrix), + MATRIX_DEF(translate, MatrixState::Translate), + MATRIX_DEF(rotate, MatrixState::Rotate), + MATRIX_DEF(scale, MatrixState::Scale), + MATRIX_DEF(skewX, MatrixState::SkewX), + MATRIX_DEF(skewY, MatrixState::SkewY) +}; + + +static void _matrixCompose(const Matrix* m1, const Matrix* m2, Matrix* dst) +{ + auto a11 = (m1->e11 * m2->e11) + (m1->e12 * m2->e21) + (m1->e13 * m2->e31); + auto a12 = (m1->e11 * m2->e12) + (m1->e12 * m2->e22) + (m1->e13 * m2->e32); + auto a13 = (m1->e11 * m2->e13) + (m1->e12 * m2->e23) + (m1->e13 * m2->e33); + + auto a21 = (m1->e21 * m2->e11) + (m1->e22 * m2->e21) + (m1->e23 * m2->e31); + auto a22 = (m1->e21 * m2->e12) + (m1->e22 * m2->e22) + (m1->e23 * m2->e32); + auto a23 = (m1->e21 * m2->e13) + (m1->e22 * m2->e23) + (m1->e23 * m2->e33); + + auto a31 = (m1->e31 * m2->e11) + (m1->e32 * m2->e21) + (m1->e33 * m2->e31); + auto a32 = (m1->e31 * m2->e12) + (m1->e32 * m2->e22) + (m1->e33 * m2->e32); + auto a33 = (m1->e31 * m2->e13) + (m1->e32 * m2->e23) + (m1->e33 * m2->e33); + + dst->e11 = a11; + dst->e12 = a12; + dst->e13 = a13; + dst->e21 = a21; + dst->e22 = a22; + dst->e23 = a23; + dst->e31 = a31; + dst->e32 = a32; + dst->e33 = a33; +} + + +/* parse transform attribute + * https://www.w3.org/TR/SVG/coords.html#TransformAttribute + */ +static Matrix* _parseTransformationMatrix(const char* value) +{ + const int POINT_CNT = 8; + + auto matrix = (Matrix*)malloc(sizeof(Matrix)); + if (!matrix) return nullptr; + *matrix = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + + float points[POINT_CNT]; + int ptCount = 0; + char* str = (char*)value; + char* end = str + strlen(str); + + while (str < end) { + auto state = MatrixState::Unknown; + + if (isspace(*str) || (*str == ',')) { + ++str; + continue; + } + for (unsigned int i = 0; i < sizeof(matrixTags) / sizeof(matrixTags[0]); i++) { + if (!strncmp(matrixTags[i].tag, str, matrixTags[i].sz - 1)) { + state = matrixTags[i].state; + str += (matrixTags[i].sz - 1); + break; + } + } + if (state == MatrixState::Unknown) goto error; + + str = _skipSpace(str, end); + if (*str != '(') goto error; + ++str; + str = _parseNumbersArray(str, points, &ptCount, POINT_CNT); + if (*str != ')') goto error; + ++str; + + if (state == MatrixState::Matrix) { + if (ptCount != 6) goto error; + Matrix tmp = {points[0], points[2], points[4], points[1], points[3], points[5], 0, 0, 1}; + _matrixCompose(matrix, &tmp, matrix); + } else if (state == MatrixState::Translate) { + if (ptCount == 1) { + Matrix tmp = {1, 0, points[0], 0, 1, 0, 0, 0, 1}; + _matrixCompose(matrix, &tmp, matrix); + } else if (ptCount == 2) { + Matrix tmp = {1, 0, points[0], 0, 1, points[1], 0, 0, 1}; + _matrixCompose(matrix, &tmp, matrix); + } else goto error; + } else if (state == MatrixState::Rotate) { + //Transform to signed. + points[0] = fmod(points[0], 360); + if (points[0] < 0) points[0] += 360; + auto c = cosf(points[0] * (M_PI / 180.0)); + auto s = sinf(points[0] * (M_PI / 180.0)); + if (ptCount == 1) { + Matrix tmp = { c, -s, 0, s, c, 0, 0, 0, 1 }; + _matrixCompose(matrix, &tmp, matrix); + } else if (ptCount == 3) { + Matrix tmp = { 1, 0, points[1], 0, 1, points[2], 0, 0, 1 }; + _matrixCompose(matrix, &tmp, matrix); + tmp = { c, -s, 0, s, c, 0, 0, 0, 1 }; + _matrixCompose(matrix, &tmp, matrix); + tmp = { 1, 0, -points[1], 0, 1, -points[2], 0, 0, 1 }; + _matrixCompose(matrix, &tmp, matrix); + } else { + goto error; + } + } else if (state == MatrixState::Scale) { + if (ptCount < 1 || ptCount > 2) goto error; + auto sx = points[0]; + auto sy = sx; + if (ptCount == 2) sy = points[1]; + Matrix tmp = { sx, 0, 0, 0, sy, 0, 0, 0, 1 }; + _matrixCompose(matrix, &tmp, matrix); + } + } + return matrix; +error: + if (matrix) free(matrix); + return nullptr; +} + + +#define LENGTH_DEF(Name, Value) \ + { \ +#Name, sizeof(#Name), Value \ + } + + +/* +// TODO - remove? +static constexpr struct +{ + const char* tag; + int sz; + SvgLengthType type; +} lengthTags[] = { + LENGTH_DEF(%, SvgLengthType::Percent), + LENGTH_DEF(px, SvgLengthType::Px), + LENGTH_DEF(pc, SvgLengthType::Pc), + LENGTH_DEF(pt, SvgLengthType::Pt), + LENGTH_DEF(mm, SvgLengthType::Mm), + LENGTH_DEF(cm, SvgLengthType::Cm), + LENGTH_DEF(in, SvgLengthType::In) +}; + +static float _parseLength(const char* str, SvgLengthType* type) +{ + float value; + int sz = strlen(str); + + *type = SvgLengthType::Px; + for (unsigned int i = 0; i < sizeof(lengthTags) / sizeof(lengthTags[0]); i++) { + if (lengthTags[i].sz - 1 == sz && !strncmp(lengthTags[i].tag, str, sz)) *type = lengthTags[i].type; + } + value = svgUtilStrtof(str, nullptr); + return value; +} +*/ + +static bool _parseStyleAttr(void* data, const char* key, const char* value); +static bool _parseStyleAttr(void* data, const char* key, const char* value, bool style); + + +static bool _attrParseSvgNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgDocNode* doc = &(node->node.doc); + + if (!strcmp(key, "width")) { + doc->w = _toFloat(loader->svgParse, value, SvgParserLengthType::Horizontal); + } else if (!strcmp(key, "height")) { + doc->h = _toFloat(loader->svgParse, value, SvgParserLengthType::Vertical); + } else if (!strcmp(key, "viewBox")) { + if (_parseNumber(&value, &doc->vx)) { + if (_parseNumber(&value, &doc->vy)) { + if (_parseNumber(&value, &doc->vw)) { + _parseNumber(&value, &doc->vh); + loader->svgParse->global.h = (uint32_t)doc->vh; + } + loader->svgParse->global.w = (uint32_t)doc->vw; + } + loader->svgParse->global.y = (int)doc->vy; + } + loader->svgParse->global.x = (int)doc->vx; + } else if (!strcmp(key, "preserveAspectRatio")) { + if (!strcmp(value, "none")) doc->preserveAspect = false; + } else if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + } +#ifdef THORVG_LOG_ENABLED + else if ((!strcmp(key, "x") || !strcmp(key, "y")) && fabsf(svgUtilStrtof(value, nullptr)) > FLT_EPSILON ) { + TVGLOG("SVG", "Unsupported attributes used [Elements type: Svg][Attribute: %s][Value: %s]", key, value); + } +#endif + else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +//https://www.w3.org/TR/SVGTiny12/painting.html#SpecifyingPaint +static void _handlePaintAttr(SvgPaint* paint, const char* value) +{ + if (!strcmp(value, "none")) { + //No paint property + paint->none = true; + return; + } + paint->none = false; + if (!strcmp(value, "currentColor")) { + paint->curColor = true; + return; + } + _toColor(value, &paint->color.r, &paint->color.g, &paint->color.b, &paint->url); +} + + +static void _handleColorAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + SvgStyleProperty* style = node->style; + style->curColorSet = true; + _toColor(value, &style->color.r, &style->color.g, &style->color.b, nullptr); +} + + +static void _handleFillAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + SvgStyleProperty* style = node->style; + style->fill.flags = (SvgFillFlags)((int)style->fill.flags | (int)SvgFillFlags::Paint); + _handlePaintAttr(&style->fill.paint, value); +} + + +static void _handleStrokeAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + SvgStyleProperty* style = node->style; + style->stroke.flags = (SvgStrokeFlags)((int)style->stroke.flags | (int)SvgStrokeFlags::Paint); + _handlePaintAttr(&style->stroke.paint, value); +} + + +static void _handleStrokeOpacityAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->stroke.flags = (SvgStrokeFlags)((int)node->style->stroke.flags | (int)SvgStrokeFlags::Opacity); + node->style->stroke.opacity = _toOpacity(value); +} + +static void _handleStrokeDashArrayAttr(SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->stroke.flags = (SvgStrokeFlags)((int)node->style->stroke.flags | (int)SvgStrokeFlags::Dash); + _parseDashArray(loader, value, &node->style->stroke.dash); +} + +static void _handleStrokeWidthAttr(SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->stroke.flags = (SvgStrokeFlags)((int)node->style->stroke.flags | (int)SvgStrokeFlags::Width); + node->style->stroke.width = _toFloat(loader->svgParse, value, SvgParserLengthType::Horizontal); +} + + +static void _handleStrokeLineCapAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->stroke.flags = (SvgStrokeFlags)((int)node->style->stroke.flags | (int)SvgStrokeFlags::Cap); + node->style->stroke.cap = _toLineCap(value); +} + + +static void _handleStrokeLineJoinAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->stroke.flags = (SvgStrokeFlags)((int)node->style->stroke.flags | (int)SvgStrokeFlags::Join); + node->style->stroke.join = _toLineJoin(value); +} + + +static void _handleFillRuleAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->fill.flags = (SvgFillFlags)((int)node->style->fill.flags | (int)SvgFillFlags::FillRule); + node->style->fill.fillRule = _toFillRule(value); +} + + +static void _handleOpacityAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->opacity = _toOpacity(value); +} + + +static void _handleFillOpacityAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->style->fill.flags = (SvgFillFlags)((int)node->style->fill.flags | (int)SvgFillFlags::Opacity); + node->style->fill.opacity = _toOpacity(value); +} + + +static void _handleTransformAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->transform = _parseTransformationMatrix(value); +} + + +static void _handleClipPathAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + SvgStyleProperty* style = node->style; + int len = strlen(value); + if (len >= 3 && !strncmp(value, "url", 3)) { + if (style->clipPath.url) free(style->clipPath.url); + style->clipPath.url = _idFromUrl((const char*)(value + 3)); + } +} + + +static void _handleMaskAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + SvgStyleProperty* style = node->style; + int len = strlen(value); + if (len >= 3 && !strncmp(value, "url", 3)) { + if (style->mask.url) free(style->mask.url); + style->mask.url = _idFromUrl((const char*)(value + 3)); + } +} + + +static void _handleDisplayAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + //TODO : The display attribute can have various values as well as "none". + // The default is "inline" which means visible and "none" means invisible. + // Depending on the type of node, additional functionality may be required. + // refer to https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/display + if (!strcmp(value, "none")) node->display = false; + else node->display = true; +} + + +typedef void (*styleMethod)(SvgLoaderData* loader, SvgNode* node, const char* value); + +#define STYLE_DEF(Name, Name1, Flag) { #Name, sizeof(#Name), _handle##Name1##Attr, Flag } + + +static constexpr struct +{ + const char* tag; + int sz; + styleMethod tagHandler; + SvgStyleFlags flag; +} styleTags[] = { + STYLE_DEF(color, Color, SvgStyleFlags::Color), + STYLE_DEF(fill, Fill, SvgStyleFlags::Fill), + STYLE_DEF(fill-rule, FillRule, SvgStyleFlags::FillRule), + STYLE_DEF(fill-opacity, FillOpacity, SvgStyleFlags::FillOpacity), + STYLE_DEF(opacity, Opacity, SvgStyleFlags::Opacity), + STYLE_DEF(stroke, Stroke, SvgStyleFlags::Stroke), + STYLE_DEF(stroke-width, StrokeWidth, SvgStyleFlags::StrokeWidth), + STYLE_DEF(stroke-linejoin, StrokeLineJoin, SvgStyleFlags::StrokeLineJoin), + STYLE_DEF(stroke-linecap, StrokeLineCap, SvgStyleFlags::StrokeLineCap), + STYLE_DEF(stroke-opacity, StrokeOpacity, SvgStyleFlags::StrokeOpacity), + STYLE_DEF(stroke-dasharray, StrokeDashArray, SvgStyleFlags::StrokeDashArray), + STYLE_DEF(transform, Transform, SvgStyleFlags::Transform), + STYLE_DEF(clip-path, ClipPath, SvgStyleFlags::ClipPath), + STYLE_DEF(mask, Mask, SvgStyleFlags::Mask), + STYLE_DEF(display, Display, SvgStyleFlags::Display) +}; + + +static bool _parseStyleAttr(void* data, const char* key, const char* value, bool style) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + int sz; + if (!key || !value) return false; + + //Trim the white space + key = _skipSpace(key, nullptr); + value = _skipSpace(value, nullptr); + + sz = strlen(key); + for (unsigned int i = 0; i < sizeof(styleTags) / sizeof(styleTags[0]); i++) { + if (styleTags[i].sz - 1 == sz && !strncmp(styleTags[i].tag, key, sz)) { + if (style) { + styleTags[i].tagHandler(loader, node, value); + node->style->flags = (SvgStyleFlags)((int)node->style->flags | (int)styleTags[i].flag); + } else if (!((int)node->style->flags & (int)styleTags[i].flag)) { + styleTags[i].tagHandler(loader, node, value); + } + return true; + } + } + + return false; +} + + +static bool _parseStyleAttr(void* data, const char* key, const char* value) +{ + return _parseStyleAttr(data, key, value, true); +} + + +/* parse g node + * https://www.w3.org/TR/SVG/struct.html#Groups + */ +static bool _attrParseGNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + + if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + } else if (!strcmp(key, "transform")) { + node->transform = _parseTransformationMatrix(value); + } else if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +/* parse clipPath node + * https://www.w3.org/TR/SVG/struct.html#Groups + */ +static bool _attrParseClipPathNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgCompositeNode* comp = &(node->node.comp); + + if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + } else if (!strcmp(key, "transform")) { + node->transform = _parseTransformationMatrix(value); + } else if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "clipPathUnits")) { + if (!strcmp(value, "objectBoundingBox")) comp->userSpace = false; + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +static bool _attrParseMaskNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgCompositeNode* comp = &(node->node.comp); + + if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + } else if (!strcmp(key, "transform")) { + node->transform = _parseTransformationMatrix(value); + } else if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "maskContentUnits")) { + if (!strcmp(value, "objectBoundingBox")) comp->userSpace = false; + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +static SvgNode* _createNode(SvgNode* parent, SvgNodeType type) +{ + SvgNode* node = (SvgNode*)calloc(1, sizeof(SvgNode)); + + if (!node) return nullptr; + + //Default fill property + node->style = (SvgStyleProperty*)calloc(1, sizeof(SvgStyleProperty)); + + if (!node->style) { + free(node); + return nullptr; + } + + //Update the default value of stroke and fill + //https://www.w3.org/TR/SVGTiny12/painting.html#SpecifyingPaint + node->style->fill.paint.none = false; + //Default fill opacity is 1 + node->style->fill.opacity = 255; + node->style->opacity = 255; + //Default current color is not set + node->style->fill.paint.curColor = false; + node->style->curColorSet = false; + //Default fill rule is nonzero + node->style->fill.fillRule = FillRule::Winding; + + //Default stroke is none + node->style->stroke.paint.none = true; + //Default stroke opacity is 1 + node->style->stroke.opacity = 255; + //Default stroke current color is not set + node->style->stroke.paint.curColor = false; + //Default stroke width is 1 + node->style->stroke.width = 1; + //Default line cap is butt + node->style->stroke.cap = StrokeCap::Butt; + //Default line join is miter + node->style->stroke.join = StrokeJoin::Miter; + node->style->stroke.scale = 1.0; + + //Default display is true("inline"). + node->display = true; + + node->parent = parent; + node->type = type; + + if (parent) parent->child.push(node); + return node; +} + + +static SvgNode* _createDefsNode(TVG_UNUSED SvgLoaderData* loader, TVG_UNUSED SvgNode* parent, const char* buf, unsigned bufLength) +{ + if (loader->def && loader->doc->node.doc.defs) return loader->def; + SvgNode* node = _createNode(nullptr, SvgNodeType::Defs); + + loader->def = node; + loader->doc->node.doc.defs = node; + return node; +} + + +static SvgNode* _createGNode(TVG_UNUSED SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::G); + if (!loader->svgParse->node) return nullptr; + + simpleXmlParseAttributes(buf, bufLength, _attrParseGNode, loader); + return loader->svgParse->node; +} + + +static SvgNode* _createSvgNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Doc); + if (!loader->svgParse->node) return nullptr; + SvgDocNode* doc = &(loader->svgParse->node->node.doc); + + loader->svgParse->global.w = 0; + loader->svgParse->global.h = 0; + + doc->preserveAspect = true; + simpleXmlParseAttributes(buf, bufLength, _attrParseSvgNode, loader); + + if (loader->svgParse->global.w == 0) { + if (doc->w < FLT_EPSILON) loader->svgParse->global.w = 1; + else loader->svgParse->global.w = (uint32_t)doc->w; + } + if (loader->svgParse->global.h == 0) { + if (doc->h < FLT_EPSILON) loader->svgParse->global.h = 1; + else loader->svgParse->global.h = (uint32_t)doc->h; + } + + return loader->svgParse->node; +} + + +static SvgNode* _createMaskNode(SvgLoaderData* loader, SvgNode* parent, TVG_UNUSED const char* buf, TVG_UNUSED unsigned bufLength) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Mask); + if (!loader->svgParse->node) return nullptr; + + loader->svgParse->node->node.comp.userSpace = true; + + simpleXmlParseAttributes(buf, bufLength, _attrParseMaskNode, loader); + + return loader->svgParse->node; +} + + +static SvgNode* _createClipPathNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::ClipPath); + if (!loader->svgParse->node) return nullptr; + + loader->svgParse->node->display = false; + loader->svgParse->node->node.comp.userSpace = true; + + simpleXmlParseAttributes(buf, bufLength, _attrParseClipPathNode, loader); + + return loader->svgParse->node; +} + +static bool _attrParsePathNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgPathNode* path = &(node->node.path); + + if (!strcmp(key, "d")) { + //Temporary: need to copy + path->path = _copyId(value); + } else if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +static SvgNode* _createPathNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Path); + + if (!loader->svgParse->node) return nullptr; + + simpleXmlParseAttributes(buf, bufLength, _attrParsePathNode, loader); + + return loader->svgParse->node; +} + + +static constexpr struct +{ + const char* tag; + SvgParserLengthType type; + int sz; + size_t offset; +} circleTags[] = { + {"cx", SvgParserLengthType::Horizontal, sizeof("cx"), offsetof(SvgCircleNode, cx)}, + {"cy", SvgParserLengthType::Vertical, sizeof("cy"), offsetof(SvgCircleNode, cy)}, + {"r", SvgParserLengthType::Other, sizeof("r"), offsetof(SvgCircleNode, r)} +}; + + +/* parse the attributes for a circle element. + * https://www.w3.org/TR/SVG/shapes.html#CircleElement + */ +static bool _attrParseCircleNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgCircleNode* circle = &(node->node.circle); + unsigned char* array; + int sz = strlen(key); + + array = (unsigned char*)circle; + for (unsigned int i = 0; i < sizeof(circleTags) / sizeof(circleTags[0]); i++) { + if (circleTags[i].sz - 1 == sz && !strncmp(circleTags[i].tag, key, sz)) { + *((float*)(array + circleTags[i].offset)) = _toFloat(loader->svgParse, value, circleTags[i].type); + return true; + } + } + + if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +static SvgNode* _createCircleNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Circle); + + if (!loader->svgParse->node) return nullptr; + + simpleXmlParseAttributes(buf, bufLength, _attrParseCircleNode, loader); + return loader->svgParse->node; +} + + +static constexpr struct +{ + const char* tag; + SvgParserLengthType type; + int sz; + size_t offset; +} ellipseTags[] = { + {"cx", SvgParserLengthType::Horizontal, sizeof("cx"), offsetof(SvgEllipseNode, cx)}, + {"cy", SvgParserLengthType::Vertical, sizeof("cy"), offsetof(SvgEllipseNode, cy)}, + {"rx", SvgParserLengthType::Horizontal, sizeof("rx"), offsetof(SvgEllipseNode, rx)}, + {"ry", SvgParserLengthType::Vertical, sizeof("ry"), offsetof(SvgEllipseNode, ry)} +}; + + +/* parse the attributes for an ellipse element. + * https://www.w3.org/TR/SVG/shapes.html#EllipseElement + */ +static bool _attrParseEllipseNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgEllipseNode* ellipse = &(node->node.ellipse); + unsigned char* array; + int sz = strlen(key); + + array = (unsigned char*)ellipse; + for (unsigned int i = 0; i < sizeof(ellipseTags) / sizeof(ellipseTags[0]); i++) { + if (ellipseTags[i].sz - 1 == sz && !strncmp(ellipseTags[i].tag, key, sz)) { + *((float*)(array + ellipseTags[i].offset)) = _toFloat(loader->svgParse, value, ellipseTags[i].type); + return true; + } + } + + if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +static SvgNode* _createEllipseNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Ellipse); + + if (!loader->svgParse->node) return nullptr; + + simpleXmlParseAttributes(buf, bufLength, _attrParseEllipseNode, loader); + return loader->svgParse->node; +} + + +static bool _attrParsePolygonPoints(const char* str, float** points, int* ptCount) +{ + float tmp[50]; + int tmpCount = 0; + int count = 0; + float num; + float *pointArray = nullptr, *tmpArray; + + while (_parseNumber(&str, &num)) { + tmp[tmpCount++] = num; + if (tmpCount == 50) { + tmpArray = (float*)realloc(pointArray, (count + tmpCount) * sizeof(float)); + if (!tmpArray) goto error_alloc; + pointArray = tmpArray; + memcpy(&pointArray[count], tmp, tmpCount * sizeof(float)); + count += tmpCount; + tmpCount = 0; + } + } + + if (tmpCount > 0) { + tmpArray = (float*)realloc(pointArray, (count + tmpCount) * sizeof(float)); + if (!tmpArray) goto error_alloc; + pointArray = tmpArray; + memcpy(&pointArray[count], tmp, tmpCount * sizeof(float)); + count += tmpCount; + } + *ptCount = count; + *points = pointArray; + return true; + +error_alloc: + return false; +} + + +/* parse the attributes for a polygon element. + * https://www.w3.org/TR/SVG/shapes.html#PolylineElement + */ +static bool _attrParsePolygonNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgPolygonNode* polygon = nullptr; + + if (node->type == SvgNodeType::Polygon) polygon = &(node->node.polygon); + else polygon = &(node->node.polyline); + + if (!strcmp(key, "points")) { + return _attrParsePolygonPoints(value, &polygon->points, &polygon->pointsCount); + } else if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +static SvgNode* _createPolygonNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Polygon); + + if (!loader->svgParse->node) return nullptr; + + simpleXmlParseAttributes(buf, bufLength, _attrParsePolygonNode, loader); + return loader->svgParse->node; +} + + +static SvgNode* _createPolylineNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Polyline); + + if (!loader->svgParse->node) return nullptr; + + simpleXmlParseAttributes(buf, bufLength, _attrParsePolygonNode, loader); + return loader->svgParse->node; +} + +static constexpr struct +{ + const char* tag; + SvgParserLengthType type; + int sz; + size_t offset; +} rectTags[] = { + {"x", SvgParserLengthType::Horizontal, sizeof("x"), offsetof(SvgRectNode, x)}, + {"y", SvgParserLengthType::Vertical, sizeof("y"), offsetof(SvgRectNode, y)}, + {"width", SvgParserLengthType::Horizontal, sizeof("width"), offsetof(SvgRectNode, w)}, + {"height", SvgParserLengthType::Vertical, sizeof("height"), offsetof(SvgRectNode, h)}, + {"rx", SvgParserLengthType::Horizontal, sizeof("rx"), offsetof(SvgRectNode, rx)}, + {"ry", SvgParserLengthType::Vertical, sizeof("ry"), offsetof(SvgRectNode, ry)} +}; + + +/* parse the attributes for a rect element. + * https://www.w3.org/TR/SVG/shapes.html#RectElement + */ +static bool _attrParseRectNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgRectNode* rect = &(node->node.rect); + unsigned char* array; + bool ret = true; + int sz = strlen(key); + + array = (unsigned char*)rect; + for (unsigned int i = 0; i < sizeof(rectTags) / sizeof(rectTags[0]); i++) { + if (rectTags[i].sz - 1 == sz && !strncmp(rectTags[i].tag, key, sz)) { + *((float*)(array + rectTags[i].offset)) = _toFloat(loader->svgParse, value, rectTags[i].type); + + //Case if only rx or ry is declared + if (!strncmp(rectTags[i].tag, "rx", sz)) rect->hasRx = true; + if (!strncmp(rectTags[i].tag, "ry", sz)) rect->hasRy = true; + + if ((rect->rx >= FLT_EPSILON) && (rect->ry < FLT_EPSILON) && rect->hasRx && !rect->hasRy) rect->ry = rect->rx; + if ((rect->ry >= FLT_EPSILON) && (rect->rx < FLT_EPSILON) && !rect->hasRx && rect->hasRy) rect->rx = rect->ry; + return ret; + } + } + + if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "style")) { + ret = simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else { + ret = _parseStyleAttr(loader, key, value, false); + } + + return ret; +} + + +static SvgNode* _createRectNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Rect); + + if (!loader->svgParse->node) return nullptr; + + loader->svgParse->node->node.rect.hasRx = loader->svgParse->node->node.rect.hasRy = false; + + simpleXmlParseAttributes(buf, bufLength, _attrParseRectNode, loader); + return loader->svgParse->node; +} + + +static constexpr struct +{ + const char* tag; + SvgParserLengthType type; + int sz; + size_t offset; +} lineTags[] = { + {"x1", SvgParserLengthType::Horizontal, sizeof("x1"), offsetof(SvgLineNode, x1)}, + {"y1", SvgParserLengthType::Vertical, sizeof("y1"), offsetof(SvgLineNode, y1)}, + {"x2", SvgParserLengthType::Horizontal, sizeof("x2"), offsetof(SvgLineNode, x2)}, + {"y2", SvgParserLengthType::Vertical, sizeof("y2"), offsetof(SvgLineNode, y2)} +}; + + +/* parse the attributes for a line element. + * https://www.w3.org/TR/SVG/shapes.html#LineElement + */ +static bool _attrParseLineNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgLineNode* line = &(node->node.line); + unsigned char* array; + int sz = strlen(key); + + array = (unsigned char*)line; + for (unsigned int i = 0; i < sizeof(lineTags) / sizeof(lineTags[0]); i++) { + if (lineTags[i].sz - 1 == sz && !strncmp(lineTags[i].tag, key, sz)) { + *((float*)(array + lineTags[i].offset)) = _toFloat(loader->svgParse, value, lineTags[i].type); + return true; + } + } + + if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +static SvgNode* _createLineNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Line); + + if (!loader->svgParse->node) return nullptr; + + simpleXmlParseAttributes(buf, bufLength, _attrParseLineNode, loader); + return loader->svgParse->node; +} + + +static char* _idFromHref(const char* href) +{ + href = _skipSpace(href, nullptr); + if ((*href) == '#') href++; + return strdup(href); +} + + +static constexpr struct +{ + const char* tag; + SvgParserLengthType type; + int sz; + size_t offset; +} imageTags[] = { + {"x", SvgParserLengthType::Horizontal, sizeof("x"), offsetof(SvgRectNode, x)}, + {"y", SvgParserLengthType::Vertical, sizeof("y"), offsetof(SvgRectNode, y)}, + {"width", SvgParserLengthType::Horizontal, sizeof("width"), offsetof(SvgRectNode, w)}, + {"height", SvgParserLengthType::Vertical, sizeof("height"), offsetof(SvgRectNode, h)}, +}; + + +/* parse the attributes for a image element. + * https://www.w3.org/TR/SVG/embedded.html#ImageElement + */ +static bool _attrParseImageNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgImageNode* image = &(node->node.image); + unsigned char* array; + int sz = strlen(key); + + array = (unsigned char*)image; + for (unsigned int i = 0; i < sizeof(imageTags) / sizeof(imageTags[0]); i++) { + if (imageTags[i].sz - 1 == sz && !strncmp(imageTags[i].tag, key, sz)) { + *((float*)(array + imageTags[i].offset)) = _toFloat(loader->svgParse, value, imageTags[i].type); + return true; + } + } + + if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) { + image->href = _idFromHref(value); + } else if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); + } else if (!strcmp(key, "style")) { + return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else { + return _parseStyleAttr(loader, key, value); + } + return true; +} + + +static SvgNode* _createImageNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Image); + + if (!loader->svgParse->node) return nullptr; + + simpleXmlParseAttributes(buf, bufLength, _attrParseImageNode, loader); + return loader->svgParse->node; +} + + +static SvgNode* _getDefsNode(SvgNode* node) +{ + if (!node) return nullptr; + + while (node->parent != nullptr) { + node = node->parent; + } + + if (node->type == SvgNodeType::Doc) return node->node.doc.defs; + + return nullptr; +} + + +static SvgNode* _findChildById(const SvgNode* node, const char* id) +{ + if (!node) return nullptr; + + auto child = node->child.data; + for (uint32_t i = 0; i < node->child.count; ++i, ++child) { + if (((*child)->id) && !strcmp((*child)->id, id)) return (*child); + } + return nullptr; +} + +static SvgNode* _findNodeById(SvgNode *node, const char* id) +{ + SvgNode* result = nullptr; + if (node->id && !strcmp(node->id, id)) return node; + + if (node->child.count > 0) { + auto child = node->child.data; + for (uint32_t i = 0; i < node->child.count; ++i, ++child) { + result = _findNodeById(*child, id); + if (result) break; + } + } + return result; +} + +static void _cloneGradStops(Array<Fill::ColorStop>& dst, const Array<Fill::ColorStop>& src) +{ + for (uint32_t i = 0; i < src.count; ++i) { + dst.push(src.data[i]); + } +} + + +static SvgStyleGradient* _cloneGradient(SvgStyleGradient* from) +{ + if (!from) return nullptr; + + auto grad = (SvgStyleGradient*)(calloc(1, sizeof(SvgStyleGradient))); + if (!grad) return nullptr; + + grad->type = from->type; + grad->id = from->id ? _copyId(from->id) : nullptr; + grad->ref = from->ref ? _copyId(from->ref) : nullptr; + grad->spread = from->spread; + grad->userSpace = from->userSpace; + + if (from->transform) { + grad->transform = (Matrix*)calloc(1, sizeof(Matrix)); + if (grad->transform) memcpy(grad->transform, from->transform, sizeof(Matrix)); + } + + if (grad->type == SvgGradientType::Linear) { + grad->linear = (SvgLinearGradient*)calloc(1, sizeof(SvgLinearGradient)); + if (!grad->linear) goto error_grad_alloc; + memcpy(grad->linear, from->linear, sizeof(SvgLinearGradient)); + } else if (grad->type == SvgGradientType::Radial) { + grad->radial = (SvgRadialGradient*)calloc(1, sizeof(SvgRadialGradient)); + if (!grad->radial) goto error_grad_alloc; + memcpy(grad->radial, from->radial, sizeof(SvgRadialGradient)); + } + + _cloneGradStops(grad->stops, from->stops); + + return grad; + +error_grad_alloc: + if (grad) { + grad->clear(); + free(grad); + } + return nullptr; +} + + +static void _copyAttr(SvgNode* to, const SvgNode* from) +{ + //Copy matrix attribute + if (from->transform) { + to->transform = (Matrix*)malloc(sizeof(Matrix)); + if (to->transform) *to->transform = *from->transform; + } + //Copy style attribute + *to->style = *from->style; + if (from->style->fill.paint.url) to->style->fill.paint.url = strdup(from->style->fill.paint.url); + if (from->style->stroke.paint.url) to->style->stroke.paint.url = strdup(from->style->stroke.paint.url); + if (from->style->clipPath.url) to->style->clipPath.url = strdup(from->style->clipPath.url); + if (from->style->mask.url) to->style->mask.url = strdup(from->style->mask.url); + + //Copy node attribute + switch (from->type) { + case SvgNodeType::Circle: { + to->node.circle.cx = from->node.circle.cx; + to->node.circle.cy = from->node.circle.cy; + to->node.circle.r = from->node.circle.r; + break; + } + case SvgNodeType::Ellipse: { + to->node.ellipse.cx = from->node.ellipse.cx; + to->node.ellipse.cy = from->node.ellipse.cy; + to->node.ellipse.rx = from->node.ellipse.rx; + to->node.ellipse.ry = from->node.ellipse.ry; + break; + } + case SvgNodeType::Rect: { + to->node.rect.x = from->node.rect.x; + to->node.rect.y = from->node.rect.y; + to->node.rect.w = from->node.rect.w; + to->node.rect.h = from->node.rect.h; + to->node.rect.rx = from->node.rect.rx; + to->node.rect.ry = from->node.rect.ry; + to->node.rect.hasRx = from->node.rect.hasRx; + to->node.rect.hasRy = from->node.rect.hasRy; + break; + } + case SvgNodeType::Line: { + to->node.line.x1 = from->node.line.x1; + to->node.line.y1 = from->node.line.y1; + to->node.line.x2 = from->node.line.x2; + to->node.line.y2 = from->node.line.y2; + break; + } + case SvgNodeType::Path: { + if (from->node.path.path) to->node.path.path = strdup(from->node.path.path); + break; + } + case SvgNodeType::Polygon: { + to->node.polygon.pointsCount = from->node.polygon.pointsCount; + to->node.polygon.points = (float*)malloc(to->node.polygon.pointsCount * sizeof(float)); + memcpy(to->node.polygon.points, from->node.polygon.points, to->node.polygon.pointsCount * sizeof(float)); + break; + } + case SvgNodeType::Polyline: { + to->node.polyline.pointsCount = from->node.polyline.pointsCount; + to->node.polyline.points = (float*)malloc(to->node.polyline.pointsCount * sizeof(float)); + memcpy(to->node.polyline.points, from->node.polyline.points, to->node.polyline.pointsCount * sizeof(float)); + break; + } + case SvgNodeType::Image: { + to->node.image.x = from->node.image.x; + to->node.image.y = from->node.image.y; + to->node.image.w = from->node.image.w; + to->node.image.h = from->node.image.h; + if (from->node.image.href) to->node.image.href = strdup(from->node.image.href); + break; + } + default: { + break; + } + } +} + + +static void _cloneNode(SvgNode* from, SvgNode* parent) +{ + SvgNode* newNode; + if (!from || !parent) return; + + newNode = _createNode(parent, from->type); + + if (!newNode) return; + + _copyAttr(newNode, from); + + auto child = from->child.data; + for (uint32_t i = 0; i < from->child.count; ++i, ++child) { + _cloneNode(*child, newNode); + } +} + + +static void _postponeCloneNode(SvgLoaderData* loader, SvgNode *node, char* id) { + loader->cloneNodes.push({node, id}); +} + + +static void _clonePostponedNodes(Array<SvgNodeIdPair>* cloneNodes) { + for (uint32_t i = 0; i < cloneNodes->count; ++i) { + auto nodeIdPair = cloneNodes->data[i]; + auto defs = _getDefsNode(nodeIdPair.node); + auto nodeFrom = _findChildById(defs, nodeIdPair.id); + _cloneNode(nodeFrom, nodeIdPair.node); + free(nodeIdPair.id); + } +} + + +static constexpr struct +{ + const char* tag; + SvgParserLengthType type; + int sz; + size_t offset; +} useTags[] = { + {"x", SvgParserLengthType::Horizontal, sizeof("x"), offsetof(SvgRectNode, x)}, + {"y", SvgParserLengthType::Vertical, sizeof("y"), offsetof(SvgRectNode, y)}, + {"width", SvgParserLengthType::Horizontal, sizeof("width"), offsetof(SvgRectNode, w)}, + {"height", SvgParserLengthType::Vertical, sizeof("height"), offsetof(SvgRectNode, h)} +}; + + +static bool _attrParseUseNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode *defs, *nodeFrom, *node = loader->svgParse->node; + char* id; + + SvgUseNode* use = &(node->node.use); + int sz = strlen(key); + unsigned char* array = (unsigned char*)use; + for (unsigned int i = 0; i < sizeof(useTags) / sizeof(useTags[0]); i++) { + if (useTags[i].sz - 1 == sz && !strncmp(useTags[i].tag, key, sz)) { + *((float*)(array + useTags[i].offset)) = _toFloat(loader->svgParse, value, useTags[i].type); + return true; + } + } + + if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) { + id = _idFromHref(value); + defs = _getDefsNode(node); + nodeFrom = _findChildById(defs, id); + if (nodeFrom) { + _cloneNode(nodeFrom, node); + free(id); + } else { + //some svg export software include <defs> element at the end of the file + //if so the 'from' element won't be found now and we have to repeat finding + //after the whole file is parsed + _postponeCloneNode(loader, node, id); + } + } else if (!strcmp(key, "clip-path")) { + _handleClipPathAttr(loader, node, value); + } else if (!strcmp(key, "mask")) { + _handleMaskAttr(loader, node, value); + } else { + return _attrParseGNode(data, key, value); + } + return true; +} + + +static SvgNode* _createUseNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Use); + + if (!loader->svgParse->node) return nullptr; + + simpleXmlParseAttributes(buf, bufLength, _attrParseUseNode, loader); + return loader->svgParse->node; +} + +//TODO: Implement 'text' primitive +static constexpr struct +{ + const char* tag; + int sz; + FactoryMethod tagHandler; +} graphicsTags[] = { + {"use", sizeof("use"), _createUseNode}, + {"circle", sizeof("circle"), _createCircleNode}, + {"ellipse", sizeof("ellipse"), _createEllipseNode}, + {"path", sizeof("path"), _createPathNode}, + {"polygon", sizeof("polygon"), _createPolygonNode}, + {"rect", sizeof("rect"), _createRectNode}, + {"polyline", sizeof("polyline"), _createPolylineNode}, + {"line", sizeof("line"), _createLineNode}, + {"image", sizeof("image"), _createImageNode} +}; + + +static constexpr struct +{ + const char* tag; + int sz; + FactoryMethod tagHandler; +} groupTags[] = { + {"defs", sizeof("defs"), _createDefsNode}, + {"g", sizeof("g"), _createGNode}, + {"svg", sizeof("svg"), _createSvgNode}, + {"mask", sizeof("mask"), _createMaskNode}, + {"clipPath", sizeof("clipPath"), _createClipPathNode} +}; + + +#define FIND_FACTORY(Short_Name, Tags_Array) \ + static FactoryMethod \ + _find##Short_Name##Factory(const char* name) \ + { \ + unsigned int i; \ + int sz = strlen(name); \ + \ + for (i = 0; i < sizeof(Tags_Array) / sizeof(Tags_Array[0]); i++) { \ + if (Tags_Array[i].sz - 1 == sz && !strncmp(Tags_Array[i].tag, name, sz)) { \ + return Tags_Array[i].tagHandler; \ + } \ + } \ + return nullptr; \ + } + +FIND_FACTORY(Group, groupTags) +FIND_FACTORY(Graphics, graphicsTags) + + +FillSpread _parseSpreadValue(const char* value) +{ + auto spread = FillSpread::Pad; + + if (!strcmp(value, "reflect")) { + spread = FillSpread::Reflect; + } else if (!strcmp(value, "repeat")) { + spread = FillSpread::Repeat; + } + + return spread; +} + + +static void _handleRadialCxAttr(SvgLoaderData* loader, SvgRadialGradient* radial, const char* value) +{ + radial->cx = _gradientToFloat(loader->svgParse, value, radial->isCxPercentage); + if (!loader->svgParse->gradient.parsedFx) { + radial->fx = radial->cx; + radial->isFxPercentage = radial->isCxPercentage; + } +} + + +static void _handleRadialCyAttr(SvgLoaderData* loader, SvgRadialGradient* radial, const char* value) +{ + radial->cy = _gradientToFloat(loader->svgParse, value, radial->isCyPercentage); + if (!loader->svgParse->gradient.parsedFy) { + radial->fy = radial->cy; + radial->isFyPercentage = radial->isCyPercentage; + } +} + + +static void _handleRadialFxAttr(SvgLoaderData* loader, SvgRadialGradient* radial, const char* value) +{ + radial->fx = _gradientToFloat(loader->svgParse, value, radial->isFxPercentage); + loader->svgParse->gradient.parsedFx = true; +} + + +static void _handleRadialFyAttr(SvgLoaderData* loader, SvgRadialGradient* radial, const char* value) +{ + radial->fy = _gradientToFloat(loader->svgParse, value, radial->isFyPercentage); + loader->svgParse->gradient.parsedFy = true; +} + + +static void _handleRadialRAttr(SvgLoaderData* loader, SvgRadialGradient* radial, const char* value) +{ + radial->r = _gradientToFloat(loader->svgParse, value, radial->isRPercentage); +} + + +static void _recalcRadialCxAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + if (userSpace && !radial->isCxPercentage) radial->cx = radial->cx / loader->svgParse->global.w; +} + + +static void _recalcRadialCyAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + if (userSpace && !radial->isCyPercentage) radial->cy = radial->cy / loader->svgParse->global.h; +} + + +static void _recalcRadialFxAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + if (userSpace && !radial->isFxPercentage) radial->fx = radial->fx / loader->svgParse->global.w; +} + + +static void _recalcRadialFyAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + if (userSpace && !radial->isFyPercentage) radial->fy = radial->fy / loader->svgParse->global.h; +} + + +static void _recalcRadialRAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) +{ + // scaling factor based on the Units paragraph from : https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html + if (userSpace && !radial->isRPercentage) radial->r = radial->r / (sqrtf(pow(loader->svgParse->global.h, 2) + pow(loader->svgParse->global.w, 2)) / sqrtf(2.0)); +} + + +typedef void (*radialMethod)(SvgLoaderData* loader, SvgRadialGradient* radial, const char* value); +typedef void (*radialMethodRecalc)(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace); + + +#define RADIAL_DEF(Name, Name1) \ + { \ +#Name, sizeof(#Name), _handleRadial##Name1##Attr, _recalcRadial##Name1##Attr \ + } + + +static constexpr struct +{ + const char* tag; + int sz; + radialMethod tagHandler; + radialMethodRecalc tagRecalc; +} radialTags[] = { + RADIAL_DEF(cx, Cx), + RADIAL_DEF(cy, Cy), + RADIAL_DEF(fx, Fx), + RADIAL_DEF(fy, Fy), + RADIAL_DEF(r, R) +}; + + +static bool _attrParseRadialGradientNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgStyleGradient* grad = loader->svgParse->styleGrad; + SvgRadialGradient* radial = grad->radial; + int sz = strlen(key); + + for (unsigned int i = 0; i < sizeof(radialTags) / sizeof(radialTags[0]); i++) { + if (radialTags[i].sz - 1 == sz && !strncmp(radialTags[i].tag, key, sz)) { + radialTags[i].tagHandler(loader, radial, value); + return true; + } + } + + if (!strcmp(key, "id")) { + grad->id = _copyId(value); + } else if (!strcmp(key, "spreadMethod")) { + grad->spread = _parseSpreadValue(value); + } else if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) { + grad->ref = _idFromHref(value); + } else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse")) { + grad->userSpace = true; + } else if (!strcmp(key, "gradientTransform")) { + grad->transform = _parseTransformationMatrix(value); + } else { + return false; + } + + return true; +} + + +static SvgStyleGradient* _createRadialGradient(SvgLoaderData* loader, const char* buf, unsigned bufLength) +{ + auto grad = (SvgStyleGradient*)(calloc(1, sizeof(SvgStyleGradient))); + loader->svgParse->styleGrad = grad; + + grad->type = SvgGradientType::Radial; + grad->userSpace = false; + grad->radial = (SvgRadialGradient*)calloc(1, sizeof(SvgRadialGradient)); + if (!grad->radial) { + grad->clear(); + free(grad); + return nullptr; + } + /** + * Default values of gradient transformed into global percentage + */ + grad->radial->cx = 0.5f; + grad->radial->cy = 0.5f; + grad->radial->fx = 0.5f; + grad->radial->fy = 0.5f; + grad->radial->r = 0.5f; + grad->radial->isCxPercentage = true; + grad->radial->isCyPercentage = true; + grad->radial->isFxPercentage = true; + grad->radial->isFyPercentage = true; + grad->radial->isRPercentage = true; + + loader->svgParse->gradient.parsedFx = false; + loader->svgParse->gradient.parsedFy = false; + simpleXmlParseAttributes(buf, bufLength, + _attrParseRadialGradientNode, loader); + + for (unsigned int i = 0; i < sizeof(radialTags) / sizeof(radialTags[0]); i++) { + radialTags[i].tagRecalc(loader, grad->radial, grad->userSpace); + } + + return loader->svgParse->styleGrad; +} + + +static bool _attrParseStopsStyle(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + auto stop = &loader->svgParse->gradStop; + + if (!strcmp(key, "stop-opacity")) { + stop->a = _toOpacity(value); + loader->svgParse->flags = (SvgStopStyleFlags)((int)loader->svgParse->flags | (int)SvgStopStyleFlags::StopOpacity); + } else if (!strcmp(key, "stop-color")) { + _toColor(value, &stop->r, &stop->g, &stop->b, nullptr); + loader->svgParse->flags = (SvgStopStyleFlags)((int)loader->svgParse->flags | (int)SvgStopStyleFlags::StopColor); + } else { + return false; + } + + return true; +} + + +static bool _attrParseStops(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + auto stop = &loader->svgParse->gradStop; + + if (!strcmp(key, "offset")) { + stop->offset = _toOffset(value); + } else if (!strcmp(key, "stop-opacity")) { + if (!((int)loader->svgParse->flags & (int)SvgStopStyleFlags::StopOpacity)) { + stop->a = _toOpacity(value); + } + } else if (!strcmp(key, "stop-color")) { + if (!((int)loader->svgParse->flags & (int)SvgStopStyleFlags::StopColor)) { + _toColor(value, &stop->r, &stop->g, &stop->b, nullptr); + } + } else if (!strcmp(key, "style")) { + simpleXmlParseW3CAttribute(value, _attrParseStopsStyle, data); + } else { + return false; + } + + return true; +} + + +static void _handleLinearX1Attr(SvgLoaderData* loader, SvgLinearGradient* linear, const char* value) +{ + linear->x1 = _gradientToFloat(loader->svgParse, value, linear->isX1Percentage); +} + + +static void _handleLinearY1Attr(SvgLoaderData* loader, SvgLinearGradient* linear, const char* value) +{ + linear->y1 = _gradientToFloat(loader->svgParse, value, linear->isY1Percentage); +} + + +static void _handleLinearX2Attr(SvgLoaderData* loader, SvgLinearGradient* linear, const char* value) +{ + linear->x2 = _gradientToFloat(loader->svgParse, value, linear->isX2Percentage); +} + + +static void _handleLinearY2Attr(SvgLoaderData* loader, SvgLinearGradient* linear, const char* value) +{ + linear->y2 = _gradientToFloat(loader->svgParse, value, linear->isY2Percentage); +} + + +static void _recalcLinearX1Attr(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace) +{ + if (userSpace && !linear->isX1Percentage) linear->x1 = linear->x1 / loader->svgParse->global.w; +} + + +static void _recalcLinearY1Attr(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace) +{ + if (userSpace && !linear->isY1Percentage) linear->y1 = linear->y1 / loader->svgParse->global.h; +} + + +static void _recalcLinearX2Attr(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace) +{ + if (userSpace && !linear->isX2Percentage) linear->x2 = linear->x2 / loader->svgParse->global.w; +} + + +static void _recalcLinearY2Attr(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace) +{ + if (userSpace && !linear->isY2Percentage) linear->y2 = linear->y2 / loader->svgParse->global.h; +} + + +typedef void (*Linear_Method)(SvgLoaderData* loader, SvgLinearGradient* linear, const char* value); +typedef void (*Linear_Method_Recalc)(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace); + + +#define LINEAR_DEF(Name, Name1) \ + { \ +#Name, sizeof(#Name), _handleLinear##Name1##Attr, _recalcLinear##Name1##Attr \ + } + + +static constexpr struct +{ + const char* tag; + int sz; + Linear_Method tagHandler; + Linear_Method_Recalc tagRecalc; +} linear_tags[] = { + LINEAR_DEF(x1, X1), + LINEAR_DEF(y1, Y1), + LINEAR_DEF(x2, X2), + LINEAR_DEF(y2, Y2) +}; + + +static bool _attrParseLinearGradientNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgStyleGradient* grad = loader->svgParse->styleGrad; + SvgLinearGradient* linear = grad->linear; + int sz = strlen(key); + + for (unsigned int i = 0; i < sizeof(linear_tags) / sizeof(linear_tags[0]); i++) { + if (linear_tags[i].sz - 1 == sz && !strncmp(linear_tags[i].tag, key, sz)) { + linear_tags[i].tagHandler(loader, linear, value); + return true; + } + } + + if (!strcmp(key, "id")) { + grad->id = _copyId(value); + } else if (!strcmp(key, "spreadMethod")) { + grad->spread = _parseSpreadValue(value); + } else if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) { + grad->ref = _idFromHref(value); + } else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse")) { + grad->userSpace = true; + } else if (!strcmp(key, "gradientTransform")) { + grad->transform = _parseTransformationMatrix(value); + } else { + return false; + } + + return true; +} + + +static SvgStyleGradient* _createLinearGradient(SvgLoaderData* loader, const char* buf, unsigned bufLength) +{ + auto grad = (SvgStyleGradient*)(calloc(1, sizeof(SvgStyleGradient))); + loader->svgParse->styleGrad = grad; + + grad->type = SvgGradientType::Linear; + grad->userSpace = false; + grad->linear = (SvgLinearGradient*)calloc(1, sizeof(SvgLinearGradient)); + if (!grad->linear) { + grad->clear(); + free(grad); + return nullptr; + } + /** + * Default value of x2 is 100% - transformed to the global percentage + */ + grad->linear->x2 = 1.0f; + grad->linear->isX2Percentage = true; + + simpleXmlParseAttributes(buf, bufLength, _attrParseLinearGradientNode, loader); + + for (unsigned int i = 0; i < sizeof(linear_tags) / sizeof(linear_tags[0]); i++) { + linear_tags[i].tagRecalc(loader, grad->linear, grad->userSpace); + } + + return loader->svgParse->styleGrad; +} + + +#define GRADIENT_DEF(Name, Name1) \ + { \ +#Name, sizeof(#Name), _create##Name1 \ + } + + +/** + * In the case when the gradients lengths are given as numbers (not percentages) + * in the current user coordinate system, they are recalculated into percentages + * related to the canvas width and height. + */ +static constexpr struct +{ + const char* tag; + int sz; + GradientFactoryMethod tagHandler; +} gradientTags[] = { + GRADIENT_DEF(linearGradient, LinearGradient), + GRADIENT_DEF(radialGradient, RadialGradient) +}; + + +static GradientFactoryMethod _findGradientFactory(const char* name) +{ + int sz = strlen(name); + + for (unsigned int i = 0; i < sizeof(gradientTags) / sizeof(gradientTags[0]); i++) { + if (gradientTags[i].sz - 1 == sz && !strncmp(gradientTags[i].tag, name, sz)) { + return gradientTags[i].tagHandler; + } + } + return nullptr; +} + + +static constexpr struct +{ + const char* tag; + size_t sz; +} popArray[] = { + {"g", sizeof("g")}, + {"svg", sizeof("svg")}, + {"defs", sizeof("defs")}, + {"mask", sizeof("mask")}, + {"clipPath", sizeof("clipPath")} +}; + + +static void _svgLoaderParerXmlClose(SvgLoaderData* loader, const char* content) +{ + content = _skipSpace(content, nullptr); + + for (unsigned int i = 0; i < sizeof(popArray) / sizeof(popArray[0]); i++) { + if (!strncmp(content, popArray[i].tag, popArray[i].sz - 1)) { + loader->stack.pop(); + break; + } + } + + loader->level--; +} + + +static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content, unsigned int length, bool empty) +{ + const char* attrs = nullptr; + int attrsLength = 0; + int sz = length; + char tagName[20] = ""; + FactoryMethod method; + GradientFactoryMethod gradientMethod; + SvgNode *node = nullptr, *parent = nullptr; + loader->level++; + attrs = simpleXmlFindAttributesTag(content, length); + + if (!attrs) { + //Parse the empty tag + attrs = content; + while ((attrs != nullptr) && *attrs != '>') attrs++; + } + + if (attrs) { + //Find out the tag name starting from content till sz length + sz = attrs - content; + while ((sz > 0) && (isspace(content[sz - 1]))) sz--; + if ((unsigned)sz >= sizeof(tagName)) return; + strncpy(tagName, content, sz); + tagName[sz] = '\0'; + attrsLength = length - sz; + } + + if ((method = _findGroupFactory(tagName))) { + //Group + if (!loader->doc) { + if (strcmp(tagName, "svg")) return; //Not a valid svg document + node = method(loader, nullptr, attrs, attrsLength); + loader->doc = node; + } else { + if (!strcmp(tagName, "svg")) return; //Already loaded <svg>(SvgNodeType::Doc) tag + if (loader->stack.count > 0) parent = loader->stack.data[loader->stack.count - 1]; + else parent = loader->doc; + node = method(loader, parent, attrs, attrsLength); + } + + if (!node) return; + if (node->type != SvgNodeType::Defs || !empty) { + loader->stack.push(node); + } + } else if ((method = _findGraphicsFactory(tagName))) { + if (loader->stack.count > 0) parent = loader->stack.data[loader->stack.count - 1]; + else parent = loader->doc; + node = method(loader, parent, attrs, attrsLength); + } else if ((gradientMethod = _findGradientFactory(tagName))) { + SvgStyleGradient* gradient; + gradient = gradientMethod(loader, attrs, attrsLength); + //FIXME: The current parsing structure does not distinguish end tags. + // There is no way to know if the currently parsed gradient is in defs. + // If a gradient is declared outside of defs after defs is set, it is included in the gradients of defs. + // But finally, the loader has a gradient style list regardless of defs. + // This is only to support this when multiple gradients are declared, even if no defs are declared. + // refer to: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs + if (loader->def && loader->doc->node.doc.defs) { + loader->def->node.defs.gradients.push(gradient); + } else { + loader->gradients.push(gradient); + } + loader->latestGradient = gradient; + } else if (!strcmp(tagName, "stop")) { + if (!loader->latestGradient) { + TVGLOG("SVG", "Stop element is used outside of the Gradient element"); + return; + } + /* default value for opacity */ + loader->svgParse->gradStop = {0.0f, 0, 0, 0, 255}; + simpleXmlParseAttributes(attrs, attrsLength, _attrParseStops, loader); + loader->latestGradient->stops.push(loader->svgParse->gradStop); + } else if (!isIgnoreUnsupportedLogElements(tagName)) { + TVGLOG("SVG", "Unsupported elements used [Elements: %s]", tagName); + } +} + + +static bool _svgLoaderParser(void* data, SimpleXMLType type, const char* content, unsigned int length) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + + switch (type) { + case SimpleXMLType::Open: { + _svgLoaderParserXmlOpen(loader, content, length, false); + break; + } + case SimpleXMLType::OpenEmpty: { + _svgLoaderParserXmlOpen(loader, content, length, true); + break; + } + case SimpleXMLType::Close: { + _svgLoaderParerXmlClose(loader, content); + break; + } + case SimpleXMLType::Data: + case SimpleXMLType::CData: + case SimpleXMLType::DoctypeChild: { + break; + } + case SimpleXMLType::Ignored: + case SimpleXMLType::Comment: + case SimpleXMLType::Doctype: { + break; + } + default: { + break; + } + } + + return true; +} + + +static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* parent) +{ + if (parent == nullptr) return; + //Inherit the property of parent if not present in child. + //Fill + if (!((int)child->fill.flags & (int)SvgFillFlags::Paint)) { + child->fill.paint.color = parent->fill.paint.color; + child->fill.paint.none = parent->fill.paint.none; + child->fill.paint.curColor = parent->fill.paint.curColor; + if (parent->fill.paint.url) child->fill.paint.url = _copyId(parent->fill.paint.url); + } else if (child->fill.paint.curColor && !child->curColorSet) { + child->color = parent->color; + } + if (!((int)child->fill.flags & (int)SvgFillFlags::Opacity)) { + child->fill.opacity = parent->fill.opacity; + } + if (!((int)child->fill.flags & (int)SvgFillFlags::FillRule)) { + child->fill.fillRule = parent->fill.fillRule; + } + //Stroke + if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Paint)) { + child->stroke.paint.color = parent->stroke.paint.color; + child->stroke.paint.none = parent->stroke.paint.none; + child->stroke.paint.curColor = parent->stroke.paint.curColor; + child->stroke.paint.url = parent->stroke.paint.url ? _copyId(parent->stroke.paint.url) : nullptr; + } else if (child->stroke.paint.curColor && !child->curColorSet) { + child->color = parent->color; + } + if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Opacity)) { + child->stroke.opacity = parent->stroke.opacity; + } + if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Width)) { + child->stroke.width = parent->stroke.width; + } + if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Dash)) { + if (parent->stroke.dash.array.count > 0) { + child->stroke.dash.array.clear(); + child->stroke.dash.array.reserve(parent->stroke.dash.array.count); + for (uint32_t i = 0; i < parent->stroke.dash.array.count; ++i) { + child->stroke.dash.array.push(parent->stroke.dash.array.data[i]); + } + } + } + if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Cap)) { + child->stroke.cap = parent->stroke.cap; + } + if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Join)) { + child->stroke.join = parent->stroke.join; + } +} + + +static void _inefficientNodeCheck(TVG_UNUSED SvgNode* node){ +#ifdef THORVG_LOG_ENABLED + auto type = simpleXmlNodeTypeToString(node->type); + + if (!node->display && node->type != SvgNodeType::ClipPath) TVGLOG("SVG", "Inefficient elements used [Display is none][Node Type : %s]", type); + if (node->style->opacity == 0) TVGLOG("SVG", "Inefficient elements used [Opacity is zero][Node Type : %s]", type); + if (node->style->fill.opacity == 0 && node->style->stroke.opacity == 0) TVGLOG("SVG", "Inefficient elements used [Fill opacity and stroke opacity are zero][Node Type : %s]", type); + + switch (node->type) { + case SvgNodeType::Path: { + if (!node->node.path.path) TVGLOG("SVG", "Inefficient elements used [Empty path][Node Type : %s]", type); + break; + } + case SvgNodeType::Ellipse: { + if (node->node.ellipse.rx == 0 && node->node.ellipse.ry == 0) TVGLOG("SVG", "Inefficient elements used [Size is zero][Node Type : %s]", type); + break; + } + case SvgNodeType::Polygon: + case SvgNodeType::Polyline: { + if (node->node.polygon.pointsCount < 2) TVGLOG("SVG", "Inefficient elements used [Invalid Polygon][Node Type : %s]", type); + break; + } + case SvgNodeType::Circle: { + if (node->node.circle.r == 0) TVGLOG("SVG", "Inefficient elements used [Size is zero][Node Type : %s]", type); + break; + } + case SvgNodeType::Rect: { + if (node->node.rect.w == 0 && node->node.rect.h) TVGLOG("SVG", "Inefficient elements used [Size is zero][Node Type : %s]", type); + break; + } + case SvgNodeType::Line: { + if (node->node.line.x1 == node->node.line.x2 && node->node.line.y1 == node->node.line.y2) TVGLOG("SVG", "Inefficient elements used [Size is zero][Node Type : %s]", type); + break; + } + default: break; + } +#endif +} + + +static void _updateStyle(SvgNode* node, SvgStyleProperty* parentStyle) +{ + _styleInherit(node->style, parentStyle); + _inefficientNodeCheck(node); + + auto child = node->child.data; + for (uint32_t i = 0; i < node->child.count; ++i, ++child) { + _updateStyle(*child, node->style); + } +} + + +static SvgStyleGradient* _gradientDup(Array<SvgStyleGradient*>* gradients, const char* id) +{ + SvgStyleGradient* result = nullptr; + + auto gradList = gradients->data; + + for (uint32_t i = 0; i < gradients->count; ++i) { + if (!strcmp((*gradList)->id, id)) { + result = _cloneGradient(*gradList); + break; + } + ++gradList; + } + + if (result && result->ref) { + gradList = gradients->data; + for (uint32_t i = 0; i < gradients->count; ++i) { + if (!strcmp((*gradList)->id, result->ref)) { + if (result->stops.count == 0) _cloneGradStops(result->stops, (*gradList)->stops); + //TODO: Properly inherit other property + break; + } + ++gradList; + } + } + + return result; +} + + +static void _updateGradient(SvgNode* node, Array<SvgStyleGradient*>* gradients) +{ + if (node->child.count > 0) { + auto child = node->child.data; + for (uint32_t i = 0; i < node->child.count; ++i, ++child) { + _updateGradient(*child, gradients); + } + } else { + if (node->style->fill.paint.url) { + if (node->style->fill.paint.gradient) { + node->style->fill.paint.gradient->clear(); + free(node->style->fill.paint.gradient); + } + node->style->fill.paint.gradient = _gradientDup(gradients, node->style->fill.paint.url); + } + if (node->style->stroke.paint.url) { + if (node->style->stroke.paint.gradient) { + node->style->stroke.paint.gradient->clear(); + free(node->style->stroke.paint.gradient); + } + node->style->stroke.paint.gradient = _gradientDup(gradients, node->style->stroke.paint.url); + } + } +} + + +static void _updateComposite(SvgNode* node, SvgNode* root) +{ + if (node->style->clipPath.url && !node->style->clipPath.node) { + SvgNode* findResult = _findNodeById(root, node->style->clipPath.url); + if (findResult) node->style->clipPath.node = findResult; + } + if (node->style->mask.url && !node->style->mask.node) { + SvgNode* findResult = _findNodeById(root, node->style->mask.url); + if (findResult) node->style->mask.node = findResult; + } + if (node->child.count > 0) { + auto child = node->child.data; + for (uint32_t i = 0; i < node->child.count; ++i, ++child) { + _updateComposite(*child, root); + } + } +} + + +static void _freeNodeStyle(SvgStyleProperty* style) +{ + if (!style) return; + + //style->clipPath.node and style->mask.node has only the addresses of node. Therefore, node is released from _freeNode. + free(style->clipPath.url); + free(style->mask.url); + + if (style->fill.paint.gradient) { + style->fill.paint.gradient->clear(); + free(style->fill.paint.gradient); + } + if (style->stroke.paint.gradient) { + style->stroke.paint.gradient->clear(); + free(style->stroke.paint.gradient); + } + free(style->fill.paint.url); + free(style->stroke.paint.url); + style->stroke.dash.array.reset(); + free(style); +} + + +static void _freeNode(SvgNode* node) +{ + if (!node) return; + + auto child = node->child.data; + for (uint32_t i = 0; i < node->child.count; ++i, ++child) { + _freeNode(*child); + } + node->child.reset(); + + free(node->id); + free(node->transform); + _freeNodeStyle(node->style); + switch (node->type) { + case SvgNodeType::Path: { + free(node->node.path.path); + break; + } + case SvgNodeType::Polygon: { + free(node->node.polygon.points); + break; + } + case SvgNodeType::Polyline: { + free(node->node.polyline.points); + break; + } + case SvgNodeType::Doc: { + _freeNode(node->node.doc.defs); + break; + } + case SvgNodeType::Defs: { + auto gradients = node->node.defs.gradients.data; + for (size_t i = 0; i < node->node.defs.gradients.count; ++i) { + (*gradients)->clear(); + free(*gradients); + ++gradients; + } + node->node.defs.gradients.reset(); + break; + } + case SvgNodeType::Image: { + free(node->node.image.href); + break; + } + default: { + break; + } + } + free(node); +} + + +static bool _svgLoaderParserForValidCheckXmlOpen(SvgLoaderData* loader, const char* content, unsigned int length) +{ + const char* attrs = nullptr; + int sz = length; + char tagName[20] = ""; + FactoryMethod method; + SvgNode *node = nullptr; + int attrsLength = 0; + loader->level++; + attrs = simpleXmlFindAttributesTag(content, length); + + if (!attrs) { + //Parse the empty tag + attrs = content; + while ((attrs != nullptr) && *attrs != '>') attrs++; + } + + if (attrs) { + sz = attrs - content; + while ((sz > 0) && (isspace(content[sz - 1]))) sz--; + if ((unsigned)sz >= sizeof(tagName)) return false; + strncpy(tagName, content, sz); + tagName[sz] = '\0'; + attrsLength = length - sz; + } + + if ((method = _findGroupFactory(tagName))) { + if (!loader->doc) { + if (strcmp(tagName, "svg")) return true; //Not a valid svg document + node = method(loader, nullptr, attrs, attrsLength); + loader->doc = node; + loader->stack.push(node); + return false; + } + } + return true; +} + + +static bool _svgLoaderParserForValidCheck(void* data, SimpleXMLType type, const char* content, unsigned int length) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + bool res = true;; + + switch (type) { + case SimpleXMLType::Open: + case SimpleXMLType::OpenEmpty: { + //If 'res' is false, it means <svg> tag is found. + res = _svgLoaderParserForValidCheckXmlOpen(loader, content, length); + break; + } + default: { + break; + } + } + + return res; +} + + +void SvgLoader::clear() +{ + if (copy) free((char*)content); + size = 0; + content = nullptr; + copy = false; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +SvgLoader::SvgLoader() +{ +} + + +SvgLoader::~SvgLoader() +{ + close(); +} + + +void SvgLoader::run(unsigned tid) +{ + if (!simpleXmlParse(content, size, true, _svgLoaderParser, &(loaderData))) return; + + if (loaderData.doc) { + _updateStyle(loaderData.doc, nullptr); + auto defs = loaderData.doc->node.doc.defs; + if (defs) _updateGradient(loaderData.doc, &defs->node.defs.gradients); + + if (loaderData.gradients.count > 0) _updateGradient(loaderData.doc, &loaderData.gradients); + + _updateComposite(loaderData.doc, loaderData.doc); + if (defs) _updateComposite(loaderData.doc, defs); + + if (loaderData.cloneNodes.count > 0) _clonePostponedNodes(&loaderData.cloneNodes); + } + root = svgSceneBuild(loaderData.doc, vx, vy, vw, vh, w, h, preserveAspect, svgPath); +} + + +bool SvgLoader::header() +{ + //For valid check, only <svg> tag is parsed first. + //If the <svg> tag is found, the loaded file is valid and stores viewbox information. + //After that, the remaining content data is parsed in order with async. + loaderData.svgParse = (SvgParser*)malloc(sizeof(SvgParser)); + if (!loaderData.svgParse) return false; + + loaderData.svgParse->flags = SvgStopStyleFlags::StopDefault; + + simpleXmlParse(content, size, true, _svgLoaderParserForValidCheck, &(loaderData)); + + if (loaderData.doc && loaderData.doc->type == SvgNodeType::Doc) { + //Return the brief resource info such as viewbox: + vx = loaderData.doc->node.doc.vx; + vy = loaderData.doc->node.doc.vy; + w = vw = loaderData.doc->node.doc.vw; + h = vh = loaderData.doc->node.doc.vh; + + //Override size + if (loaderData.doc->node.doc.w > 0) { + w = loaderData.doc->node.doc.w; + if (vw < FLT_EPSILON) vw = w; + } + if (loaderData.doc->node.doc.h > 0) { + h = loaderData.doc->node.doc.h; + if (vh < FLT_EPSILON) vh = h; + } + + preserveAspect = loaderData.doc->node.doc.preserveAspect; + } else { + TVGLOG("SVG", "No SVG File. There is no <svg/>"); + return false; + } + + return true; +} + + +bool SvgLoader::open(const char* data, uint32_t size, bool copy) +{ + clear(); + + if (copy) { + content = (char*)malloc(size); + if (!content) return false; + memcpy((char*)content, data, size); + } else content = data; + + this->size = size; + this->copy = copy; + + return header(); +} + + +bool SvgLoader::open(const string& path) +{ + clear(); + + ifstream f; + f.open(path); + + if (!f.is_open()) return false; + + svgPath = path; + getline(f, filePath, '\0'); + f.close(); + + if (filePath.empty()) return false; + + content = filePath.c_str(); + size = filePath.size(); + + return header(); +} + + +bool SvgLoader::resize(Paint* paint, float w, float h) +{ + if (!paint) return false; + + auto sx = w / this->w; + auto sy = h / this->h; + + if (preserveAspect) { + //Scale + auto scale = sx < sy ? sx : sy; + paint->scale(scale); + //Align + auto tx = 0.0f; + auto ty = 0.0f; + auto tw = this->w * scale; + auto th = this->h * scale; + if (tw > th) ty -= (h - th) * 0.5f; + else tx -= (w - tw) * 0.5f; + paint->translate(-tx, -ty); + } else { + //Align + auto tx = 0.0f; + auto ty = 0.0f; + auto tw = this->w * sx; + auto th = this->h * sy; + if (tw > th) ty -= (h - th) * 0.5f; + else tx -= (w - tw) * 0.5f; + + Matrix m = {sx, 0, -tx, 0, sy, -ty, 0, 0, 1}; + paint->transform(m); + } + return true; +} + + +bool SvgLoader::read() +{ + if (!content || size == 0) return false; + + TaskScheduler::request(this); + + return true; +} + + +bool SvgLoader::close() +{ + this->done(); + + if (loaderData.svgParse) { + free(loaderData.svgParse); + loaderData.svgParse = nullptr; + } + auto gradients = loaderData.gradients.data; + for (size_t i = 0; i < loaderData.gradients.count; ++i) { + (*gradients)->clear(); + free(*gradients); + ++gradients; + } + loaderData.gradients.reset(); + + _freeNode(loaderData.doc); + loaderData.doc = nullptr; + loaderData.stack.reset(); + + clear(); + + return true; +} + + +unique_ptr<Paint> SvgLoader::paint() +{ + this->done(); + if (root) return move(root); + else return nullptr; +} diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h new file mode 100644 index 0000000000..468f05801d --- /dev/null +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_SVG_LOADER_H_ +#define _TVG_SVG_LOADER_H_ + +#include "tvgTaskScheduler.h" +#include "tvgSvgLoaderCommon.h" + +class SvgLoader : public LoadModule, public Task +{ +public: + string filePath; + string svgPath = ""; + const char* content = nullptr; + uint32_t size = 0; + + SvgLoaderData loaderData; + unique_ptr<Scene> root; + + bool copy = false; + + SvgLoader(); + ~SvgLoader(); + + using LoadModule::open; + bool open(const string& path) override; + bool open(const char* data, uint32_t size, bool copy) override; + bool resize(Paint* paint, float w, float h) override; + bool read() override; + bool close() override; + unique_ptr<Paint> paint() override; + +private: + bool header(); + void clear(); + void run(unsigned tid) override; +}; + + +#endif //_TVG_SVG_LOADER_H_ diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h new file mode 100644 index 0000000000..cceef915f0 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h @@ -0,0 +1,412 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_SVG_LOADER_COMMON_H_ +#define _TVG_SVG_LOADER_COMMON_H_ + +#include "tvgCommon.h" +#include "tvgArray.h" + +struct SvgNode; +struct SvgStyleGradient; + +//NOTE: Please update simpleXmlNodeTypeToString() as well. +enum class SvgNodeType +{ + Doc, + G, + Defs, + Animation, + Arc, + Circle, + Ellipse, + Image, + Line, + Path, + Polygon, + Polyline, + Rect, + Text, + TextArea, + Tspan, + Use, + Video, + ClipPath, + Mask, + Unknown +}; + +/* +// TODO - remove? +enum class SvgLengthType +{ + Percent, + Px, + Pc, + Pt, + Mm, + Cm, + In, +}; +*/ + +enum class SvgFillFlags +{ + Paint = 0x01, + Opacity = 0x02, + Gradient = 0x04, + FillRule = 0x08, + ClipPath = 0x16 +}; + +enum class SvgStrokeFlags +{ + Paint = 0x1, + Opacity = 0x2, + Gradient = 0x4, + Scale = 0x8, + Width = 0x10, + Cap = 0x20, + Join = 0x40, + Dash = 0x80, +}; + +enum class SvgGradientType +{ + Linear, + Radial +}; + +enum class SvgStyleFlags +{ + Color = 0x01, + Fill = 0x02, + FillRule = 0x04, + FillOpacity = 0x08, + Opacity = 0x010, + Stroke = 0x20, + StrokeWidth = 0x40, + StrokeLineJoin = 0x80, + StrokeLineCap = 0x100, + StrokeOpacity = 0x200, + StrokeDashArray = 0x400, + Transform = 0x800, + ClipPath = 0x1000, + Mask = 0x2000, + Display = 0x4000 +}; + +enum class SvgStopStyleFlags +{ + StopDefault = 0x0, + StopOpacity = 0x01, + StopColor = 0x02 +}; + +enum class SvgFillRule +{ + Winding = 0, + OddEven = 1 +}; + +//Length type to recalculate %, pt, pc, mm, cm etc +enum class SvgParserLengthType +{ + Vertical, + Horizontal, + //In case of, for example, radius of radial gradient + Other +}; + +struct SvgDocNode +{ + float w; + float h; + float vx; + float vy; + float vw; + float vh; + SvgNode* defs; + bool preserveAspect; +}; + +struct SvgGNode +{ +}; + +struct SvgDefsNode +{ + Array<SvgStyleGradient*> gradients; +}; + +struct SvgUseNode +{ + float x, y, w, h; +}; + + +struct SvgEllipseNode +{ + float cx; + float cy; + float rx; + float ry; +}; + +struct SvgCircleNode +{ + float cx; + float cy; + float r; +}; + +struct SvgRectNode +{ + float x; + float y; + float w; + float h; + float rx; + float ry; + bool hasRx; + bool hasRy; +}; + +struct SvgLineNode +{ + float x1; + float y1; + float x2; + float y2; +}; + +struct SvgImageNode +{ + float x, y, w, h; + char* href; +}; + +struct SvgPathNode +{ + char* path; +}; + +struct SvgPolygonNode +{ + int pointsCount; + float* points; +}; + +struct SvgCompositeNode +{ + bool userSpace; +}; + +struct SvgLinearGradient +{ + float x1; + float y1; + float x2; + float y2; + bool isX1Percentage; + bool isY1Percentage; + bool isX2Percentage; + bool isY2Percentage; +}; + +struct SvgRadialGradient +{ + float cx; + float cy; + float fx; + float fy; + float r; + bool isCxPercentage; + bool isCyPercentage; + bool isFxPercentage; + bool isFyPercentage; + bool isRPercentage; +}; + +struct SvgComposite +{ + char *url; + SvgNode* node; + bool applying; //flag for checking circular dependency. +}; + +struct SvgColor +{ + uint8_t r; + uint8_t g; + uint8_t b; +}; + +struct SvgPaint +{ + SvgStyleGradient* gradient; + char *url; + SvgColor color; + bool none; + bool curColor; +}; + +struct SvgDash +{ + Array<float> array; +}; + +struct SvgStyleGradient +{ + SvgGradientType type; + char* id; + char* ref; + FillSpread spread; + SvgRadialGradient* radial; + SvgLinearGradient* linear; + Matrix* transform; + Array<Fill::ColorStop> stops; + bool userSpace; + + void clear() + { + stops.reset(); + free(transform); + free(radial); + free(linear); + free(ref); + free(id); + } +}; + +struct SvgStyleFill +{ + SvgFillFlags flags; + SvgPaint paint; + int opacity; + FillRule fillRule; +}; + +struct SvgStyleStroke +{ + SvgStrokeFlags flags; + SvgPaint paint; + int opacity; + float scale; + float width; + float centered; + StrokeCap cap; + StrokeJoin join; + SvgDash dash; + int dashCount; +}; + +struct SvgStyleProperty +{ + SvgStyleFill fill; + SvgStyleStroke stroke; + SvgComposite clipPath; + SvgComposite mask; + int opacity; + SvgColor color; + bool curColorSet; + SvgStyleFlags flags; +}; + +struct SvgNode +{ + SvgNodeType type; + SvgNode* parent; + Array<SvgNode*> child; + char *id; + SvgStyleProperty *style; + Matrix* transform; + union { + SvgGNode g; + SvgDocNode doc; + SvgDefsNode defs; + SvgUseNode use; + SvgCircleNode circle; + SvgEllipseNode ellipse; + SvgPolygonNode polygon; + SvgPolygonNode polyline; + SvgRectNode rect; + SvgPathNode path; + SvgLineNode line; + SvgImageNode image; + SvgCompositeNode comp; + } node; + bool display; + ~SvgNode(); +}; + +struct SvgParser +{ + SvgNode* node; + SvgStyleGradient* styleGrad; + Fill::ColorStop gradStop; + SvgStopStyleFlags flags; + struct + { + int x, y; + uint32_t w, h; + } global; + struct + { + bool parsedFx; + bool parsedFy; + } gradient; +}; + +struct SvgNodeIdPair +{ + SvgNode* node; + char *id; +}; + +struct SvgLoaderData +{ + Array<SvgNode *> stack = {nullptr, 0, 0}; + SvgNode* doc = nullptr; + SvgNode* def = nullptr; + Array<SvgStyleGradient*> gradients; + SvgStyleGradient* latestGradient = nullptr; //For stops + SvgParser* svgParse = nullptr; + Array<SvgNodeIdPair> cloneNodes; + int level = 0; + bool result = false; +}; + +/* + * https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strtof-strtod-l-wcstod-wcstod-l?view=vs-2017 + * + * src should be one of the following form : + * + * [whitespace] [sign] {digits [radix digits] | radix digits} [{e | E} [sign] digits] + * [whitespace] [sign] {INF | INFINITY} + * [whitespace] [sign] NAN [sequence] + * + * No hexadecimal form supported + * no sequence supported after NAN + */ +float customStrtof(const char *nptr, char **endptr); + +#endif diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp new file mode 100644 index 0000000000..2b62315de8 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp @@ -0,0 +1,563 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Copyright notice for the EFL: + + * Copyright (C) EFL developers (see AUTHORS) + + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define _USE_MATH_DEFINES //Math Constants are not defined in Standard C/C++. + +#include <math.h> +#include <clocale> +#include <ctype.h> +#include "tvgSvgLoaderCommon.h" +#include "tvgSvgPath.h" +#include "tvgSvgUtil.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static char* _skipComma(const char* content) +{ + while (*content && isspace(*content)) { + content++; + } + if (*content == ',') return (char*)content + 1; + return (char*)content; +} + + +static bool _parseNumber(char** content, float* number) +{ + char* end = NULL; + *number = svgUtilStrtof(*content, &end); + //If the start of string is not number + if ((*content) == end) return false; + //Skip comma if any + *content = _skipComma(end); + return true; +} + + +static bool _parseFlag(char** content, int* number) +{ + char* end = NULL; + if (*(*content) != '0' && *(*content) != '1') return false; + *number = *(*content) - '0'; + *content += 1; + end = *content; + *content = _skipComma(end); + + return true; +} + + +void _pathAppendArcTo(Array<PathCommand>* cmds, Array<Point>* pts, Point* cur, Point* curCtl, float x, float y, float rx, float ry, float angle, bool largeArc, bool sweep) +{ + float cxp, cyp, cx, cy; + float sx, sy; + float cosPhi, sinPhi; + float dx2, dy2; + float x1p, y1p; + float x1p2, y1p2; + float rx2, ry2; + float lambda; + float c; + float at; + float theta1, deltaTheta; + float nat; + float delta, bcp; + float cosPhiRx, cosPhiRy; + float sinPhiRx, sinPhiRy; + float cosTheta1, sinTheta1; + int segments; + + //Some helpful stuff is available here: + //http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes + sx = cur->x; + sy = cur->y; + + //If start and end points are identical, then no arc is drawn + if ((fabsf(x - sx) < (1.0f / 256.0f)) && (fabsf(y - sy) < (1.0f / 256.0f))) return; + + //Correction of out-of-range radii, see F6.6.1 (step 2) + rx = fabsf(rx); + ry = fabsf(ry); + + angle = angle * M_PI / 180.0f; + cosPhi = cosf(angle); + sinPhi = sinf(angle); + dx2 = (sx - x) / 2.0f; + dy2 = (sy - y) / 2.0f; + x1p = cosPhi * dx2 + sinPhi * dy2; + y1p = cosPhi * dy2 - sinPhi * dx2; + x1p2 = x1p * x1p; + y1p2 = y1p * y1p; + rx2 = rx * rx; + ry2 = ry * ry; + lambda = (x1p2 / rx2) + (y1p2 / ry2); + + //Correction of out-of-range radii, see F6.6.2 (step 4) + if (lambda > 1.0f) { + //See F6.6.3 + float lambdaRoot = sqrtf(lambda); + + rx *= lambdaRoot; + ry *= lambdaRoot; + //Update rx2 and ry2 + rx2 = rx * rx; + ry2 = ry * ry; + } + + c = (rx2 * ry2) - (rx2 * y1p2) - (ry2 * x1p2); + + //Check if there is no possible solution + //(i.e. we can't do a square root of a negative value) + if (c < 0.0f) { + //Scale uniformly until we have a single solution + //(see F6.2) i.e. when c == 0.0 + float scale = sqrtf(1.0f - c / (rx2 * ry2)); + rx *= scale; + ry *= scale; + //Update rx2 and ry2 + rx2 = rx * rx; + ry2 = ry * ry; + + //Step 2 (F6.5.2) - simplified since c == 0.0 + cxp = 0.0f; + cyp = 0.0f; + //Step 3 (F6.5.3 first part) - simplified since cxp and cyp == 0.0 + cx = 0.0f; + cy = 0.0f; + } else { + //Complete c calculation + c = sqrtf(c / ((rx2 * y1p2) + (ry2 * x1p2))); + //Inverse sign if Fa == Fs + if (largeArc == sweep) c = -c; + + //Step 2 (F6.5.2) + cxp = c * (rx * y1p / ry); + cyp = c * (-ry * x1p / rx); + + //Step 3 (F6.5.3 first part) + cx = cosPhi * cxp - sinPhi * cyp; + cy = sinPhi * cxp + cosPhi * cyp; + } + + //Step 3 (F6.5.3 second part) we now have the center point of the ellipse + cx += (sx + x) / 2.0f; + cy += (sy + y) / 2.0f; + + //Sstep 4 (F6.5.4) + //We dont' use arccos (as per w3c doc), see + //http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm + //Note: atan2 (0.0, 1.0) == 0.0 + at = atan2(((y1p - cyp) / ry), ((x1p - cxp) / rx)); + theta1 = (at < 0.0f) ? 2.0f * M_PI + at : at; + + nat = atan2(((-y1p - cyp) / ry), ((-x1p - cxp) / rx)); + deltaTheta = (nat < at) ? 2.0f * M_PI - at + nat : nat - at; + + if (sweep) { + //Ensure delta theta < 0 or else add 360 degrees + if (deltaTheta < 0.0f) deltaTheta += (float)(2.0f * M_PI); + } else { + //Ensure delta theta > 0 or else substract 360 degrees + if (deltaTheta > 0.0f) deltaTheta -= (float)(2.0f * M_PI); + } + + //Add several cubic bezier to approximate the arc + //(smaller than 90 degrees) + //We add one extra segment because we want something + //Smaller than 90deg (i.e. not 90 itself) + segments = static_cast<int>(fabsf(deltaTheta / float(M_PI_2)) + 1.0f); + delta = deltaTheta / segments; + + //http://www.stillhq.com/ctpfaq/2001/comp.text.pdf-faq-2001-04.txt (section 2.13) + bcp = 4.0f / 3.0f * (1.0f - cosf(delta / 2.0f)) / sinf(delta / 2.0f); + + cosPhiRx = cosPhi * rx; + cosPhiRy = cosPhi * ry; + sinPhiRx = sinPhi * rx; + sinPhiRy = sinPhi * ry; + + cosTheta1 = cosf(theta1); + sinTheta1 = sinf(theta1); + + for (int i = 0; i < segments; ++i) { + //End angle (for this segment) = current + delta + float c1x, c1y, ex, ey, c2x, c2y; + float theta2 = theta1 + delta; + float cosTheta2 = cosf(theta2); + float sinTheta2 = sinf(theta2); + Point p[3]; + + //First control point (based on start point sx,sy) + c1x = sx - bcp * (cosPhiRx * sinTheta1 + sinPhiRy * cosTheta1); + c1y = sy + bcp * (cosPhiRy * cosTheta1 - sinPhiRx * sinTheta1); + + //End point (for this segment) + ex = cx + (cosPhiRx * cosTheta2 - sinPhiRy * sinTheta2); + ey = cy + (sinPhiRx * cosTheta2 + cosPhiRy * sinTheta2); + + //Second control point (based on end point ex,ey) + c2x = ex + bcp * (cosPhiRx * sinTheta2 + sinPhiRy * cosTheta2); + c2y = ey + bcp * (sinPhiRx * sinTheta2 - cosPhiRy * cosTheta2); + cmds->push(PathCommand::CubicTo); + p[0] = {c1x, c1y}; + p[1] = {c2x, c2y}; + p[2] = {ex, ey}; + pts->push(p[0]); + pts->push(p[1]); + pts->push(p[2]); + *curCtl = p[1]; + *cur = p[2]; + + //Next start point is the current end point (same for angle) + sx = ex; + sy = ey; + theta1 = theta2; + //Avoid recomputations + cosTheta1 = cosTheta2; + sinTheta1 = sinTheta2; + } +} + +static int _numberCount(char cmd) +{ + int count = 0; + switch (cmd) { + case 'M': + case 'm': + case 'L': + case 'l': + case 'T': + case 't': { + count = 2; + break; + } + case 'C': + case 'c': + case 'E': + case 'e': { + count = 6; + break; + } + case 'H': + case 'h': + case 'V': + case 'v': { + count = 1; + break; + } + case 'S': + case 's': + case 'Q': + case 'q': { + count = 4; + break; + } + case 'A': + case 'a': { + count = 7; + break; + } + default: + break; + } + return count; +} + + +static bool _processCommand(Array<PathCommand>* cmds, Array<Point>* pts, char cmd, float* arr, int count, Point* cur, Point* curCtl, Point* startPoint, bool *isQuadratic) +{ + switch (cmd) { + case 'm': + case 'l': + case 'c': + case 's': + case 'q': + case 't': { + for (int i = 0; i < count - 1; i += 2) { + arr[i] = arr[i] + cur->x; + arr[i + 1] = arr[i + 1] + cur->y; + } + break; + } + case 'h': { + arr[0] = arr[0] + cur->x; + break; + } + case 'v': { + arr[0] = arr[0] + cur->y; + break; + } + case 'a': { + arr[5] = arr[5] + cur->x; + arr[6] = arr[6] + cur->y; + break; + } + default: { + break; + } + } + + switch (cmd) { + case 'm': + case 'M': { + Point p = {arr[0], arr[1]}; + cmds->push(PathCommand::MoveTo); + pts->push(p); + *cur = {arr[0], arr[1]}; + *startPoint = {arr[0], arr[1]}; + break; + } + case 'l': + case 'L': { + Point p = {arr[0], arr[1]}; + cmds->push(PathCommand::LineTo); + pts->push(p); + *cur = {arr[0], arr[1]}; + break; + } + case 'c': + case 'C': { + Point p[3]; + cmds->push(PathCommand::CubicTo); + p[0] = {arr[0], arr[1]}; + p[1] = {arr[2], arr[3]}; + p[2] = {arr[4], arr[5]}; + pts->push(p[0]); + pts->push(p[1]); + pts->push(p[2]); + *curCtl = p[1]; + *cur = p[2]; + *isQuadratic = false; + break; + } + case 's': + case 'S': { + Point p[3], ctrl; + if ((cmds->count > 1) && (cmds->data[cmds->count - 1] == PathCommand::CubicTo) && + !(*isQuadratic)) { + ctrl.x = 2 * cur->x - curCtl->x; + ctrl.y = 2 * cur->y - curCtl->y; + } else { + ctrl = *cur; + } + cmds->push(PathCommand::CubicTo); + p[0] = ctrl; + p[1] = {arr[0], arr[1]}; + p[2] = {arr[2], arr[3]}; + pts->push(p[0]); + pts->push(p[1]); + pts->push(p[2]); + *curCtl = p[1]; + *cur = p[2]; + *isQuadratic = false; + break; + } + case 'q': + case 'Q': { + Point p[3]; + float ctrl_x0 = (cur->x + 2 * arr[0]) * (1.0 / 3.0); + float ctrl_y0 = (cur->y + 2 * arr[1]) * (1.0 / 3.0); + float ctrl_x1 = (arr[2] + 2 * arr[0]) * (1.0 / 3.0); + float ctrl_y1 = (arr[3] + 2 * arr[1]) * (1.0 / 3.0); + cmds->push(PathCommand::CubicTo); + p[0] = {ctrl_x0, ctrl_y0}; + p[1] = {ctrl_x1, ctrl_y1}; + p[2] = {arr[2], arr[3]}; + pts->push(p[0]); + pts->push(p[1]); + pts->push(p[2]); + *curCtl = {arr[0], arr[1]}; + *cur = p[2]; + *isQuadratic = true; + break; + } + case 't': + case 'T': { + Point p[3], ctrl; + if ((cmds->count > 1) && (cmds->data[cmds->count - 1] == PathCommand::CubicTo) && + *isQuadratic) { + ctrl.x = 2 * cur->x - curCtl->x; + ctrl.y = 2 * cur->y - curCtl->y; + } else { + ctrl = *cur; + } + float ctrl_x0 = (cur->x + 2 * ctrl.x) * (1.0 / 3.0); + float ctrl_y0 = (cur->y + 2 * ctrl.y) * (1.0 / 3.0); + float ctrl_x1 = (arr[0] + 2 * ctrl.x) * (1.0 / 3.0); + float ctrl_y1 = (arr[1] + 2 * ctrl.y) * (1.0 / 3.0); + cmds->push(PathCommand::CubicTo); + p[0] = {ctrl_x0, ctrl_y0}; + p[1] = {ctrl_x1, ctrl_y1}; + p[2] = {arr[0], arr[1]}; + pts->push(p[0]); + pts->push(p[1]); + pts->push(p[2]); + *curCtl = {ctrl.x, ctrl.y}; + *cur = p[2]; + *isQuadratic = true; + break; + } + case 'h': + case 'H': { + Point p = {arr[0], cur->y}; + cmds->push(PathCommand::LineTo); + pts->push(p); + cur->x = arr[0]; + break; + } + case 'v': + case 'V': { + Point p = {cur->x, arr[0]}; + cmds->push(PathCommand::LineTo); + pts->push(p); + cur->y = arr[0]; + break; + } + case 'z': + case 'Z': { + cmds->push(PathCommand::Close); + *cur = *startPoint; + break; + } + case 'a': + case 'A': { + _pathAppendArcTo(cmds, pts, cur, curCtl, arr[5], arr[6], arr[0], arr[1], arr[2], arr[3], arr[4]); + *cur = *curCtl = {arr[5], arr[6]}; + *isQuadratic = false; + break; + } + default: { + return false; + } + } + return true; +} + + +static char* _nextCommand(char* path, char* cmd, float* arr, int* count) +{ + int large, sweep; + + path = _skipComma(path); + if (isalpha(*path)) { + *cmd = *path; + path++; + *count = _numberCount(*cmd); + } else { + if (*cmd == 'm') *cmd = 'l'; + else if (*cmd == 'M') *cmd = 'L'; + } + if (*count == 7) { + //Special case for arc command + if (_parseNumber(&path, &arr[0])) { + if (_parseNumber(&path, &arr[1])) { + if (_parseNumber(&path, &arr[2])) { + if (_parseFlag(&path, &large)) { + if (_parseFlag(&path, &sweep)) { + if (_parseNumber(&path, &arr[5])) { + if (_parseNumber(&path, &arr[6])) { + arr[3] = (float)large; + arr[4] = (float)sweep; + return path; + } + } + } + } + } + } + } + *count = 0; + return NULL; + } + for (int i = 0; i < *count; i++) { + if (!_parseNumber(&path, &arr[i])) { + *count = 0; + return NULL; + } + path = _skipComma(path); + } + return path; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + + +bool svgPathToTvgPath(const char* svgPath, Array<PathCommand>& cmds, Array<Point>& pts) +{ + float numberArray[7]; + int numberCount = 0; + Point cur = { 0, 0 }; + Point curCtl = { 0, 0 }; + Point startPoint = { 0, 0 }; + char cmd = 0; + bool isQuadratic = false; + char* path = (char*)svgPath; + char* curLocale; + + curLocale = setlocale(LC_NUMERIC, NULL); + if (curLocale) curLocale = strdup(curLocale); + setlocale(LC_NUMERIC, "POSIX"); + + while ((path[0] != '\0')) { + path = _nextCommand(path, &cmd, numberArray, &numberCount); + if (!path) break; + if (!_processCommand(&cmds, &pts, cmd, numberArray, numberCount, &cur, &curCtl, &startPoint, &isQuadratic)) break; + } + + setlocale(LC_NUMERIC, curLocale); + if (curLocale) free(curLocale); + + return true; +} diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.h new file mode 100644 index 0000000000..7f26c4a213 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _TVG_SVG_PATH_H_ +#define _TVG_SVG_PATH_H_ + +#include <tvgCommon.h> + +bool svgPathToTvgPath(const char* svgPath, Array<PathCommand>& cmds, Array<Point>& pts); + +#endif //_TVG_SVG_PATH_H_ diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp new file mode 100644 index 0000000000..8701fe32b1 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -0,0 +1,652 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Copyright notice for the EFL: + + * Copyright (C) EFL developers (see AUTHORS) + + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <string> +#include "tvgMath.h" +#include "tvgSvgLoaderCommon.h" +#include "tvgSvgSceneBuilder.h" +#include "tvgSvgPath.h" +#include "tvgSvgUtil.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct Box +{ + float x, y, w, h; +}; + + +static bool _appendShape(SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath); +static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask); + + +static inline bool _isGroupType(SvgNodeType type) +{ + if (type == SvgNodeType::Doc || type == SvgNodeType::G || type == SvgNodeType::Use || type == SvgNodeType::ClipPath) return true; + return false; +} + + +//According to: https://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBoxUnits (the last paragraph) +//a stroke width should be ignored for bounding box calculations +static Box _boundingBox(const Shape* shape) +{ + float x, y, w, h; + shape->bounds(&x, &y, &w, &h, false); + + if (auto strokeW = shape->strokeWidth()) { + x += 0.5f * strokeW; + y += 0.5f * strokeW; + w -= strokeW; + h -= strokeW; + } + + return {x, y, w, h}; +} + + +static void _transformMultiply(const Matrix* mBBox, Matrix* gradTransf) +{ + gradTransf->e13 = gradTransf->e13 * mBBox->e11 + mBBox->e13; + gradTransf->e12 *= mBBox->e11; + gradTransf->e11 *= mBBox->e11; + + gradTransf->e23 = gradTransf->e23 * mBBox->e22 + mBBox->e23; + gradTransf->e22 *= mBBox->e22; + gradTransf->e21 *= mBBox->e22; +} + + +static unique_ptr<LinearGradient> _applyLinearGradientProperty(SvgStyleGradient* g, const Shape* vg, const Box& vBox, int opacity) +{ + Fill::ColorStop* stops; + int stopCount = 0; + auto fillGrad = LinearGradient::gen(); + + bool isTransform = (g->transform ? true : false); + Matrix finalTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + if (isTransform) finalTransform = *g->transform; + + if (g->userSpace) { + g->linear->x1 = g->linear->x1 * vBox.w; + g->linear->y1 = g->linear->y1 * vBox.h; + g->linear->x2 = g->linear->x2 * vBox.w; + g->linear->y2 = g->linear->y2 * vBox.h; + } else { + Matrix m = {vBox.w, 0, vBox.x, 0, vBox.h, vBox.y, 0, 0, 1}; + if (isTransform) _transformMultiply(&m, &finalTransform); + else { + finalTransform = m; + isTransform = true; + } + } + + if (isTransform) fillGrad->transform(finalTransform); + + fillGrad->linear(g->linear->x1, g->linear->y1, g->linear->x2, g->linear->y2); + fillGrad->spread(g->spread); + + //Update the stops + stopCount = g->stops.count; + if (stopCount > 0) { + stops = (Fill::ColorStop*)calloc(stopCount, sizeof(Fill::ColorStop)); + if (!stops) return fillGrad; + auto prevOffset = 0.0f; + for (uint32_t i = 0; i < g->stops.count; ++i) { + auto colorStop = &g->stops.data[i]; + //Use premultiplied color + stops[i].r = colorStop->r; + stops[i].g = colorStop->g; + stops[i].b = colorStop->b; + stops[i].a = static_cast<uint8_t>((colorStop->a * opacity) / 255); + stops[i].offset = colorStop->offset; + //check the offset corner cases - refer to: https://svgwg.org/svg2-draft/pservers.html#StopNotes + if (colorStop->offset < prevOffset) stops[i].offset = prevOffset; + else if (colorStop->offset > 1) stops[i].offset = 1; + prevOffset = stops[i].offset; + } + fillGrad->colorStops(stops, stopCount); + free(stops); + } + return fillGrad; +} + + +static unique_ptr<RadialGradient> _applyRadialGradientProperty(SvgStyleGradient* g, const Shape* vg, const Box& vBox, int opacity) +{ + Fill::ColorStop *stops; + int stopCount = 0; + auto fillGrad = RadialGradient::gen(); + + bool isTransform = (g->transform ? true : false); + Matrix finalTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + if (isTransform) finalTransform = *g->transform; + + if (g->userSpace) { + //The radius scalling is done according to the Units section: + //https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html + g->radial->cx = g->radial->cx * vBox.w; + g->radial->cy = g->radial->cy * vBox.h; + g->radial->r = g->radial->r * sqrtf(powf(vBox.w, 2.0f) + powf(vBox.h, 2.0f)) / sqrtf(2.0f); + g->radial->fx = g->radial->fx * vBox.w; + g->radial->fy = g->radial->fy * vBox.h; + } else { + Matrix m = {vBox.w, 0, vBox.x, 0, vBox.h, vBox.y, 0, 0, 1}; + if (isTransform) _transformMultiply(&m, &finalTransform); + else { + finalTransform = m; + isTransform = true; + } + } + + if (isTransform) fillGrad->transform(finalTransform); + + //TODO: Tvg is not support to focal + //if (g->radial->fx != 0 && g->radial->fy != 0) { + // fillGrad->radial(g->radial->fx, g->radial->fy, g->radial->r); + //} + fillGrad->radial(g->radial->cx, g->radial->cy, g->radial->r); + fillGrad->spread(g->spread); + + //Update the stops + stopCount = g->stops.count; + if (stopCount > 0) { + stops = (Fill::ColorStop*)calloc(stopCount, sizeof(Fill::ColorStop)); + if (!stops) return fillGrad; + auto prevOffset = 0.0f; + for (uint32_t i = 0; i < g->stops.count; ++i) { + auto colorStop = &g->stops.data[i]; + //Use premultiplied color + stops[i].r = colorStop->r; + stops[i].g = colorStop->g; + stops[i].b = colorStop->b; + stops[i].a = static_cast<uint8_t>((colorStop->a * opacity) / 255); + stops[i].offset = colorStop->offset; + //check the offset corner cases - refer to: https://svgwg.org/svg2-draft/pservers.html#StopNotes + if (colorStop->offset < prevOffset) stops[i].offset = prevOffset; + else if (colorStop->offset > 1) stops[i].offset = 1; + prevOffset = stops[i].offset; + } + fillGrad->colorStops(stops, stopCount); + free(stops); + } + return fillGrad; +} + + +static bool _appendChildShape(SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath) +{ + auto valid = false; + + if (_appendShape(node, shape, vBox, svgPath)) valid = true; + + if (node->child.count > 0) { + auto child = node->child.data; + for (uint32_t i = 0; i < node->child.count; ++i, ++child) { + if (_appendChildShape(*child, shape, vBox, svgPath)) valid = true; + } + } + + return valid; +} + + +static void _applyComposition(Paint* paint, const SvgNode* node, const Box& vBox, const string& svgPath) +{ + /* ClipPath */ + /* Do not drop in Circular Dependency for ClipPath. + Composition can be applied recursively if its children nodes have composition target to this one. */ + if (node->style->clipPath.applying) { + TVGLOG("SVG", "Multiple Composition Tried! Check out Circular dependency?"); + } else { + auto compNode = node->style->clipPath.node; + if (compNode && compNode->child.count > 0) { + node->style->clipPath.applying = true; + + auto comp = Shape::gen(); + comp->fill(255, 255, 255, 255); + if (node->transform) comp->transform(*node->transform); + + auto child = compNode->child.data; + auto valid = false; //Composite only when valid shapes are existed + + for (uint32_t i = 0; i < compNode->child.count; ++i, ++child) { + if (_appendChildShape(*child, comp.get(), vBox, svgPath)) valid = true; + } + + if (valid) paint->composite(move(comp), CompositeMethod::ClipPath); + + node->style->clipPath.applying = false; + } + } + + /* Mask */ + /* Do not drop in Circular Dependency for Mask. + Composition can be applied recursively if its children nodes have composition target to this one. */ + if (node->style->mask.applying) { + TVGLOG("SVG", "Multiple Composition Tried! Check out Circular dependency?"); + } else { + auto compNode = node->style->mask.node; + if (compNode && compNode->child.count > 0) { + node->style->mask.applying = true; + + auto comp = _sceneBuildHelper(compNode, vBox, svgPath, true); + if (comp) { + if (node->transform) comp->transform(*node->transform); + paint->composite(move(comp), CompositeMethod::AlphaMask); + } + + node->style->mask.applying = false; + } + } +} + + +static void _applyProperty(SvgNode* node, Shape* vg, const Box& vBox, const string& svgPath) +{ + SvgStyleProperty* style = node->style; + + if (node->transform) vg->transform(*node->transform); + if (node->type == SvgNodeType::Doc || !node->display) return; + + //If fill property is nullptr then do nothing + if (style->fill.paint.none) { + //Do nothing + } else if (style->fill.paint.gradient) { + Box bBox = vBox; + if (!style->fill.paint.gradient->userSpace) bBox = _boundingBox(vg); + + if (style->fill.paint.gradient->type == SvgGradientType::Linear) { + auto linear = _applyLinearGradientProperty(style->fill.paint.gradient, vg, bBox, style->fill.opacity); + vg->fill(move(linear)); + } else if (style->fill.paint.gradient->type == SvgGradientType::Radial) { + auto radial = _applyRadialGradientProperty(style->fill.paint.gradient, vg, bBox, style->fill.opacity); + vg->fill(move(radial)); + } + } else if (style->fill.paint.url) { + //TODO: Apply the color pointed by url + } else if (style->fill.paint.curColor) { + //Apply the current style color + vg->fill(style->color.r, style->color.g, style->color.b, style->fill.opacity); + } else { + //Apply the fill color + vg->fill(style->fill.paint.color.r, style->fill.paint.color.g, style->fill.paint.color.b, style->fill.opacity); + } + + //Apply the fill rule + vg->fill((tvg::FillRule)style->fill.fillRule); + + //Apply node opacity + if (style->opacity < 255) vg->opacity(style->opacity); + + if (node->type == SvgNodeType::G || node->type == SvgNodeType::Use) return; + + //Apply the stroke style property + vg->stroke(style->stroke.width); + vg->stroke(style->stroke.cap); + vg->stroke(style->stroke.join); + if (style->stroke.dash.array.count > 0) { + vg->stroke(style->stroke.dash.array.data, style->stroke.dash.array.count); + } + + //If stroke property is nullptr then do nothing + if (style->stroke.paint.none) { + //Do nothing + } else if (style->stroke.paint.gradient) { + Box bBox = vBox; + if (!style->stroke.paint.gradient->userSpace) bBox = _boundingBox(vg); + + if (style->stroke.paint.gradient->type == SvgGradientType::Linear) { + auto linear = _applyLinearGradientProperty(style->stroke.paint.gradient, vg, bBox, style->stroke.opacity); + vg->stroke(move(linear)); + } else if (style->stroke.paint.gradient->type == SvgGradientType::Radial) { + auto radial = _applyRadialGradientProperty(style->stroke.paint.gradient, vg, bBox, style->stroke.opacity); + vg->stroke(move(radial)); + } + } else if (style->stroke.paint.url) { + //TODO: Apply the color pointed by url + } else if (style->stroke.paint.curColor) { + //Apply the current style color + vg->stroke(style->color.r, style->color.g, style->color.b, style->stroke.opacity); + } else { + //Apply the stroke color + vg->stroke(style->stroke.paint.color.r, style->stroke.paint.color.g, style->stroke.paint.color.b, style->stroke.opacity); + } + + _applyComposition(vg, node, vBox, svgPath); +} + + +static unique_ptr<Shape> _shapeBuildHelper(SvgNode* node, const Box& vBox, const string& svgPath) +{ + auto shape = Shape::gen(); + if (_appendShape(node, shape.get(), vBox, svgPath)) return shape; + else return nullptr; +} + + +static bool _appendShape(SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath) +{ + Array<PathCommand> cmds; + Array<Point> pts; + + switch (node->type) { + case SvgNodeType::Path: { + if (node->node.path.path) { + if (svgPathToTvgPath(node->node.path.path, cmds, pts)) { + shape->appendPath(cmds.data, cmds.count, pts.data, pts.count); + } + } + break; + } + case SvgNodeType::Ellipse: { + shape->appendCircle(node->node.ellipse.cx, node->node.ellipse.cy, node->node.ellipse.rx, node->node.ellipse.ry); + break; + } + case SvgNodeType::Polygon: { + if (node->node.polygon.pointsCount < 2) break; + shape->moveTo(node->node.polygon.points[0], node->node.polygon.points[1]); + for (int i = 2; i < node->node.polygon.pointsCount - 1; i += 2) { + shape->lineTo(node->node.polygon.points[i], node->node.polygon.points[i + 1]); + } + shape->close(); + break; + } + case SvgNodeType::Polyline: { + if (node->node.polygon.pointsCount < 2) break; + shape->moveTo(node->node.polygon.points[0], node->node.polygon.points[1]); + for (int i = 2; i < node->node.polygon.pointsCount - 1; i += 2) { + shape->lineTo(node->node.polygon.points[i], node->node.polygon.points[i + 1]); + } + break; + } + case SvgNodeType::Circle: { + shape->appendCircle(node->node.circle.cx, node->node.circle.cy, node->node.circle.r, node->node.circle.r); + break; + } + case SvgNodeType::Rect: { + shape->appendRect(node->node.rect.x, node->node.rect.y, node->node.rect.w, node->node.rect.h, node->node.rect.rx, node->node.rect.ry); + break; + } + case SvgNodeType::Line: { + shape->moveTo(node->node.line.x1, node->node.line.y1); + shape->lineTo(node->node.line.x2, node->node.line.y2); + break; + } + default: { + return false; + } + } + + _applyProperty(node, shape, vBox, svgPath); + return true; +} + + +enum class imageMimeTypeEncoding +{ + base64 = 0x1, + utf8 = 0x2 +}; +constexpr imageMimeTypeEncoding operator|(imageMimeTypeEncoding a, imageMimeTypeEncoding b) { + return static_cast<imageMimeTypeEncoding>(static_cast<int>(a) | static_cast<int>(b)); +} +constexpr bool operator&(imageMimeTypeEncoding a, imageMimeTypeEncoding b) { + return (static_cast<int>(a) & static_cast<int>(b)); +} + + +static constexpr struct +{ + const char* name; + int sz; + imageMimeTypeEncoding encoding; +} imageMimeTypes[] = { + {"jpeg", sizeof("jpeg"), imageMimeTypeEncoding::base64}, + {"png", sizeof("png"), imageMimeTypeEncoding::base64}, + {"svg+xml", sizeof("svg+xml"), imageMimeTypeEncoding::base64 | imageMimeTypeEncoding::utf8}, +}; + + +static bool _isValidImageMimeTypeAndEncoding(const char** href, const char** mimetype, imageMimeTypeEncoding* encoding) { + if (strncmp(*href, "image/", sizeof("image/") - 1)) return false; //not allowed mime type + *href += sizeof("image/") - 1; + + //RFC2397 data:[<mediatype>][;base64],<data> + //mediatype := [ type "/" subtype ] *( ";" parameter ) + //parameter := attribute "=" value + for (unsigned int i = 0; i < sizeof(imageMimeTypes) / sizeof(imageMimeTypes[0]); i++) { + if (!strncmp(*href, imageMimeTypes[i].name, imageMimeTypes[i].sz - 1)) { + *href += imageMimeTypes[i].sz - 1; + *mimetype = imageMimeTypes[i].name; + + while (**href && **href != ',') { + while (**href && **href != ';') ++(*href); + if (!**href) return false; + ++(*href); + + if (imageMimeTypes[i].encoding & imageMimeTypeEncoding::base64) { + if (!strncmp(*href, "base64,", sizeof("base64,") - 1)) { + *href += sizeof("base64,") - 1; + *encoding = imageMimeTypeEncoding::base64; + return true; //valid base64 + } + } + if (imageMimeTypes[i].encoding & imageMimeTypeEncoding::utf8) { + if (!strncmp(*href, "utf8,", sizeof("utf8,") - 1)) { + *href += sizeof("utf8,") - 1; + *encoding = imageMimeTypeEncoding::utf8; + return true; //valid utf8 + } + } + } + //no encoding defined + if (**href == ',' && (imageMimeTypes[i].encoding & imageMimeTypeEncoding::utf8)) { + ++(*href); + *encoding = imageMimeTypeEncoding::utf8; + return true; //allow no encoding defined if utf8 expected + } + return false; + } + } + return false; +} + + +static unique_ptr<Picture> _imageBuildHelper(SvgNode* node, const Box& vBox, const string& svgPath) +{ + if (!node->node.image.href) return nullptr; + auto picture = Picture::gen(); + + const char* href = node->node.image.href; + if (!strncmp(href, "data:", sizeof("data:") - 1)) { + href += sizeof("data:") - 1; + const char* mimetype; + imageMimeTypeEncoding encoding; + if (!_isValidImageMimeTypeAndEncoding(&href, &mimetype, &encoding)) return nullptr; //not allowed mime type or encoding + if (encoding == imageMimeTypeEncoding::base64) { + string decoded = svgUtilBase64Decode(href); + if (picture->load(decoded.c_str(), decoded.size(), mimetype, true) != Result::Success) return nullptr; + } else { + string decoded = svgUtilURLDecode(href); + if (picture->load(decoded.c_str(), decoded.size(), mimetype, true) != Result::Success) return nullptr; + } + } else { + if (!strncmp(href, "file://", sizeof("file://") - 1)) href += sizeof("file://") - 1; + //TODO: protect against recursive svg image loading + //Temporarily disable embedded svg: + const char *dot = strrchr(href, '.'); + if (dot && !strcmp(dot, ".svg")) { + TVGLOG("SVG", "Embedded svg file is disabled."); + return nullptr; + } + string imagePath = href; + if (strncmp(href, "/", 1)) { + auto last = svgPath.find_last_of("/"); + imagePath = svgPath.substr(0, (last == string::npos ? 0 : last + 1 )) + imagePath; + } + if (picture->load(imagePath) != Result::Success) return nullptr; + } + + float w, h; + if (picture->size(&w, &h) == Result::Success && w > 0 && h > 0) { + auto sx = node->node.image.w / w; + auto sy = node->node.image.h / h; + Matrix m = {sx, 0, node->node.image.x, 0, sy, node->node.image.y, 0, 0, 1}; + picture->transform(m); + } + + _applyComposition(picture.get(), node, vBox, svgPath); + return picture; +} + + +static unique_ptr<Scene> _useBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath) +{ + auto scene = _sceneBuildHelper(node, vBox, svgPath, false); + if (node->node.use.x != 0.0f || node->node.use.y != 0.0f) { + scene->translate(node->node.use.x, node->node.use.y); + } + if (node->node.use.w > 0.0f && node->node.use.h > 0.0f) { + //TODO: handle width/height properties + } + return scene; +} + + +static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask) +{ + if (_isGroupType(node->type) || mask) { + auto scene = Scene::gen(); + if (!mask && node->transform) scene->transform(*node->transform); + + if (node->display && node->style->opacity != 0) { + auto child = node->child.data; + for (uint32_t i = 0; i < node->child.count; ++i, ++child) { + if (_isGroupType((*child)->type)) { + if ((*child)->type == SvgNodeType::Use) + scene->push(_useBuildHelper(*child, vBox, svgPath)); + else + scene->push(_sceneBuildHelper(*child, vBox, svgPath, false)); + } else if ((*child)->type == SvgNodeType::Image) { + auto image = _imageBuildHelper(*child, vBox, svgPath); + if (image) scene->push(move(image)); + } else if ((*child)->type != SvgNodeType::Mask) { + auto shape = _shapeBuildHelper(*child, vBox, svgPath); + if (shape) scene->push(move(shape)); + } + } + _applyComposition(scene.get(), node, vBox, svgPath); + scene->opacity(node->style->opacity); + } + return scene; + } + return nullptr; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +unique_ptr<Scene> svgSceneBuild(SvgNode* node, float vx, float vy, float vw, float vh, float w, float h, bool preserveAspect, const string& svgPath) +{ + if (!node || (node->type != SvgNodeType::Doc)) return nullptr; + + Box vBox = {vx, vy, vw, vh}; + auto docNode = _sceneBuildHelper(node, vBox, svgPath, false); + + if (!mathEqual(w, vw) || !mathEqual(h, vh)) { + auto sx = w / vw; + auto sy = h / vh; + + if (preserveAspect) { + //Scale + auto scale = sx < sy ? sx : sy; + docNode->scale(scale); + //Align + auto tvx = vx * scale; + auto tvy = vy * scale; + auto tvw = vw * scale; + auto tvh = vh * scale; + if (vw > vh) tvy -= (h - tvh) * 0.5f; + else tvx -= (w - tvw) * 0.5f; + docNode->translate(-tvx, -tvy); + } else { + //Align + auto tvx = vx * sx; + auto tvy = vy * sy; + auto tvw = vw * sx; + auto tvh = vh * sy; + if (tvw > tvh) tvy -= (h - tvh) * 0.5f; + else tvx -= (w - tvw) * 0.5f; + Matrix m = {sx, 0, -tvx, 0, sy, -tvy, 0, 0, 1}; + docNode->transform(m); + } + } else if (!mathZero(vx) || !mathZero(vy)) { + docNode->translate(-vx, -vy); + } + + auto viewBoxClip = Shape::gen(); + viewBoxClip->appendRect(0, 0, w, h, 0, 0); + viewBoxClip->fill(0, 0, 0, 255); + + auto compositeLayer = Scene::gen(); + compositeLayer->composite(move(viewBoxClip), CompositeMethod::ClipPath); + compositeLayer->push(move(docNode)); + + auto root = Scene::gen(); + root->push(move(compositeLayer)); + + return root; +} diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h new file mode 100644 index 0000000000..4232aca612 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _TVG_SVG_SCENE_BUILDER_H_ +#define _TVG_SVG_SCENE_BUILDER_H_ + +#include "tvgCommon.h" + +unique_ptr<Scene> svgSceneBuild(SvgNode* node, float vx, float vy, float vw, float vh, float w, float h, bool preserveAspect, const string& svgPath); + +#endif //_TVG_SVG_SCENE_BUILDER_H_ diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp new file mode 100644 index 0000000000..d5b9cdcf7b --- /dev/null +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <math.h> +#include <memory.h> +#include "tvgSvgUtil.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static inline bool _floatExact(float a, float b) +{ + return memcmp(&a, &b, sizeof(float)) == 0; +} + +static uint8_t _hexCharToDec(const char c) +{ + if (c >= 'a') return c - 'a' + 10; + else if (c >= 'A') return c - 'A' + 10; + else return c - '0'; +} + +static uint8_t _base64Value(const char chr) +{ + if (chr >= 'A' && chr <= 'Z') return chr - 'A'; + else if (chr >= 'a' && chr <= 'z') return chr - 'a' + ('Z' - 'A') + 1; + else if (chr >= '0' && chr <= '9') return chr - '0' + ('Z' - 'A') + ('z' - 'a') + 2; + else if (chr == '+' || chr == '-') return 62; + else return 63; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + + +/* + * https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strtof-strtof-l-wcstof-wcstof-l?view=msvc-160 + * + * src should be one of the following form : + * + * [whitespace] [sign] {digits [radix digits] | radix digits} [{e | E} [sign] digits] + * [whitespace] [sign] {INF | INFINITY} + * [whitespace] [sign] NAN [sequence] + * + * No hexadecimal form supported + * no sequence supported after NAN + */ +float svgUtilStrtof(const char *nPtr, char **endPtr) +{ + if (endPtr) *endPtr = (char*)(nPtr); + if (!nPtr) return 0.0f; + + auto a = nPtr; + auto iter = nPtr; + auto val = 0.0f; + unsigned long long integerPart = 0; + int minus = 1; + + //ignore leading whitespaces + while (isspace(*iter)) iter++; + + //signed or not + if (*iter == '-') { + minus = -1; + iter++; + } else if (*iter == '+') { + iter++; + } + + if (tolower(*iter) == 'i') { + if ((tolower(*(iter + 1)) == 'n') && (tolower(*(iter + 2)) == 'f')) iter += 3; + else goto error; + + if (tolower(*(iter + 3)) == 'i') { + if ((tolower(*(iter + 4)) == 'n') && (tolower(*(iter + 5)) == 'i') && (tolower(*(iter + 6)) == 't') && (tolower(*(iter + 7)) == 'y')) iter += 5; + else goto error; + } + if (endPtr) *endPtr = (char *)(iter); + return (minus == -1) ? -INFINITY : INFINITY; + } + + if (tolower(*iter) == 'n') { + if ((tolower(*(iter + 1)) == 'a') && (tolower(*(iter + 2)) == 'n')) iter += 3; + else goto error; + + if (endPtr) *endPtr = (char *)(iter); + return (minus == -1) ? -NAN : NAN; + } + + //Optional: integer part before dot + if (isdigit(*iter)) { + for (; isdigit(*iter); iter++) { + integerPart = integerPart * 10ULL + (unsigned long long)(*iter - '0'); + } + a = iter; + } else if (*iter != '.') { + goto success; + } + + val = static_cast<float>(integerPart); + + //Optional: decimal part after dot + if (*iter == '.') { + unsigned long long decimalPart = 0; + unsigned long long pow10 = 1; + int count = 0; + + iter++; + + if (isdigit(*iter)) { + for (; isdigit(*iter); iter++, count++) { + if (count < 19) { + decimalPart = decimalPart * 10ULL + + static_cast<unsigned long long>(*iter - '0'); + pow10 *= 10ULL; + } + } + } + val += static_cast<float>(decimalPart) / static_cast<float>(pow10); + a = iter; + } + + //Optional: exponent + if (*iter == 'e' || *iter == 'E') { + ++iter; + + //Exception: svg may have 'em' unit for fonts. ex) 5em, 10.5em + if ((*iter == 'm') || (*iter == 'M')) { + //TODO: We don't support font em unit now, but has to multiply val * font size later... + a = iter + 1; + goto success; + } + + //signed or not + int minus_e = 1; + + if (*iter == '-') { + minus_e = -1; + ++iter; + } else if (*iter == '+') { + iter++; + } + + unsigned int exponentPart = 0; + + if (isdigit(*iter)) { + while (*iter == '0') iter++; + for (; isdigit(*iter); iter++) { + exponentPart = exponentPart * 10U + static_cast<unsigned int>(*iter - '0'); + } + } else if (!isdigit(*(a - 1))) { + a = nPtr; + goto success; + } else if (*iter == 0) { + goto success; + } + + //if ((_floatExact(val, 2.2250738585072011f)) && ((minus_e * static_cast<int>(exponentPart)) <= -308)) { + if ((_floatExact(val, 1.175494351f)) && ((minus_e * static_cast<int>(exponentPart)) <= -38)) { + //val *= 1.0e-308f; + val *= 1.0e-38f; + a = iter; + goto success; + } + + a = iter; + auto scale = 1.0f; + + while (exponentPart >= 8U) { + scale *= 1E8; + exponentPart -= 8U; + } + while (exponentPart > 0U) { + scale *= 10.0f; + exponentPart--; + } + val = (minus_e == -1) ? (val / scale) : (val * scale); + } else if ((iter > nPtr) && !isdigit(*(iter - 1))) { + a = nPtr; + goto success; + } + +success: + if (endPtr) *endPtr = (char*)(a); + return minus * val; + +error: + if (endPtr) *endPtr = (char*)(nPtr); + return 0.0f; +} + + +string svgUtilURLDecode(const char *src) +{ + if (!src) return nullptr; + + auto length = strlen(src); + if (length == 0) return nullptr; + + string decoded; + decoded.reserve(length); + + char a, b; + while (*src) { + if (*src == '%' && + ((a = src[1]) && (b = src[2])) && + (isxdigit(a) && isxdigit(b))) { + decoded += (_hexCharToDec(a) << 4) + _hexCharToDec(b); + src+=3; + } else if (*src == '+') { + decoded += ' '; + src++; + } else { + decoded += *src++; + } + } + return decoded; +} + + +string svgUtilBase64Decode(const char *src) +{ + if (!src) return nullptr; + + auto length = strlen(src); + if (length == 0) return nullptr; + + string decoded; + decoded.reserve(3*(1+(length >> 2))); + + while (*src && *(src+1)) { + if (*src <= 0x20) { + ++src; + continue; + } + + auto value1 = _base64Value(src[0]); + auto value2 = _base64Value(src[1]); + decoded += (value1 << 2) + ((value2 & 0x30) >> 4); + + if (!src[2] || src[2] == '=' || src[2] == '.') break; + auto value3 = _base64Value(src[2]); + decoded += ((value2 & 0x0f) << 4) + ((value3 & 0x3c) >> 2); + + if (!src[3] || src[3] == '=' || src[3] == '.') break; + auto value4 = _base64Value(src[3]); + decoded += ((value3 & 0x03) << 6) + value4; + src += 4; + } + return decoded; +} diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.h new file mode 100644 index 0000000000..4320cfed4e --- /dev/null +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _TVG_SVG_UTIL_H_ +#define _TVG_SVG_UTIL_H_ + +#include "tvgCommon.h" + +float svgUtilStrtof(const char *nPtr, char **endPtr); + +string svgUtilURLDecode(const char *src); +string svgUtilBase64Decode(const char *src); + +#endif //_TVG_SVG_UTIL_H_ diff --git a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp new file mode 100644 index 0000000000..2e3d5928d9 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp @@ -0,0 +1,527 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <ctype.h> +#include <string> + +#ifdef _WIN32 + #include <malloc.h> +#else + #include <alloca.h> +#endif + +#include "tvgXmlParser.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +bool _isIgnoreUnsupportedLogAttributes(TVG_UNUSED const char* tagAttribute, TVG_UNUSED const char* tagValue) +{ +#ifdef THORVG_LOG_ENABLED + const auto attributesNum = 6; + const struct + { + const char* tag; + bool tagWildcard; //If true, it is assumed that a wildcard is used after the tag. (ex: tagName*) + const char* value; + } attributes[] = { + {"id", false, nullptr}, + {"data-name", false, nullptr}, + {"overflow", false, "visible"}, + {"version", false, nullptr}, + {"xmlns", true, nullptr}, + {"xml:space", false, nullptr}, + }; + + for (unsigned int i = 0; i < attributesNum; ++i) { + if (!strncmp(tagAttribute, attributes[i].tag, attributes[i].tagWildcard ? strlen(attributes[i].tag) : strlen(tagAttribute))) { + if (attributes[i].value && tagValue) { + if (!strncmp(tagValue, attributes[i].value, strlen(tagValue))) { + return true; + } else continue; + } + return true; + } + } + return false; +#endif + return true; +} + + +static const char* _simpleXmlFindWhiteSpace(const char* itr, const char* itrEnd) +{ + for (; itr < itrEnd; itr++) { + if (isspace((unsigned char)*itr)) break; + } + return itr; +} + + +static const char* _simpleXmlSkipWhiteSpace(const char* itr, const char* itrEnd) +{ + for (; itr < itrEnd; itr++) { + if (!isspace((unsigned char)*itr)) break; + } + return itr; +} + + +static const char* _simpleXmlUnskipWhiteSpace(const char* itr, const char* itrStart) +{ + for (itr--; itr > itrStart; itr--) { + if (!isspace((unsigned char)*itr)) break; + } + return itr + 1; +} + + +static const char* _simpleXmlSkipXmlEntities(const char* itr, const char* itrEnd) +{ + auto p = itr; + while (itr < itrEnd && *itr == '&') { + for (int i = 0; i < NUMBER_OF_XML_ENTITIES; ++i) { + if (strncmp(itr, xmlEntity[i], xmlEntityLength[i]) == 0) { + itr += xmlEntityLength[i]; + break; + } + } + if (itr == p) break; + p = itr; + } + return itr; +} + + +static const char* _simpleXmlUnskipXmlEntities(const char* itr, const char* itrStart) +{ + auto p = itr; + while (itr > itrStart && *(itr - 1) == ';') { + for (int i = 0; i < NUMBER_OF_XML_ENTITIES; ++i) { + if (itr - xmlEntityLength[i] > itrStart && + strncmp(itr - xmlEntityLength[i], xmlEntity[i], xmlEntityLength[i]) == 0) { + itr -= xmlEntityLength[i]; + break; + } + } + if (itr == p) break; + p = itr; + } + return itr; +} + + +static const char* _skipWhiteSpacesAndXmlEntities(const char* itr, const char* itrEnd) +{ + itr = _simpleXmlSkipWhiteSpace(itr, itrEnd); + auto p = itr; + while (true) { + if (p != (itr = _simpleXmlSkipXmlEntities(itr, itrEnd))) p = itr; + else break; + if (p != (itr = _simpleXmlSkipWhiteSpace(itr, itrEnd))) p = itr; + else break; + } + return itr; +} + + +static const char* _unskipWhiteSpacesAndXmlEntities(const char* itr, const char* itrStart) +{ + itr = _simpleXmlUnskipWhiteSpace(itr, itrStart); + auto p = itr; + while (true) { + if (p != (itr = _simpleXmlUnskipXmlEntities(itr, itrStart))) p = itr; + else break; + if (p != (itr = _simpleXmlUnskipWhiteSpace(itr, itrStart))) p = itr; + else break; + } + return itr; +} + + +static const char* _simpleXmlFindStartTag(const char* itr, const char* itrEnd) +{ + return (const char*)memchr(itr, '<', itrEnd - itr); +} + + +static const char* _simpleXmlFindEndTag(const char* itr, const char* itrEnd) +{ + bool insideQuote = false; + for (; itr < itrEnd; itr++) { + if (*itr == '"') insideQuote = !insideQuote; + if (!insideQuote) { + if ((*itr == '>') || (*itr == '<')) + return itr; + } + } + return nullptr; +} + + +static const char* _simpleXmlFindEndCommentTag(const char* itr, const char* itrEnd) +{ + for (; itr < itrEnd; itr++) { + if ((*itr == '-') && ((itr + 1 < itrEnd) && (*(itr + 1) == '-')) && ((itr + 2 < itrEnd) && (*(itr + 2) == '>'))) return itr + 2; + } + return nullptr; +} + + +static const char* _simpleXmlFindEndCdataTag(const char* itr, const char* itrEnd) +{ + for (; itr < itrEnd; itr++) { + if ((*itr == ']') && ((itr + 1 < itrEnd) && (*(itr + 1) == ']')) && ((itr + 2 < itrEnd) && (*(itr + 2) == '>'))) return itr + 2; + } + return nullptr; +} + + +static const char* _simpleXmlFindDoctypeChildEndTag(const char* itr, const char* itrEnd) +{ + for (; itr < itrEnd; itr++) { + if (*itr == '>') return itr; + } + return nullptr; +} + + +static SimpleXMLType _getXMLType(const char* itr, const char* itrEnd, size_t &toff) +{ + toff = 0; + if (itr[1] == '/') { + toff = 1; + return SimpleXMLType::Close; + } else if (itr[1] == '?') { + toff = 1; + return SimpleXMLType::Processing; + } else if (itr[1] == '!') { + if ((itr + sizeof("<!DOCTYPE>") - 1 < itrEnd) && (!memcmp(itr + 2, "DOCTYPE", sizeof("DOCTYPE") - 1)) && ((itr[2 + sizeof("DOCTYPE") - 1] == '>') || (isspace((unsigned char)itr[2 + sizeof("DOCTYPE") - 1])))) { + toff = sizeof("!DOCTYPE") - 1; + return SimpleXMLType::Doctype; + } else if (itr + sizeof("<!>") - 1 < itrEnd) { + toff = sizeof("!") - 1; + return SimpleXMLType::DoctypeChild; + } else if ((itr + sizeof("<![CDATA[]]>") - 1 < itrEnd) && (!memcmp(itr + 2, "[CDATA[", sizeof("[CDATA[") - 1))) { + toff = sizeof("![CDATA[") - 1; + return SimpleXMLType::CData; + } else if ((itr + sizeof("<!---->") - 1 < itrEnd) && (!memcmp(itr + 2, "--", sizeof("--") - 1))) { + toff = sizeof("!--") - 1; + return SimpleXMLType::Comment; + } + return SimpleXMLType::Open; + } + return SimpleXMLType::Open; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +const char* simpleXmlNodeTypeToString(TVG_UNUSED SvgNodeType type) +{ +#ifdef THORVG_LOG_ENABLED + static const char* TYPE_NAMES[] = { + "Svg", + "G", + "Defs", + "Animation", + "Arc", + "Circle", + "Ellipse", + "Image", + "Line", + "Path", + "Polygon", + "Polyline", + "Rect", + "Text", + "TextArea", + "Tspan", + "Use", + "Video", + "ClipPath", + "Mask", + "Unknown", + }; + return TYPE_NAMES[(int) type]; +#endif + return nullptr; +} + + +bool isIgnoreUnsupportedLogElements(TVG_UNUSED const char* tagName) +{ +#ifdef THORVG_LOG_ENABLED + const auto elementsNum = 1; + const char* const elements[] = { "title" }; + + for (unsigned int i = 0; i < elementsNum; ++i) { + if (!strncmp(tagName, elements[i], strlen(tagName))) { + return true; + } + } + return false; +#else + return true; +#endif +} + + +bool simpleXmlParseAttributes(const char* buf, unsigned bufLength, simpleXMLAttributeCb func, const void* data) +{ + const char *itr = buf, *itrEnd = buf + bufLength; + char* tmpBuf = (char*)alloca(bufLength + 1); + + if (!buf || !func) return false; + + while (itr < itrEnd) { + const char* p = _skipWhiteSpacesAndXmlEntities(itr, itrEnd); + const char *key, *keyEnd, *value, *valueEnd; + char* tval; + + if (p == itrEnd) return true; + + key = p; + for (keyEnd = key; keyEnd < itrEnd; keyEnd++) { + if ((*keyEnd == '=') || (isspace((unsigned char)*keyEnd))) break; + } + if (keyEnd == itrEnd) return false; + if (keyEnd == key) continue; + + if (*keyEnd == '=') value = keyEnd + 1; + else { + value = (const char*)memchr(keyEnd, '=', itrEnd - keyEnd); + if (!value) return false; + value++; + } + keyEnd = _simpleXmlUnskipXmlEntities(keyEnd, key); + + value = _skipWhiteSpacesAndXmlEntities(value, itrEnd); + if (value == itrEnd) return false; + + if ((*value == '"') || (*value == '\'')) { + valueEnd = (const char*)memchr(value + 1, *value, itrEnd - value); + if (!valueEnd) return false; + value++; + } else { + valueEnd = _simpleXmlFindWhiteSpace(value, itrEnd); + } + + itr = valueEnd + 1; + + value = _skipWhiteSpacesAndXmlEntities(value, itrEnd); + valueEnd = _unskipWhiteSpacesAndXmlEntities(valueEnd, value); + + memcpy(tmpBuf, key, keyEnd - key); + tmpBuf[keyEnd - key] = '\0'; + + tval = tmpBuf + (keyEnd - key) + 1; + int i = 0; + while (value < valueEnd) { + value = _simpleXmlSkipXmlEntities(value, valueEnd); + tval[i++] = *value; + value++; + } + tval[i] = '\0'; + + if (!func((void*)data, tmpBuf, tval)) { + if (!_isIgnoreUnsupportedLogAttributes(tmpBuf, tval)) { + TVGLOG("SVG", "Unsupported attributes used [Elements type: %s][Id : %s][Attribute: %s][Value: %s]", simpleXmlNodeTypeToString(((SvgLoaderData*)data)->svgParse->node->type), ((SvgLoaderData*)data)->svgParse->node->id ? ((SvgLoaderData*)data)->svgParse->node->id : "NO_ID", tmpBuf, tval ? tval : "NONE"); + } + } + } + return true; +} + + +bool simpleXmlParse(const char* buf, unsigned bufLength, bool strip, simpleXMLCb func, const void* data) +{ + const char *itr = buf, *itrEnd = buf + bufLength; + + if (!buf || !func) return false; + + while (itr < itrEnd) { + if (itr[0] == '<') { + //Invalid case + if (itr + 1 >= itrEnd) return false; + + size_t toff = 0; + SimpleXMLType type = _getXMLType(itr, itrEnd, toff); + + const char* p; + if (type == SimpleXMLType::CData) p = _simpleXmlFindEndCdataTag(itr + 1 + toff, itrEnd); + else if (type == SimpleXMLType::DoctypeChild) p = _simpleXmlFindDoctypeChildEndTag(itr + 1 + toff, itrEnd); + else if (type == SimpleXMLType::Comment) p = _simpleXmlFindEndCommentTag(itr + 1 + toff, itrEnd); + else p = _simpleXmlFindEndTag(itr + 1 + toff, itrEnd); + + if (p) { + //Invalid case: '<' nested + if (*p == '<') return false; + const char *start, *end; + + start = itr + 1 + toff; + end = p; + + switch (type) { + case SimpleXMLType::Open: { + if (p[-1] == '/') { + type = SimpleXMLType::OpenEmpty; + end--; + } + break; + } + case SimpleXMLType::CData: { + if (!memcmp(p - 2, "]]", 2)) end -= 2; + break; + } + case SimpleXMLType::Processing: { + if (p[-1] == '?') end--; + break; + } + case SimpleXMLType::Comment: { + if (!memcmp(p - 2, "--", 2)) end -= 2; + break; + } + default: { + break; + } + } + + if (strip && (type != SimpleXMLType::CData)) { + start = _skipWhiteSpacesAndXmlEntities(start, end); + end = _unskipWhiteSpacesAndXmlEntities(end, start); + } + + if (!func((void*)data, type, start, (unsigned int)(end - start))) return false; + + itr = p + 1; + } else { + return false; + } + } else { + const char *p, *end; + + if (strip) { + p = itr; + p = _skipWhiteSpacesAndXmlEntities(p, itrEnd); + if (p) { + if (!func((void*)data, SimpleXMLType::Ignored, itr, (unsigned int)(p - itr))) return false; + itr = p; + } + } + + p = _simpleXmlFindStartTag(itr, itrEnd); + if (!p) p = itrEnd; + + end = p; + if (strip) end = _unskipWhiteSpacesAndXmlEntities(end, itr); + + if (itr != end && !func((void*)data, SimpleXMLType::Data, itr, (unsigned int)(end - itr))) return false; + + if (strip && (end < p) && !func((void*)data, SimpleXMLType::Ignored, end, (unsigned int)(p - end))) return false; + + itr = p; + } + } + return true; +} + + +bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLAttributeCb func, const void* data) +{ + const char* end; + char* key; + char* val; + char* next; + + if (!buf) return false; + + end = buf + strlen(buf); + key = (char*)alloca(end - buf + 1); + val = (char*)alloca(end - buf + 1); + + if (buf == end) return true; + + do { + char* sep = (char*)strchr(buf, ':'); + next = (char*)strchr(buf, ';'); + + key[0] = '\0'; + val[0] = '\0'; + + if (next == nullptr && sep != nullptr) { + memcpy(key, buf, sep - buf); + key[sep - buf] = '\0'; + + memcpy(val, sep + 1, end - sep - 1); + val[end - sep - 1] = '\0'; + } else if (sep < next && sep != nullptr) { + memcpy(key, buf, sep - buf); + key[sep - buf] = '\0'; + + memcpy(val, sep + 1, next - sep - 1); + val[next - sep - 1] = '\0'; + } else if (next) { + memcpy(key, buf, next - buf); + key[next - buf] = '\0'; + } + + if (key[0]) { + key = const_cast<char*>(_simpleXmlSkipWhiteSpace(key, key + strlen(key))); + key[_simpleXmlUnskipWhiteSpace(key + strlen(key) , key) - key] = '\0'; + val = const_cast<char*>(_simpleXmlSkipWhiteSpace(val, val + strlen(val))); + val[_simpleXmlUnskipWhiteSpace(val + strlen(val) , val) - val] = '\0'; + + if (!func((void*)data, key, val)) { + if (!_isIgnoreUnsupportedLogAttributes(key, val)) { + TVGLOG("SVG", "Unsupported attributes used [Elements type: %s][Id : %s][Attribute: %s][Value: %s]", simpleXmlNodeTypeToString(((SvgLoaderData*)data)->svgParse->node->type), ((SvgLoaderData*)data)->svgParse->node->id ? ((SvgLoaderData*)data)->svgParse->node->id : "NO_ID", key, val ? val : "NONE"); + } + } + } + + buf = next + 1; + } while (next != nullptr); + + return true; +} + + +const char* simpleXmlFindAttributesTag(const char* buf, unsigned bufLength) +{ + const char *itr = buf, *itrEnd = buf + bufLength; + + for (; itr < itrEnd; itr++) { + if (!isspace((unsigned char)*itr)) { + //User skip tagname and already gave it the attributes. + if (*itr == '=') return buf; + } else { + itr = _simpleXmlUnskipXmlEntities(itr, buf); + if (itr == itrEnd) return nullptr; + return itr; + } + } + + return nullptr; +} diff --git a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h new file mode 100644 index 0000000000..d96a631528 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _TVG_SIMPLE_XML_PARSER_H_ +#define _TVG_SIMPLE_XML_PARSER_H_ + +#include "tvgSvgLoaderCommon.h" + +#define NUMBER_OF_XML_ENTITIES 8 +const char* const xmlEntity[] = {""", " ", "'", "&", "<", ">", "#", "'"}; +const int xmlEntityLength[] = {6, 6, 6, 5, 4, 4, 6, 6}; + +enum class SimpleXMLType +{ + Open = 0, //!< \<tag attribute="value"\> + OpenEmpty, //!< \<tag attribute="value" /\> + Close, //!< \</tag\> + Data, //!< tag text data + CData, //!< \<![cdata[something]]\> + Error, //!< error contents + Processing, //!< \<?xml ... ?\> \<?php .. ?\> + Doctype, //!< \<!doctype html + Comment, //!< \<!-- something --\> + Ignored, //!< whatever is ignored by parser, like whitespace + DoctypeChild //!< \<!doctype_child +}; + +typedef bool (*simpleXMLCb)(void* data, SimpleXMLType type, const char* content, unsigned int length); +typedef bool (*simpleXMLAttributeCb)(void* data, const char* key, const char* value); + +bool simpleXmlParseAttributes(const char* buf, unsigned buflen, simpleXMLAttributeCb func, const void* data); +bool simpleXmlParse(const char* buf, unsigned buflen, bool strip, simpleXMLCb func, const void* data); +bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLAttributeCb func, const void* data); +const char *simpleXmlFindAttributesTag(const char* buf, unsigned buflen); +bool isIgnoreUnsupportedLogElements(const char* tagName); +const char* simpleXmlNodeTypeToString(SvgNodeType type); + +#endif //_TVG_SIMPLE_XML_PARSER_H_ diff --git a/thirdparty/thorvg/src/loaders/tvg/tvgTvgBinInterpreter.cpp b/thirdparty/thorvg/src/loaders/tvg/tvgTvgBinInterpreter.cpp new file mode 100644 index 0000000000..b0364b1055 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/tvg/tvgTvgBinInterpreter.cpp @@ -0,0 +1,450 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include <memory.h> + +#ifdef _WIN32 + #include <malloc.h> +#else + #include <alloca.h> +#endif + +#include "tvgTvgCommon.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct TvgBinBlock +{ + TvgBinTag type; + TvgBinCounter length; + const char* data; + const char* end; +}; + +static Paint* _parsePaint(TvgBinBlock baseBlock); + + +static TvgBinBlock _readBlock(const char *ptr) +{ + TvgBinBlock block; + block.type = *ptr; + READ_UI32(&block.length, ptr + SIZE(TvgBinTag)); + block.data = ptr + SIZE(TvgBinTag) + SIZE(TvgBinCounter); + block.end = block.data + block.length; + return block; +} + + +static bool _parseCmpTarget(const char *ptr, const char *end, Paint *paint) +{ + auto block = _readBlock(ptr); + if (block.end > end) return false; + + if (block.type != TVG_TAG_PAINT_CMP_METHOD) return false; + if (block.length != SIZE(TvgBinFlag)) return false; + + auto cmpMethod = static_cast<CompositeMethod>(*block.data); + + ptr = block.end; + + auto cmpBlock = _readBlock(ptr); + if (cmpBlock.end > end) return false; + + paint->composite(unique_ptr<Paint>(_parsePaint(cmpBlock)), cmpMethod); + + return true; +} + + +static bool _parsePaintProperty(TvgBinBlock block, Paint *paint) +{ + switch (block.type) { + case TVG_TAG_PAINT_OPACITY: { + if (block.length != SIZE(uint8_t)) return false; + paint->opacity(*block.data); + return true; + } + case TVG_TAG_PAINT_TRANSFORM: { + if (block.length != SIZE(Matrix)) return false; + Matrix matrix; + memcpy(&matrix, block.data, SIZE(Matrix)); + paint->transform(matrix); + return true; + } + case TVG_TAG_PAINT_CMP_TARGET: { + if (block.length < SIZE(TvgBinTag) + SIZE(TvgBinCounter)) return false; + return _parseCmpTarget(block.data, block.end, paint); + } + } + return false; +} + + +static bool _parseScene(TvgBinBlock block, Paint *paint) +{ + auto scene = static_cast<Scene*>(paint); + + //Case1: scene reserve count + if (block.type == TVG_TAG_SCENE_RESERVEDCNT) { + if (block.length != SIZE(uint32_t)) return false; + uint32_t reservedCnt; + READ_UI32(&reservedCnt, block.data); + scene->reserve(reservedCnt); + return true; + } + + //Case2: Base Paint Properties + if (_parsePaintProperty(block, scene)) return true; + + //Case3: A Child paint + if (auto paint = _parsePaint(block)) { + scene->push(unique_ptr<Paint>(paint)); + return true; + } + + return false; +} + + +static bool _parseShapePath(const char *ptr, const char *end, Shape *shape) +{ + uint32_t cmdCnt, ptsCnt; + + READ_UI32(&cmdCnt, ptr); + ptr += SIZE(cmdCnt); + + READ_UI32(&ptsCnt, ptr); + ptr += SIZE(ptsCnt); + + auto cmds = (TvgBinFlag*) ptr; + ptr += SIZE(TvgBinFlag) * cmdCnt; + + auto pts = (Point*) ptr; + ptr += SIZE(Point) * ptsCnt; + + if (ptr > end) return false; + + /* Recover to PathCommand(4 bytes) from TvgBinFlag(1 byte) */ + PathCommand* inCmds = (PathCommand*)alloca(sizeof(PathCommand) * cmdCnt); + for (uint32_t i = 0; i < cmdCnt; ++i) { + inCmds[i] = static_cast<PathCommand>(cmds[i]); + } + + shape->appendPath(inCmds, cmdCnt, pts, ptsCnt); + + return true; +} + + +static unique_ptr<Fill> _parseShapeFill(const char *ptr, const char *end) +{ + unique_ptr<Fill> fillGrad; + + while (ptr < end) { + auto block = _readBlock(ptr); + if (block.end > end) return nullptr; + + switch (block.type) { + case TVG_TAG_FILL_RADIAL_GRADIENT: { + if (block.length != 3 * SIZE(float)) return nullptr; + + auto ptr = block.data; + float x, y, radius; + + READ_FLOAT(&x, ptr); + ptr += SIZE(float); + READ_FLOAT(&y, ptr); + ptr += SIZE(float); + READ_FLOAT(&radius, ptr); + + auto fillGradRadial = RadialGradient::gen(); + fillGradRadial->radial(x, y, radius); + fillGrad = move(fillGradRadial); + break; + } + case TVG_TAG_FILL_LINEAR_GRADIENT: { + if (block.length != 4 * SIZE(float)) return nullptr; + + auto ptr = block.data; + float x1, y1, x2, y2; + + READ_FLOAT(&x1, ptr); + ptr += SIZE(float); + READ_FLOAT(&y1, ptr); + ptr += SIZE(float); + READ_FLOAT(&x2, ptr); + ptr += SIZE(float); + READ_FLOAT(&y2, ptr); + + auto fillGradLinear = LinearGradient::gen(); + fillGradLinear->linear(x1, y1, x2, y2); + fillGrad = move(fillGradLinear); + break; + } + case TVG_TAG_FILL_FILLSPREAD: { + if (!fillGrad) return nullptr; + if (block.length != SIZE(TvgBinFlag)) return nullptr; + fillGrad->spread((FillSpread) *block.data); + break; + } + case TVG_TAG_FILL_COLORSTOPS: { + if (!fillGrad) return nullptr; + if (block.length == 0 || block.length & 0x07) return nullptr; + uint32_t stopsCnt = block.length >> 3; // 8 bytes per ColorStop + if (stopsCnt > 1023) return nullptr; + Fill::ColorStop* stops = (Fill::ColorStop*)alloca(sizeof(Fill::ColorStop) * stopsCnt); + auto p = block.data; + for (uint32_t i = 0; i < stopsCnt; i++, p += 8) { + READ_FLOAT(&stops[i].offset, p); + stops[i].r = p[4]; + stops[i].g = p[5]; + stops[i].b = p[6]; + stops[i].a = p[7]; + } + fillGrad->colorStops(stops, stopsCnt); + break; + } + case TVG_TAG_FILL_TRANSFORM: { + if (!fillGrad || block.length != SIZE(Matrix)) return nullptr; + Matrix gradTransform; + memcpy(&gradTransform, block.data, SIZE(Matrix)); + fillGrad->transform(gradTransform); + break; + } + default: { + TVGLOG("TVG", "Unsupported tag %d (0x%x) used as one of the fill properties, %d bytes skipped", block.type, block.type, block.length); + break; + } + } + ptr = block.end; + } + return fillGrad; +} + + +static bool _parseShapeStrokeDashPattern(const char *ptr, const char *end, Shape *shape) +{ + uint32_t dashPatternCnt; + READ_UI32(&dashPatternCnt, ptr); + ptr += SIZE(uint32_t); + if (dashPatternCnt > 0) { + float* dashPattern = static_cast<float*>(malloc(sizeof(float) * dashPatternCnt)); + if (!dashPattern) return false; + memcpy(dashPattern, ptr, sizeof(float) * dashPatternCnt); + ptr += SIZE(float) * dashPatternCnt; + + if (ptr > end) { + free(dashPattern); + return false; + } + + shape->stroke(dashPattern, dashPatternCnt); + free(dashPattern); + } + return true; +} + + +static bool _parseShapeStroke(const char *ptr, const char *end, Shape *shape) +{ + while (ptr < end) { + auto block = _readBlock(ptr); + if (block.end > end) return false; + + switch (block.type) { + case TVG_TAG_SHAPE_STROKE_CAP: { + if (block.length != SIZE(TvgBinFlag)) return false; + shape->stroke((StrokeCap) *block.data); + break; + } + case TVG_TAG_SHAPE_STROKE_JOIN: { + if (block.length != SIZE(TvgBinFlag)) return false; + shape->stroke((StrokeJoin) *block.data); + break; + } + case TVG_TAG_SHAPE_STROKE_WIDTH: { + if (block.length != SIZE(float)) return false; + float width; + READ_FLOAT(&width, block.data); + shape->stroke(width); + break; + } + case TVG_TAG_SHAPE_STROKE_COLOR: { + if (block.length != 4) return false; + shape->stroke(block.data[0], block.data[1], block.data[2], block.data[3]); + break; + } + case TVG_TAG_SHAPE_STROKE_FILL: { + auto fill = _parseShapeFill(block.data, block.end); + if (!fill) return false; + shape->stroke(move(move(fill))); + break; + } + case TVG_TAG_SHAPE_STROKE_DASHPTRN: { + if (!_parseShapeStrokeDashPattern(block.data, block.end, shape)) return false; + break; + } + default: { + TVGLOG("TVG", "Unsupported tag %d (0x%x) used as one of stroke properties, %d bytes skipped", block.type, block.type, block.length); + break; + } + } + ptr = block.end; + } + return true; +} + + +static bool _parseShape(TvgBinBlock block, Paint* paint) +{ + auto shape = static_cast<Shape*>(paint); + + //Case1: Shape specific properties + switch (block.type) { + case TVG_TAG_SHAPE_PATH: { + return _parseShapePath(block.data, block.end, shape); + } + case TVG_TAG_SHAPE_STROKE: { + return _parseShapeStroke(block.data, block.end, shape); + } + case TVG_TAG_SHAPE_FILL: { + auto fill = _parseShapeFill(block.data, block.end); + if (!fill) return false; + shape->fill(move(fill)); + return true; + } + case TVG_TAG_SHAPE_COLOR: { + if (block.length != 4) return false; + shape->fill(block.data[0], block.data[1], block.data[2], block.data[3]); + return true; + } + case TVG_TAG_SHAPE_FILLRULE: { + if (block.length != SIZE(TvgBinFlag)) return false; + shape->fill((FillRule)*block.data); + return true; + } + } + + //Case2: Base Paint Properties + return _parsePaintProperty(block, shape); +} + + +static bool _parsePicture(TvgBinBlock block, Paint* paint) +{ + auto picture = static_cast<Picture*>(paint); + + //Case1: Image Picture + if (block.type == TVG_TAG_PICTURE_RAW_IMAGE) { + if (block.length < 2 * SIZE(uint32_t)) return false; + + auto ptr = block.data; + uint32_t w, h; + + READ_UI32(&w, ptr); + ptr += SIZE(uint32_t); + READ_UI32(&h, ptr); + ptr += SIZE(uint32_t); + + auto size = w * h * SIZE(uint32_t); + if (block.length != 2 * SIZE(uint32_t) + size) return false; + + picture->load((uint32_t*) ptr, w, h, true); + return true; + } + + //Case2: Base Paint Properties + if (_parsePaintProperty(block, picture)) return true; + + //Vector Picture won't be requested since Saver replaces it with the Scene + return false; +} + + +static Paint* _parsePaint(TvgBinBlock baseBlock) +{ + bool (*parser)(TvgBinBlock, Paint*); + Paint *paint; + + //1. Decide the type of paint. + switch (baseBlock.type) { + case TVG_TAG_CLASS_SCENE: { + paint = Scene::gen().release(); + parser = _parseScene; + break; + } + case TVG_TAG_CLASS_SHAPE: { + paint = Shape::gen().release(); + parser = _parseShape; + break; + } + case TVG_TAG_CLASS_PICTURE: { + paint = Picture::gen().release(); + parser = _parsePicture; + break; + } + default: { + TVGERR("TVG", "Invalid Paint Type %d (0x%x)", baseBlock.type, baseBlock.type); + return nullptr; + } + } + + auto ptr = baseBlock.data; + + //2. Read Subsquent properties of the current paint. + while (ptr < baseBlock.end) { + auto block = _readBlock(ptr); + if (block.end > baseBlock.end) return paint; + if (!parser(block, paint)) { + TVGERR("TVG", "Encountered the wrong paint properties... Paint Class %d (0x%x)", baseBlock.type, baseBlock.type); + return paint; + } + ptr = block.end; + } + return paint; +} + + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +unique_ptr<Scene> TvgBinInterpreter::run(const char *ptr, const char* end) +{ + auto scene = Scene::gen(); + if (!scene) return nullptr; + + while (ptr < end) { + auto block = _readBlock(ptr); + if (block.end > end) { + TVGERR("TVG", "Corrupted tvg file."); + return nullptr; + } + scene->push(unique_ptr<Paint>(_parsePaint(block))); + ptr = block.end; + } + + return scene; +} diff --git a/thirdparty/thorvg/src/loaders/tvg/tvgTvgCommon.h b/thirdparty/thorvg/src/loaders/tvg/tvgTvgCommon.h new file mode 100644 index 0000000000..e7c3eba488 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/tvg/tvgTvgCommon.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _TVG_TVG_COMMON_H_ +#define _TVG_TVG_COMMON_H_ + +#include "tvgCommon.h" +#include "tvgBinaryDesc.h" + +#define SIZE(A) sizeof(A) +#define READ_UI32(dst, src) memcpy(dst, (src), sizeof(uint32_t)) +#define READ_FLOAT(dst, src) memcpy(dst, (src), sizeof(float)) + + +/* Interface for Tvg Binary Interpreter */ +class TvgBinInterpreterBase +{ +public: + virtual ~TvgBinInterpreterBase() {} + + /* ptr: points the tvg binary body (after header) + end: end of the tvg binary data */ + virtual unique_ptr<Scene> run(const char* ptr, const char* end) = 0; +}; + + +/* Version 0 */ +class TvgBinInterpreter : public TvgBinInterpreterBase +{ +public: + unique_ptr<Scene> run(const char* ptr, const char* end) override; +}; + + +#endif //_TVG_TVG_COMMON_H_
\ No newline at end of file diff --git a/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.cpp b/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.cpp new file mode 100644 index 0000000000..d7f3184435 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.cpp @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include <memory.h> +#include <fstream> +#include "tvgLoader.h" +#include "tvgTvgLoader.h" +#include "tvgLzw.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + + +void TvgLoader::clear() +{ + if (copy) free((char*)data); + ptr = data = nullptr; + size = 0; + copy = false; + + if (interpreter) { + delete(interpreter); + interpreter = nullptr; + } +} + + +/* WARNING: Header format shall not change! */ +bool TvgLoader::readHeader() +{ + if (!ptr) return false; + + //Make sure the size is large enough to hold the header + if (size < TVG_HEADER_SIZE) return false; + + //1. Signature + if (memcmp(ptr, TVG_HEADER_SIGNATURE, TVG_HEADER_SIGNATURE_LENGTH)) return false; + ptr += TVG_HEADER_SIGNATURE_LENGTH; + + //2. Version + char version[TVG_HEADER_VERSION_LENGTH + 1]; + memcpy(version, ptr, TVG_HEADER_VERSION_LENGTH); + version[TVG_HEADER_VERSION_LENGTH - 1] = '\0'; + ptr += TVG_HEADER_VERSION_LENGTH; + this->version = atoi(version); + if (this->version > THORVG_VERSION_NUMBER()) { + TVGLOG("TVG", "This TVG file expects a higher version(%d) of ThorVG symbol(%d)", this->version, THORVG_VERSION_NUMBER()); + } + + //3. View Size + READ_FLOAT(&w, ptr); + ptr += SIZE(float); + READ_FLOAT(&h, ptr); + ptr += SIZE(float); + + //4. Reserved + if (*ptr & TVG_HEAD_FLAG_COMPRESSED) compressed = true; + ptr += TVG_HEADER_RESERVED_LENGTH; + + //5. Compressed Size if any + if (compressed) { + auto p = ptr; + + //TVG_HEADER_UNCOMPRESSED_SIZE + memcpy(&uncompressedSize, p, sizeof(uint32_t)); + p += SIZE(uint32_t); + + //TVG_HEADER_COMPRESSED_SIZE + memcpy(&compressedSize, p, sizeof(uint32_t)); + p += SIZE(uint32_t); + + //TVG_HEADER_COMPRESSED_SIZE_BITS + memcpy(&compressedSizeBits, p, sizeof(uint32_t)); + } + + ptr += TVG_HEADER_COMPRESS_SIZE; + + //Decide the proper Tvg Binary Interpreter based on the current file version + if (this->version >= 0) interpreter = new TvgBinInterpreter; + + return true; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +TvgLoader::~TvgLoader() +{ + close(); +} + + +bool TvgLoader::open(const string &path) +{ + clear(); + + ifstream f; + f.open(path, ifstream::in | ifstream::binary | ifstream::ate); + + if (!f.is_open()) return false; + + size = f.tellg(); + f.seekg(0, ifstream::beg); + + copy = true; + data = (char*)malloc(size); + if (!data) { + clear(); + f.close(); + return false; + } + + if (!f.read((char*)data, size)) + { + clear(); + f.close(); + return false; + } + + f.close(); + + ptr = data; + + return readHeader(); +} + + +bool TvgLoader::open(const char *data, uint32_t size, bool copy) +{ + clear(); + + if (copy) { + this->data = (char*)malloc(size); + if (!this->data) return false; + memcpy((char*)this->data, data, size); + } else this->data = data; + + this->ptr = this->data; + this->size = size; + this->copy = copy; + + return readHeader(); +} + + +bool TvgLoader::resize(Paint* paint, float w, float h) +{ + if (!paint) return false; + + auto sx = w / this->w; + auto sy = h / this->h; + + //Scale + auto scale = sx < sy ? sx : sy; + paint->scale(scale); + + //Align + float tx = 0, ty = 0; + auto sw = this->w * scale; + auto sh = this->h * scale; + if (sw > sh) ty -= (h - sh) * 0.5f; + else tx -= (w - sw) * 0.5f; + paint->translate(-tx, -ty); + + return true; +} + + +bool TvgLoader::read() +{ + if (!ptr || size == 0) return false; + + TaskScheduler::request(this); + + return true; +} + + +bool TvgLoader::close() +{ + this->done(); + clear(); + return true; +} + + +void TvgLoader::run(unsigned tid) +{ + if (root) root.reset(); + + auto data = const_cast<char*>(ptr); + + if (compressed) { + data = (char*) lzwDecode((uint8_t*) data, compressedSize, compressedSizeBits, uncompressedSize); + root = interpreter->run(data, data + uncompressedSize); + free(data); + } else { + root = interpreter->run(data, this->data + size); + } + + if (!root) clear(); +} + + +unique_ptr<Paint> TvgLoader::paint() +{ + this->done(); + if (root) return move(root); + return nullptr; +} diff --git a/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.h b/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.h new file mode 100644 index 0000000000..d276ded33a --- /dev/null +++ b/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _TVG_TVG_LOADER_H_ +#define _TVG_TVG_LOADER_H_ + +#include "tvgTaskScheduler.h" +#include "tvgTvgCommon.h" + + +class TvgLoader : public LoadModule, public Task +{ +public: + const char* data = nullptr; + const char* ptr = nullptr; + uint32_t size = 0; + uint16_t version = 0; + unique_ptr<Scene> root = nullptr; + TvgBinInterpreterBase* interpreter = nullptr; + uint32_t uncompressedSize = 0; + uint32_t compressedSize = 0; + uint32_t compressedSizeBits = 0; + bool copy = false; + bool compressed = false; + + ~TvgLoader(); + + using LoadModule::open; + bool open(const string &path) override; + bool open(const char *data, uint32_t size, bool copy) override; + bool read() override; + bool close() override; + bool resize(Paint* paint, float w, float h) override; + unique_ptr<Paint> paint() override; + +private: + bool readHeader(); + void run(unsigned tid) override; + void clear(); +}; + +#endif //_TVG_TVG_LOADER_H_ diff --git a/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp new file mode 100644 index 0000000000..9450d80e88 --- /dev/null +++ b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp @@ -0,0 +1,773 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "tvgMath.h" +#include "tvgSaveModule.h" +#include "tvgTvgSaver.h" +#include "tvgLzw.h" + +#ifdef _WIN32 + #include <malloc.h> +#else + #include <alloca.h> +#endif + +static FILE* _fopen(const char* filename, const char* mode) +{ +#if defined(_MSC_VER) && defined(__clang__) + FILE *fp; + auto err = fopen_s(&fp, filename, mode); + if (err != 0) return nullptr; + return fp; +#else + auto fp = fopen(filename, mode); + if (!fp) return nullptr; + return fp; +#endif +} + +#define SIZE(A) sizeof(A) + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static inline TvgBinCounter SERIAL_DONE(TvgBinCounter cnt) +{ + return SIZE(TvgBinTag) + SIZE(TvgBinCounter) + cnt; +} + + +/* if the properties are identical, we can merge the shapes. */ +static bool _merge(Shape* from, Shape* to) +{ + uint8_t r, g, b, a; + uint8_t r2, g2, b2, a2; + + //fill + if (from->fill() || to->fill()) return false; + + r = g = b = a = r2 = g2 = b2 = a2 = 0; + + from->fillColor(&r, &g, &b, &a); + to->fillColor(&r2, &g2, &b2, &a2); + + if (r != r2 || g != g2 || b != b2 || a != a2) return false; + + //composition + if (from->composite(nullptr) != CompositeMethod::None) return false; + if (to->composite(nullptr) != CompositeMethod::None) return false; + + //opacity + if (from->opacity() != to->opacity()) return false; + + //transform + auto t1 = from->transform(); + auto t2 = to->transform(); + + if (!mathEqual(t1.e11, t2.e11) || !mathEqual(t1.e12, t2.e12) || !mathEqual(t1.e13, t2.e13) || + !mathEqual(t1.e21, t2.e21) || !mathEqual(t1.e22, t2.e22) || !mathEqual(t1.e23, t2.e23) || + !mathEqual(t1.e31, t2.e31) || !mathEqual(t1.e32, t2.e32) || !mathEqual(t1.e33, t2.e33)) { + return false; + } + + //stroke + r = g = b = a = r2 = g2 = b2 = a2 = 0; + + from->strokeColor(&r, &g, &b, &a); + to->strokeColor(&r2, &g2, &b2, &a2); + + if (r != r2 || g != g2 || b != b2 || a != a2) return false; + + if (fabs(from->strokeWidth() - to->strokeWidth()) > FLT_EPSILON) return false; + + //OPTIMIZE: Yet we can't merge outlining shapes unless we can support merging shapes feature. + if (from->strokeWidth() > 0 || to->strokeWidth() > 0) return false; + + if (from->strokeCap() != to->strokeCap()) return false; + if (from->strokeJoin() != to->strokeJoin()) return false; + if (from->strokeDash(nullptr) > 0 || to->strokeDash(nullptr) > 0) return false; + if (from->strokeFill() || to->strokeFill()) return false; + + //fill rule + if (from->fillRule() != to->fillRule()) return false; + + //Good, identical shapes, we can merge them. + const PathCommand* cmds = nullptr; + auto cmdCnt = from->pathCommands(&cmds); + + const Point* pts = nullptr; + auto ptsCnt = from->pathCoords(&pts); + + to->appendPath(cmds, cmdCnt, pts, ptsCnt); + + return true; +} + + +bool TvgSaver::saveEncoding(const std::string& path) +{ + if (!compress) return flushTo(path); + + //Try encoding + auto uncompressed = buffer.data + headerSize; + auto uncompressedSize = buffer.count - headerSize; + + uint32_t compressedSize, compressedSizeBits; + + auto compressed = lzwEncode(uncompressed, uncompressedSize, &compressedSize, &compressedSizeBits); + + //Failed compression. + if (!compressed) return flushTo(path); + + //Optimization is ineffective. + if (compressedSize >= uncompressedSize) { + free(compressed); + return flushTo(path); + } + + TVGLOG("TVG_SAVER", "%s, compressed: %d -> %d, saved rate: %3.2f%%", path.c_str(), uncompressedSize, compressedSize, (1 - ((float) compressedSize / (float) uncompressedSize)) * 100); + + //Update compress size in the header. + uncompressed -= (TVG_HEADER_COMPRESS_SIZE + TVG_HEADER_RESERVED_LENGTH); + + //Compression Flag + *uncompressed |= TVG_HEAD_FLAG_COMPRESSED; + uncompressed += TVG_HEADER_RESERVED_LENGTH; + + //Uncompressed Size + memcpy(uncompressed, &uncompressedSize, TVG_HEADER_UNCOMPRESSED_SIZE); + uncompressed += TVG_HEADER_UNCOMPRESSED_SIZE; + + //Comprssed Size + memcpy(uncompressed, &compressedSize, TVG_HEADER_COMPRESSED_SIZE); + uncompressed += TVG_HEADER_COMPRESSED_SIZE; + + //Compressed Size Bits + memcpy(uncompressed, &compressedSizeBits, TVG_HEADER_COMPRESSED_SIZE_BITS); + + //Good optimization, flush to file. + auto fp = _fopen(path.c_str(), "w+"); + if (!fp) goto fail; + + //write header + if (fwrite(buffer.data, SIZE(uint8_t), headerSize, fp) == 0) goto fail; + + //write compressed data + if (fwrite(compressed, SIZE(uint8_t), compressedSize, fp) == 0) goto fail; + + fclose(fp); + free(compressed); + + return true; + +fail: + if (fp) fclose(fp); + if (compressed) free(compressed); + return false; +} + + +bool TvgSaver::flushTo(const std::string& path) +{ + auto fp = _fopen(path.c_str(), "w+"); + if (!fp) return false; + + if (fwrite(buffer.data, SIZE(uint8_t), buffer.count, fp) == 0) { + fclose(fp); + return false; + } + fclose(fp); + + return true; +} + + +/* WARNING: Header format shall not changed! */ +bool TvgSaver::writeHeader() +{ + headerSize = TVG_HEADER_SIGNATURE_LENGTH + TVG_HEADER_VERSION_LENGTH + SIZE(vsize) + TVG_HEADER_RESERVED_LENGTH + TVG_HEADER_COMPRESS_SIZE; + + buffer.grow(headerSize); + + //1. Signature + auto ptr = buffer.ptr(); + memcpy(ptr, TVG_HEADER_SIGNATURE, TVG_HEADER_SIGNATURE_LENGTH); + ptr += TVG_HEADER_SIGNATURE_LENGTH; + + //2. Version + memcpy(ptr, TVG_HEADER_VERSION, TVG_HEADER_VERSION_LENGTH); + ptr += TVG_HEADER_VERSION_LENGTH; + + buffer.count += (TVG_HEADER_SIGNATURE_LENGTH + TVG_HEADER_VERSION_LENGTH); + + //3. View Size + writeData(vsize, SIZE(vsize)); + ptr += SIZE(vsize); + + //4. Reserved data + Compress size + memset(ptr, 0x00, TVG_HEADER_RESERVED_LENGTH + TVG_HEADER_COMPRESS_SIZE); + buffer.count += (TVG_HEADER_RESERVED_LENGTH + TVG_HEADER_COMPRESS_SIZE); + + return true; +} + + +void TvgSaver::writeTag(TvgBinTag tag) +{ + buffer.grow(SIZE(TvgBinTag)); + memcpy(buffer.ptr(), &tag, SIZE(TvgBinTag)); + buffer.count += SIZE(TvgBinTag); +} + + +void TvgSaver::writeCount(TvgBinCounter cnt) +{ + buffer.grow(SIZE(TvgBinCounter)); + memcpy(buffer.ptr(), &cnt, SIZE(TvgBinCounter)); + buffer.count += SIZE(TvgBinCounter); +} + + +void TvgSaver::writeReservedCount(TvgBinCounter cnt) +{ + memcpy(buffer.ptr() - cnt - SIZE(TvgBinCounter), &cnt, SIZE(TvgBinCounter)); +} + + +void TvgSaver::reserveCount() +{ + buffer.grow(SIZE(TvgBinCounter)); + buffer.count += SIZE(TvgBinCounter); +} + + +TvgBinCounter TvgSaver::writeData(const void* data, TvgBinCounter cnt) +{ + buffer.grow(cnt); + memcpy(buffer.ptr(), data, cnt); + buffer.count += cnt; + + return cnt; +} + + +TvgBinCounter TvgSaver::writeTagProperty(TvgBinTag tag, TvgBinCounter cnt, const void* data) +{ + auto growCnt = SERIAL_DONE(cnt); + + buffer.grow(growCnt); + + auto ptr = buffer.ptr(); + + *ptr = tag; + ++ptr; + + memcpy(ptr, &cnt, SIZE(TvgBinCounter)); + ptr += SIZE(TvgBinCounter); + + memcpy(ptr, data, cnt); + ptr += cnt; + + buffer.count += growCnt; + + return growCnt; +} + + +TvgBinCounter TvgSaver::writeTransform(const Matrix* transform, TvgBinTag tag) +{ + if (!mathIdentity(transform)) return writeTagProperty(tag, SIZE(Matrix), transform); + return 0; +} + + +TvgBinCounter TvgSaver::serializePaint(const Paint* paint, const Matrix* pTransform) +{ + TvgBinCounter cnt = 0; + + //opacity + auto opacity = paint->opacity(); + if (opacity < 255) { + cnt += writeTagProperty(TVG_TAG_PAINT_OPACITY, SIZE(opacity), &opacity); + } + + //composite + const Paint* cmpTarget = nullptr; + auto cmpMethod = paint->composite(&cmpTarget); + if (cmpMethod != CompositeMethod::None && cmpTarget) { + cnt += serializeComposite(cmpTarget, cmpMethod, pTransform); + } + + return cnt; +} + + +/* Propagate parents properties to the child so that we can skip saving the parent. */ +TvgBinCounter TvgSaver::serializeChild(const Paint* parent, const Paint* child, const Matrix* transform) +{ + const Paint* compTarget = nullptr; + auto compMethod = parent->composite(&compTarget); + + /* If the parent & the only child have composition, we can't skip the parent... + Or if the parent has the transform and composition, we can't skip the parent... */ + if (compMethod != CompositeMethod::None) { + if (transform || child->composite(nullptr) != CompositeMethod::None) return 0; + } + + //propagate opacity + uint32_t opacity = parent->opacity(); + + if (opacity < 255) { + uint32_t tmp = (child->opacity() * opacity); + if (tmp > 0) tmp /= 255; + const_cast<Paint*>(child)->opacity(tmp); + } + + //propagate composition + if (compTarget) const_cast<Paint*>(child)->composite(unique_ptr<Paint>(compTarget->duplicate()), compMethod); + + return serialize(child, transform); +} + + +TvgBinCounter TvgSaver::serializeScene(const Scene* scene, const Matrix* pTransform, const Matrix* cTransform) +{ + auto it = this->iterator(scene); + if (it->count() == 0) { + delete(it); + return 0; + } + + //Case - Only Child: Skip saving this scene. + if (it->count() == 1) { + auto cnt = serializeChild(scene, it->next(), cTransform); + if (cnt > 0) { + delete(it); + return cnt; + } + } + + it->begin(); + + //Case - Delegator Scene: This scene is just a delegator, we can skip this: + if (scene->composite(nullptr) == CompositeMethod::None && scene->opacity() == 255) { + auto ret = serializeChildren(it, cTransform, false); + delete(it); + return ret; + } + + //Case - Serialize Scene & its children + writeTag(TVG_TAG_CLASS_SCENE); + reserveCount(); + + auto cnt = serializeChildren(it, cTransform, true) + serializePaint(scene, pTransform); + + delete(it); + + writeReservedCount(cnt); + + return SERIAL_DONE(cnt); +} + + +TvgBinCounter TvgSaver::serializeFill(const Fill* fill, TvgBinTag tag, const Matrix* pTransform) +{ + const Fill::ColorStop* stops = nullptr; + auto stopsCnt = fill->colorStops(&stops); + if (!stops || stopsCnt == 0) return 0; + + writeTag(tag); + reserveCount(); + + TvgBinCounter cnt = 0; + + //radial fill + if (fill->identifier() == TVG_CLASS_ID_RADIAL) { + float args[3]; + static_cast<const RadialGradient*>(fill)->radial(args, args + 1, args + 2); + cnt += writeTagProperty(TVG_TAG_FILL_RADIAL_GRADIENT, SIZE(args), args); + //linear fill + } else { + float args[4]; + static_cast<const LinearGradient*>(fill)->linear(args, args + 1, args + 2, args + 3); + cnt += writeTagProperty(TVG_TAG_FILL_LINEAR_GRADIENT, SIZE(args), args); + } + + if (auto flag = static_cast<TvgBinFlag>(fill->spread())) + cnt += writeTagProperty(TVG_TAG_FILL_FILLSPREAD, SIZE(TvgBinFlag), &flag); + cnt += writeTagProperty(TVG_TAG_FILL_COLORSTOPS, stopsCnt * SIZE(Fill::ColorStop), stops); + + auto gTransform = fill->transform(); + if (pTransform) gTransform = mathMultiply(pTransform, &gTransform); + + cnt += writeTransform(&gTransform, TVG_TAG_FILL_TRANSFORM); + + writeReservedCount(cnt); + + return SERIAL_DONE(cnt); +} + + +TvgBinCounter TvgSaver::serializeStroke(const Shape* shape, const Matrix* pTransform, bool preTransform) +{ + writeTag(TVG_TAG_SHAPE_STROKE); + reserveCount(); + + //width + auto width = shape->strokeWidth(); + if (preTransform) width *= sqrtf(powf(pTransform->e11, 2.0f) + powf(pTransform->e21, 2.0f)); //we know x/y scaling factors are same. + auto cnt = writeTagProperty(TVG_TAG_SHAPE_STROKE_WIDTH, SIZE(width), &width); + + //cap + if (auto flag = static_cast<TvgBinFlag>(shape->strokeCap())) + cnt += writeTagProperty(TVG_TAG_SHAPE_STROKE_CAP, SIZE(TvgBinFlag), &flag); + + //join + if (auto flag = static_cast<TvgBinFlag>(shape->strokeJoin())) + cnt += writeTagProperty(TVG_TAG_SHAPE_STROKE_JOIN, SIZE(TvgBinFlag), &flag); + + //fill + if (auto fill = shape->strokeFill()) { + cnt += serializeFill(fill, TVG_TAG_SHAPE_STROKE_FILL, (preTransform ? pTransform : nullptr)); + } else { + uint8_t color[4] = {0, 0, 0, 0}; + shape->strokeColor(color, color + 1, color + 2, color + 3); + cnt += writeTagProperty(TVG_TAG_SHAPE_STROKE_COLOR, SIZE(color), &color); + } + + //dash + const float* dashPattern = nullptr; + auto dashCnt = shape->strokeDash(&dashPattern); + if (dashPattern && dashCnt > 0) { + TvgBinCounter dashCntSize = SIZE(dashCnt); + TvgBinCounter dashPtrnSize = dashCnt * SIZE(dashPattern[0]); + + writeTag(TVG_TAG_SHAPE_STROKE_DASHPTRN); + writeCount(dashCntSize + dashPtrnSize); + cnt += writeData(&dashCnt, dashCntSize); + cnt += writeData(dashPattern, dashPtrnSize); + cnt += SIZE(TvgBinTag) + SIZE(TvgBinCounter); + } + + writeReservedCount(cnt); + + return SERIAL_DONE(cnt); +} + + +TvgBinCounter TvgSaver::serializePath(const Shape* shape, const Matrix* transform, bool preTransform) +{ + const PathCommand* cmds = nullptr; + auto cmdCnt = shape->pathCommands(&cmds); + const Point* pts = nullptr; + auto ptsCnt = shape->pathCoords(&pts); + + if (!cmds || !pts || cmdCnt == 0 || ptsCnt == 0) return 0; + + writeTag(TVG_TAG_SHAPE_PATH); + reserveCount(); + + /* Reduce the binary size. + Convert PathCommand(4 bytes) to TvgBinFlag(1 byte) */ + TvgBinFlag* outCmds = (TvgBinFlag*)alloca(SIZE(TvgBinFlag) * cmdCnt); + for (uint32_t i = 0; i < cmdCnt; ++i) { + outCmds[i] = static_cast<TvgBinFlag>(cmds[i]); + } + + auto cnt = writeData(&cmdCnt, SIZE(cmdCnt)); + cnt += writeData(&ptsCnt, SIZE(ptsCnt)); + cnt += writeData(outCmds, SIZE(TvgBinFlag) * cmdCnt); + + //transform? + if (preTransform) { + if (!mathEqual(transform->e11, 1.0f) || !mathZero(transform->e12) || !mathZero(transform->e13) || + !mathZero(transform->e21) || !mathEqual(transform->e22, 1.0f) || !mathZero(transform->e23) || + !mathZero(transform->e31) || !mathZero(transform->e32) || !mathEqual(transform->e33, 1.0f)) { + auto p = const_cast<Point*>(pts); + for (uint32_t i = 0; i < ptsCnt; ++i) mathMultiply(p++, transform); + } + } + + cnt += writeData(pts, ptsCnt * SIZE(pts[0])); + + writeReservedCount(cnt); + + return SERIAL_DONE(cnt); +} + + +TvgBinCounter TvgSaver::serializeShape(const Shape* shape, const Matrix* pTransform, const Matrix* cTransform) +{ + writeTag(TVG_TAG_CLASS_SHAPE); + reserveCount(); + TvgBinCounter cnt = 0; + + //fill rule + if (auto flag = static_cast<TvgBinFlag>(shape->fillRule())) { + cnt = writeTagProperty(TVG_TAG_SHAPE_FILLRULE, SIZE(TvgBinFlag), &flag); + } + + //the pre-transformation can't be applied in the case when the stroke is dashed or irregulary scaled + bool preTransform = true; + + //stroke + if (shape->strokeWidth() > 0) { + uint8_t color[4] = {0, 0, 0, 0}; + shape->strokeColor(color, color + 1, color + 2, color + 3); + auto fill = shape->strokeFill(); + if (fill || color[3] > 0) { + if (!mathEqual(cTransform->e11, cTransform->e22) || (mathZero(cTransform->e11) && !mathEqual(cTransform->e12, cTransform->e21)) || shape->strokeDash(nullptr) > 0) preTransform = false; + cnt += serializeStroke(shape, cTransform, preTransform); + } + } + + //fill + if (auto fill = shape->fill()) { + cnt += serializeFill(fill, TVG_TAG_SHAPE_FILL, (preTransform ? cTransform : nullptr)); + } else { + uint8_t color[4] = {0, 0, 0, 0}; + shape->fillColor(color, color + 1, color + 2, color + 3); + if (color[3] > 0) cnt += writeTagProperty(TVG_TAG_SHAPE_COLOR, SIZE(color), color); + } + + cnt += serializePath(shape, cTransform, preTransform); + + if (!preTransform) cnt += writeTransform(cTransform, TVG_TAG_PAINT_TRANSFORM); + cnt += serializePaint(shape, pTransform); + + writeReservedCount(cnt); + + return SERIAL_DONE(cnt); +} + + +/* Picture has either a vector scene or a bitmap. */ +TvgBinCounter TvgSaver::serializePicture(const Picture* picture, const Matrix* pTransform, const Matrix* cTransform) +{ + auto it = this->iterator(picture); + + //Case - Vector Scene: + if (it->count() == 1) { + auto cnt = serializeChild(picture, it->next(), cTransform); + //Only child, Skip to save Picture... + if (cnt > 0) { + delete(it); + return cnt; + /* Unfortunately, we can't skip the Picture because it might have a compositor, + Serialize Scene(instead of the Picture) & its scene. */ + } else { + writeTag(TVG_TAG_CLASS_SCENE); + reserveCount(); + auto cnt = serializeChildren(it, cTransform, true) + serializePaint(picture, pTransform); + writeReservedCount(cnt); + delete(it); + return SERIAL_DONE(cnt); + } + } + delete(it); + + //Case - Bitmap Image: + uint32_t w, h; + auto pixels = picture->data(&w, &h); + if (!pixels) return 0; + + writeTag(TVG_TAG_CLASS_PICTURE); + reserveCount(); + + TvgBinCounter cnt = 0; + TvgBinCounter sizeCnt = SIZE(w); + TvgBinCounter imgSize = w * h * SIZE(pixels[0]); + + writeTag(TVG_TAG_PICTURE_RAW_IMAGE); + writeCount(2 * sizeCnt + imgSize); + + cnt += writeData(&w, sizeCnt); + cnt += writeData(&h, sizeCnt); + cnt += writeData(pixels, imgSize); + cnt += SIZE(TvgBinTag) + SIZE(TvgBinCounter); + + //Bitmap picture needs the transform info. + cnt += writeTransform(cTransform, TVG_TAG_PAINT_TRANSFORM); + + cnt += serializePaint(picture, pTransform); + + writeReservedCount(cnt); + + return SERIAL_DONE(cnt); +} + + +TvgBinCounter TvgSaver::serializeComposite(const Paint* cmpTarget, CompositeMethod cmpMethod, const Matrix* pTransform) +{ + writeTag(TVG_TAG_PAINT_CMP_TARGET); + reserveCount(); + + auto flag = static_cast<TvgBinFlag>(cmpMethod); + auto cnt = writeTagProperty(TVG_TAG_PAINT_CMP_METHOD, SIZE(TvgBinFlag), &flag); + + cnt += serialize(cmpTarget, pTransform, true); + + writeReservedCount(cnt); + + return SERIAL_DONE(cnt); +} + + +TvgBinCounter TvgSaver::serializeChildren(Iterator* it, const Matrix* pTransform, bool reserved) +{ + TvgBinCounter cnt = 0; + + //Merging shapes. the result is written in the children. + Array<const Paint*> children; + children.reserve(it->count()); + children.push(it->next()); + + while (auto child = it->next()) { + if (child->identifier() == TVG_CLASS_ID_SHAPE) { + //only dosable if the previous child is a shape. + auto target = children.ptr() - 1; + if ((*target)->identifier() == TVG_CLASS_ID_SHAPE) { + if (_merge((Shape*)child, (Shape*)*target)) { + continue; + } + } + } + children.push(child); + } + + //The children of a reserved scene + if (reserved && children.count > 1) { + cnt += writeTagProperty(TVG_TAG_SCENE_RESERVEDCNT, SIZE(children.count), &children.count); + } + + //Serialize merged children. + auto child = children.data; + for (uint32_t i = 0; i < children.count; ++i, ++child) { + cnt += serialize(*child, pTransform); + } + + return cnt; +} + + +TvgBinCounter TvgSaver::serialize(const Paint* paint, const Matrix* pTransform, bool compTarget) +{ + if (!paint) return 0; + + //Invisible paint, no point to save it if the paint is not the composition target... + if (!compTarget && paint->opacity() == 0) return 0; + + auto transform = const_cast<Paint*>(paint)->transform(); + if (pTransform) transform = mathMultiply(pTransform, &transform); + + switch (paint->identifier()) { + case TVG_CLASS_ID_SHAPE: return serializeShape(static_cast<const Shape*>(paint), pTransform, &transform); + case TVG_CLASS_ID_SCENE: return serializeScene(static_cast<const Scene*>(paint), pTransform, &transform); + case TVG_CLASS_ID_PICTURE: return serializePicture(static_cast<const Picture*>(paint), pTransform, &transform); + } + + return 0; +} + + +void TvgSaver::run(unsigned tid) +{ + if (!writeHeader()) return; + + //Serialize Root Paint, without its transform. + Matrix transform = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + + if (paint->opacity() > 0) { + switch (paint->identifier()) { + case TVG_CLASS_ID_SHAPE: { + serializeShape(static_cast<const Shape*>(paint), nullptr, &transform); + break; + } + case TVG_CLASS_ID_SCENE: { + serializeScene(static_cast<const Scene*>(paint), nullptr, &transform); + break; + } + case TVG_CLASS_ID_PICTURE: { + serializePicture(static_cast<const Picture*>(paint), nullptr, &transform); + break; + } + } + } + + if (!saveEncoding(path)) return; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +TvgSaver::~TvgSaver() +{ + close(); +} + + +bool TvgSaver::close() +{ + this->done(); + + if (paint) { + delete(paint); + paint = nullptr; + } + if (path) { + free(path); + path = nullptr; + } + buffer.reset(); + return true; +} + + +bool TvgSaver::save(Paint* paint, const string& path, bool compress) +{ + close(); + + float x, y; + x = y = 0; + paint->bounds(&x, &y, &vsize[0], &vsize[1], false); + + //cut off the negative space + if (x < 0) vsize[0] += x; + if (y < 0) vsize[1] += y; + + if (vsize[0] < FLT_EPSILON || vsize[1] < FLT_EPSILON) { + TVGLOG("TVG_SAVER", "Saving paint(%p) has zero view size.", paint); + return false; + } + + this->path = strdup(path.c_str()); + if (!this->path) return false; + + this->paint = paint; + this->compress = compress; + + TaskScheduler::request(this); + + return true; +} diff --git a/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.h b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.h new file mode 100644 index 0000000000..27186b5d4a --- /dev/null +++ b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_TVGSAVER_H_ +#define _TVG_TVGSAVER_H_ + +#include "tvgArray.h" +#include "tvgBinaryDesc.h" +#include "tvgTaskScheduler.h" + +namespace tvg +{ + +class TvgSaver : public SaveModule, public Task +{ +private: + Array<TvgBinByte> buffer; + Paint* paint = nullptr; + char *path = nullptr; + uint32_t headerSize; + float vsize[2] = {0.0f, 0.0f}; + bool compress; + + bool flushTo(const std::string& path); + bool saveEncoding(const std::string& path); + void reserveCount(); + + bool writeHeader(); + bool writeViewSize(); + void writeTag(TvgBinTag tag); + void writeCount(TvgBinCounter cnt); + void writeReservedCount(TvgBinCounter cnt); + TvgBinCounter writeData(const void* data, TvgBinCounter cnt); + TvgBinCounter writeTagProperty(TvgBinTag tag, TvgBinCounter cnt, const void* data); + TvgBinCounter writeTransform(const Matrix* transform, TvgBinTag tag); + + TvgBinCounter serialize(const Paint* paint, const Matrix* pTransform, bool compTarget = false); + TvgBinCounter serializeScene(const Scene* scene, const Matrix* pTransform, const Matrix* cTransform); + TvgBinCounter serializeShape(const Shape* shape, const Matrix* pTransform, const Matrix* cTransform); + TvgBinCounter serializePicture(const Picture* picture, const Matrix* pTransform, const Matrix* cTransform); + TvgBinCounter serializePaint(const Paint* paint, const Matrix* pTransform); + TvgBinCounter serializeFill(const Fill* fill, TvgBinTag tag, const Matrix* pTransform); + TvgBinCounter serializeStroke(const Shape* shape, const Matrix* pTransform, bool preTransform); + TvgBinCounter serializePath(const Shape* shape, const Matrix* transform, bool preTransform); + TvgBinCounter serializeComposite(const Paint* cmpTarget, CompositeMethod cmpMethod, const Matrix* pTransform); + TvgBinCounter serializeChildren(Iterator* it, const Matrix* transform, bool reserved); + TvgBinCounter serializeChild(const Paint* parent, const Paint* child, const Matrix* pTransform); + +public: + ~TvgSaver(); + + bool save(Paint* paint, const string& path, bool compress) override; + bool close() override; + void run(unsigned tid) override; +}; + +} + +#endif //_TVG_SAVE_MODULE_H_ diff --git a/thirdparty/thorvg/update-thorvg.sh b/thirdparty/thorvg/update-thorvg.sh new file mode 100755 index 0000000000..c200131eba --- /dev/null +++ b/thirdparty/thorvg/update-thorvg.sh @@ -0,0 +1,28 @@ +VERSION=0.7.0 +rm -rf AUTHORS inc LICENSE src *.zip +curl -L -O https://github.com/Samsung/thorvg/archive/refs/tags/v$VERSION.zip +bsdtar --strip-components=1 -xvf *.zip +rm *.zip +rm -rf .github docs pc res test tools .git* *.md *.txt wasm_build.sh +find . -type f -name 'meson.build' -delete +rm -rf src/bin src/bindings src/examples src/wasm +rm -rf src/lib/gl_engine tvgcompat +cat << EOF > inc/config.h +#ifndef THORVG_CONFIG_H +#define THORVG_CONFIG_H + +#define THORVG_SW_RASTER_SUPPORT 1 + +#define THORVG_SVG_LOADER_SUPPORT 1 + +#define THORVG_PNG_LOADER_SUPPORT 1 + +#define THORVG_TVG_LOADER_SUPPORT 1 + +#define THORVG_TVG_SAVER_SUPPORT 1 + +#define THORVG_JPG_LOADER_SUPPORT 1 + +#define THORVG_VERSION_STRING "$VERSION" +#endif +EOF |