diff options
145 files changed, 1153 insertions, 480 deletions
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index df1ab0c849..7f6c9b3dc0 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -399,7 +399,7 @@ License: Expat Files: ./thirdparty/thorvg/ Comment: ThorVG -Copyright: 2020-2021, Samsung Electronics Co., Ltd. +Copyright: 2020-2022, Samsung Electronics Co., Ltd. License: Expat Files: ./thirdparty/tinyexr/ diff --git a/doc/classes/AspectRatioContainer.xml b/doc/classes/AspectRatioContainer.xml index 41e06e6e98..742a7276d4 100644 --- a/doc/classes/AspectRatioContainer.xml +++ b/doc/classes/AspectRatioContainer.xml @@ -34,7 +34,7 @@ </constant> <constant name="STRETCH_COVER" value="3" enum="StretchMode"> The width and height of child controls is automatically adjusted to make their bounding rectangle cover the entire area of the container while keeping the aspect ratio. - When the bounding rectangle of child controls exceed the container's size and [member Control.rect_clip_content] is enabled, this allows to show only the container's area restricted by its own bounding rectangle. + When the bounding rectangle of child controls exceed the container's size and [member Control.clip_contents] is enabled, this allows to show only the container's area restricted by its own bounding rectangle. </constant> <constant name="ALIGNMENT_BEGIN" value="0" enum="AlignmentMode"> Aligns child controls with the beginning (left or top) of the container. diff --git a/doc/classes/ColorPickerButton.xml b/doc/classes/ColorPickerButton.xml index e2f1fdfae1..f5e752578e 100644 --- a/doc/classes/ColorPickerButton.xml +++ b/doc/classes/ColorPickerButton.xml @@ -6,7 +6,7 @@ <description> Encapsulates a [ColorPicker] making it accessible by pressing a button. Pressing the button will toggle the [ColorPicker] visibility. See also [BaseButton] which contains common properties and methods associated with this node. - [b]Note:[/b] By default, the button may not be wide enough for the color preview swatch to be visible. Make sure to set [member Control.rect_min_size] to a big enough value to give the button enough space. + [b]Note:[/b] By default, the button may not be wide enough for the color preview swatch to be visible. Make sure to set [member Control.minimum_size] to a big enough value to give the button enough space. </description> <tutorials> <link title="GUI Drag And Drop Demo">https://godotengine.org/asset-library/asset/133</link> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index cecc8f658d..97fd584ed1 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -100,7 +100,7 @@ <method name="_get_minimum_size" qualifiers="virtual const"> <return type="Vector2" /> <description> - Virtual method to be implemented by the user. Returns the minimum size for this control. Alternative to [member rect_min_size] for controlling minimum size via code. The actual minimum size will be the max value of these two (in each axis separately). + Virtual method to be implemented by the user. Returns the minimum size for this control. Alternative to [member minimum_size] for controlling minimum size via code. The actual minimum size will be the max value of these two (in each axis separately). If not overridden, defaults to [constant Vector2.ZERO]. [b]Note:[/b] This method will not be called when the script is attached to a [Control] node that already overrides its minimum size (e.g. [Label], [Button], [PanelContainer] etc.). It can only be used with most basic GUI nodes, like [Control], [Container], [Panel] etc. </description> @@ -137,7 +137,7 @@ * control has [member mouse_filter] set to [constant MOUSE_FILTER_IGNORE]; * control is obstructed by another [Control] on top of it, which doesn't have [member mouse_filter] set to [constant MOUSE_FILTER_IGNORE]; * control's parent has [member mouse_filter] set to [constant MOUSE_FILTER_STOP] or has accepted the event; - * it happens outside the parent's rectangle and the parent has either [member rect_clip_content] enabled. + * it happens outside the parent's rectangle and the parent has either [member clip_contents] enabled. [b]Note:[/b] Event position is relative to the control origin. </description> </method> @@ -157,7 +157,7 @@ Virtual method to be implemented by the user. Returns a [Control] node that should be used as a tooltip instead of the default one. The [code]for_text[/code] includes the contents of the [member hint_tooltip] property. The returned node must be of type [Control] or Control-derived. It can have child nodes of any type. It is freed when the tooltip disappears, so make sure you always provide a new instance (if you want to use a pre-existing node from your scene tree, you can duplicate it and pass the duplicated instance). When [code]null[/code] or a non-Control node is returned, the default tooltip will be used instead. The returned node will be added as child to a [PopupPanel], so you should only provide the contents of that panel. That [PopupPanel] can be themed using [method Theme.set_stylebox] for the type [code]"TooltipPanel"[/code] (see [member hint_tooltip] for an example). - [b]Note:[/b] The tooltip is shrunk to minimal size. If you want to ensure it's fully visible, you might want to set its [member rect_min_size] to some non-zero value. + [b]Note:[/b] The tooltip is shrunk to minimal size. If you want to ensure it's fully visible, you might want to set its [member minimum_size] to some non-zero value. [b]Note:[/b] The node (and any relevant children) should be [member CanvasItem.visible] when returned, otherwise, the viewport that instantiates it will not be able to calculate its minimum size reliably. Example of usage with a custom-constructed node: [codeblocks] @@ -351,13 +351,13 @@ <method name="get_begin" qualifiers="const"> <return type="Vector2" /> <description> - Returns [member offset_left] and [member offset_top]. See also [member rect_position]. + Returns [member offset_left] and [member offset_top]. See also [member position]. </description> </method> <method name="get_combined_minimum_size" qualifiers="const"> <return type="Vector2" /> <description> - Returns combined minimum size from [member rect_min_size] and [method get_minimum_size]. + Returns combined minimum size from [member minimum_size] and [method get_minimum_size]. </description> </method> <method name="get_cursor_shape" qualifiers="const"> @@ -383,13 +383,13 @@ <method name="get_global_rect" qualifiers="const"> <return type="Rect2" /> <description> - Returns the position and size of the control relative to the top-left corner of the screen. See [member rect_position] and [member rect_size]. + Returns the position and size of the control relative to the top-left corner of the screen. See [member position] and [member size]. </description> </method> <method name="get_minimum_size" qualifiers="const"> <return type="Vector2" /> <description> - Returns the minimum size for this control. See [member rect_min_size]. + Returns the minimum size for this control. See [member minimum_size]. </description> </method> <method name="get_offset" qualifiers="const"> @@ -414,7 +414,7 @@ <method name="get_rect" qualifiers="const"> <return type="Rect2" /> <description> - Returns the position and size of the control relative to the top-left corner of the parent Control. See [member rect_position] and [member rect_size]. + Returns the position and size of the control relative to the top-left corner of the parent Control. See [member position] and [member size]. </description> </method> <method name="get_theme_color" qualifiers="const"> @@ -759,7 +759,7 @@ <return type="void" /> <argument index="0" name="position" type="Vector2" /> <description> - Sets [member offset_left] and [member offset_top] at the same time. Equivalent of changing [member rect_position]. + Sets [member offset_left] and [member offset_top] at the same time. Equivalent of changing [member position]. </description> </method> <method name="set_drag_forwarding"> @@ -840,7 +840,7 @@ # Use a control that is not in the tree var cpb = ColorPickerButton.new() cpb.color = color - cpb.rect_size = Vector2(50, 50) + cpb.size = Vector2(50, 50) set_drag_preview(cpb) return color [/gdscript] @@ -881,7 +881,7 @@ <argument index="0" name="position" type="Vector2" /> <argument index="1" name="keep_offsets" type="bool" default="false" /> <description> - Sets the [member rect_global_position] to given [code]position[/code]. + Sets the [member global_position] to given [code]position[/code]. If [code]keep_offsets[/code] is [code]true[/code], control's anchors will be updated instead of offsets. </description> </method> @@ -909,7 +909,7 @@ <argument index="0" name="position" type="Vector2" /> <argument index="1" name="keep_offsets" type="bool" default="false" /> <description> - Sets the [member rect_position] to given [code]position[/code]. + Sets the [member position] to given [code]position[/code]. If [code]keep_offsets[/code] is [code]true[/code], control's anchors will be updated instead of offsets. </description> </method> @@ -918,21 +918,21 @@ <argument index="0" name="size" type="Vector2" /> <argument index="1" name="keep_offsets" type="bool" default="false" /> <description> - Sets the size (see [member rect_size]). + Sets the size (see [member size]). If [code]keep_offsets[/code] is [code]true[/code], control's anchors will be updated instead of offsets. </description> </method> <method name="update_minimum_size"> <return type="void" /> <description> - Invalidates the size cache in this node and in parent nodes up to top level. Intended to be used with [method get_minimum_size] when the return value is changed. Setting [member rect_min_size] directly calls this method automatically. + Invalidates the size cache in this node and in parent nodes up to top level. Intended to be used with [method get_minimum_size] when the return value is changed. Setting [member minimum_size] directly calls this method automatically. </description> </method> <method name="warp_mouse"> <return type="void" /> <argument index="0" name="to_position" type="Vector2" /> <description> - Moves the mouse cursor to [code]to_position[/code], relative to [member rect_position] of this [Control]. + Moves the mouse cursor to [code]to_position[/code], relative to [member position] of this [Control]. </description> </method> </methods> @@ -953,6 +953,9 @@ Toggles if any text should automatically change to its translated version depending on the current locale. Note that this will not affect any internal nodes (e.g. the popup of a [MenuButton]). Also decides if the node's strings should be parsed for POT generation. </member> + <member name="clip_contents" type="bool" setter="set_clip_contents" getter="is_clipping_contents" default="false"> + Enables whether rendering of [CanvasItem] based children should be clipped to this control's rectangle. If [code]true[/code], parts of a child which would be visibly outside of this control's rectangle will not be rendered and won't receive input. + </member> <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" enum="Control.FocusMode" default="0"> The focus access mode for the control (None, Click or All). Only one Control can be focused at the same time, and it will receive keyboard signals. </member> @@ -976,6 +979,9 @@ Tells Godot which node it should give keyboard focus to if the user presses [kbd]Shift + Tab[/kbd] on a keyboard by default. You can change the key by editing the [code]ui_focus_prev[/code] input action. If this property is not set, Godot will select a "best guess" based on surrounding nodes in the scene tree. </member> + <member name="global_position" type="Vector2" setter="_set_global_position" getter="get_global_position"> + The node's global position, relative to the world (usually to the top-left corner of the window). + </member> <member name="grow_horizontal" type="int" setter="set_h_grow_direction" getter="get_h_grow_direction" enum="Control.GrowDirection" default="1"> Controls the direction on the horizontal axis in which the control should grow if its horizontal minimum size is changed to be greater than its current size, as the control always has to be at least the minimum size. </member> @@ -1007,6 +1013,9 @@ <member name="layout_direction" type="int" setter="set_layout_direction" getter="get_layout_direction" enum="Control.LayoutDirection" default="0"> Controls layout direction and text writing direction. Right-to-left layouts are necessary for certain languages (e.g. Arabic and Hebrew). </member> + <member name="minimum_size" type="Vector2" setter="set_custom_minimum_size" getter="get_custom_minimum_size" default="Vector2(0, 0)"> + The minimum size of the node's bounding rectangle. If you set it to a value greater than (0, 0), the node's bounding rectangle will always have at least this size, even if its content is smaller. If it's set to (0, 0), the node sizes automatically to fit its content, be it a texture or child nodes. + </member> <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" enum="Control.CursorShape" default="0"> The default cursor shape for this control. Useful for Godot plugins and applications or games that use the system's mouse cursors. [b]Note:[/b] On Linux, shapes may vary depending on the cursor theme of the system. @@ -1030,30 +1039,21 @@ Distance between the node's top edge and its parent control, based on [member anchor_top]. Offsets are often controlled by one or multiple parent [Container] nodes, so you should not modify them manually if your node is a direct child of a [Container]. Offsets update automatically when you move or resize the node. </member> - <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" default="false"> - Enables whether rendering of [CanvasItem] based children should be clipped to this control's rectangle. If [code]true[/code], parts of a child which would be visibly outside of this control's rectangle will not be rendered and won't receive input. - </member> - <member name="rect_global_position" type="Vector2" setter="_set_global_position" getter="get_global_position"> - The node's global position, relative to the world (usually to the top-left corner of the window). - </member> - <member name="rect_min_size" type="Vector2" setter="set_custom_minimum_size" getter="get_custom_minimum_size" default="Vector2(0, 0)"> - The minimum size of the node's bounding rectangle. If you set it to a value greater than (0, 0), the node's bounding rectangle will always have at least this size, even if its content is smaller. If it's set to (0, 0), the node sizes automatically to fit its content, be it a texture or child nodes. - </member> - <member name="rect_pivot_offset" type="Vector2" setter="set_pivot_offset" getter="get_pivot_offset" default="Vector2(0, 0)"> - By default, the node's pivot is its top-left corner. When you change its [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. + <member name="pivot_offset" type="Vector2" setter="set_pivot_offset" getter="get_pivot_offset" default="Vector2(0, 0)"> + By default, the node's pivot is its top-left corner. When you change its [member rotation] or [member scale], it will rotate or scale around this pivot. Set this property to [member size] / 2 to pivot around the Control's center. </member> - <member name="rect_position" type="Vector2" setter="_set_position" getter="get_position" default="Vector2(0, 0)"> - The node's position, relative to its parent. It corresponds to the rectangle's top-left corner. The property is not affected by [member rect_pivot_offset]. + <member name="position" type="Vector2" setter="_set_position" getter="get_position" default="Vector2(0, 0)"> + The node's position, relative to its parent. It corresponds to the rectangle's top-left corner. The property is not affected by [member pivot_offset]. </member> - <member name="rect_rotation" type="float" setter="set_rotation" getter="get_rotation" default="0.0"> - The node's rotation around its pivot, in radians. See [member rect_pivot_offset] to change the pivot's position. + <member name="rotation" type="float" setter="set_rotation" getter="get_rotation" default="0.0"> + The node's rotation around its pivot, in radians. See [member pivot_offset] to change the pivot's position. </member> - <member name="rect_scale" type="Vector2" setter="set_scale" getter="get_scale" default="Vector2(1, 1)"> - The node's scale, relative to its [member rect_size]. Change this property to scale the node around its [member rect_pivot_offset]. The Control's [member hint_tooltip] will also scale according to this value. + <member name="scale" type="Vector2" setter="set_scale" getter="get_scale" default="Vector2(1, 1)"> + The node's scale, relative to its [member size]. Change this property to scale the node around its [member pivot_offset]. The Control's [member hint_tooltip] will also scale according to this value. [b]Note:[/b] This property is mainly intended to be used for animation purposes. Text inside the Control will look pixelated or blurry when the Control is scaled. To support multiple resolutions in your project, use an appropriate viewport stretch mode as described in the [url=$DOCS_URL/tutorials/viewports/multiple_resolutions.html]documentation[/url] instead of scaling Controls individually. - [b]Note:[/b] If the Control node is a child of a [Container] node, the scale will be reset to [code]Vector2(1, 1)[/code] when the scene is instantiated. To set the Control's scale when it's instantiated, wait for one frame using [code]await get_tree().process_frame[/code] then set its [member rect_scale] property. + [b]Note:[/b] If the Control node is a child of a [Container] node, the scale will be reset to [code]Vector2(1, 1)[/code] when the scene is instantiated. To set the Control's scale when it's instantiated, wait for one frame using [code]await get_tree().process_frame[/code] then set its [member scale] property. </member> - <member name="rect_size" type="Vector2" setter="_set_size" getter="get_size" default="Vector2(0, 0)"> + <member name="size" type="Vector2" setter="_set_size" getter="get_size" default="Vector2(0, 0)"> The size of the node's bounding rectangle, in pixels. [Container] nodes update this property automatically. </member> <member name="size_flags_horizontal" type="int" setter="set_h_size_flags" getter="get_h_size_flags" default="1"> @@ -1110,7 +1110,7 @@ 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()): + if not Rect2(Vector2(), size).has_point(get_local_mouse_position()): # Not hovering over area. [/codeblock] </description> @@ -1141,7 +1141,7 @@ The node can grab focus on mouse click or using the arrows and the Tab keys on the keyboard. Use with [member focus_mode]. </constant> <constant name="NOTIFICATION_RESIZED" value="40"> - Sent when the node changes size. Use [member rect_size] to get the new size. + Sent when the node changes size. Use [member size] to get the new size. </constant> <constant name="NOTIFICATION_MOUSE_ENTER" value="41"> Sent when the mouse pointer enters the node. diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml index 5525e7f1f3..19f2915087 100644 --- a/doc/classes/GraphEdit.xml +++ b/doc/classes/GraphEdit.xml @@ -198,6 +198,7 @@ </method> </methods> <members> + <member name="clip_contents" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" /> <member name="connection_lines_antialiased" type="bool" setter="set_connection_lines_antialiased" getter="is_connection_lines_antialiased" default="true"> If [code]true[/code], the lines between nodes will use antialiasing. </member> @@ -217,7 +218,6 @@ <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. </member> diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml index 8b564c01c9..48fa009300 100644 --- a/doc/classes/ItemList.xml +++ b/doc/classes/ItemList.xml @@ -366,6 +366,7 @@ <member name="auto_height" type="bool" setter="set_auto_height" getter="has_auto_height" default="false"> If [code]true[/code], the control will automatically resize the height to fit its content. </member> + <member name="clip_contents" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" /> <member name="fixed_column_width" type="int" setter="set_fixed_column_width" getter="get_fixed_column_width" default="0"> The width all columns will be adjusted to. A value of zero disables the adjustment, each item will have a width equal to the width of its content and the columns will have an uneven width. @@ -393,7 +394,6 @@ Maximum lines of text allowed in each item. Space will be reserved even when there is not enough lines of text to display. [b]Note:[/b] This property takes effect only when [member icon_mode] is [constant ICON_MODE_TOP]. To make the text wrap, [member fixed_column_width] should be greater than zero. </member> - <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" /> <member name="same_column_width" type="bool" setter="set_same_column_width" getter="is_same_column_width" default="false"> Whether all columns will have the same width. If [code]true[/code], the width is equal to the largest column width of all columns. diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml index 0350d09dfd..b7822f1bb0 100644 --- a/doc/classes/Light3D.xml +++ b/doc/classes/Light3D.xml @@ -86,9 +86,6 @@ <member name="shadow_blur" type="float" setter="set_param" getter="get_param" default="1.0"> Blurs the edges of the shadow. Can be used to hide pixel artifacts in low-resolution shadow maps. A high value can impact performance, make shadows appear grainy and can cause other unwanted artifacts. Try to keep as near default as possible. </member> - <member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" default="Color(0, 0, 0, 1)"> - The color of shadows cast by this light. - </member> <member name="shadow_enabled" type="bool" setter="set_shadow" getter="has_shadow" default="false"> If [code]true[/code], the light will cast real-time shadows. This has a significant performance cost. Only enable shadow rendering when it makes a noticeable difference in the scene's appearance, and consider using [member distance_fade_enabled] to hide the light when far away from the [Camera3D]. </member> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index ba3f5e10f5..50990b5320 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -1709,14 +1709,6 @@ If [code]true[/code], light will cast shadows. Equivalent to [member Light3D.shadow_enabled]. </description> </method> - <method name="light_set_shadow_color"> - <return type="void" /> - <argument index="0" name="light" type="RID" /> - <argument index="1" name="color" type="Color" /> - <description> - Sets the color of the shadow cast by the light. Equivalent to [member Light3D.shadow_color]. - </description> - </method> <method name="lightmap_create"> <return type="RID" /> <description> diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index f480071d32..d5e134fc60 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -412,6 +412,7 @@ <member name="bbcode_enabled" type="bool" setter="set_use_bbcode" getter="is_using_bbcode" default="false"> If [code]true[/code], the label uses BBCode formatting. </member> + <member name="clip_contents" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" /> <member name="custom_effects" type="Array" setter="set_effects" getter="get_effects" default="[]"> The currently installed custom effects. This is an array of [RichTextEffect]s. To add a custom effect, it's more convenient to use [method install_effect]. @@ -436,7 +437,6 @@ The range of characters to display, as a [float] between 0.0 and 1.0. When assigned an out of range value, it's the same as assigning 1.0. [b]Note:[/b] Setting this property updates [member visible_characters] based on current [method get_total_character_count]. </member> - <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" /> <member name="scroll_active" type="bool" setter="set_scroll_active" getter="is_scroll_active" default="true"> If [code]true[/code], the scrollbar is visible. Setting this to [code]false[/code] does not block scrolling completely. See [method scroll_to_line]. </member> diff --git a/doc/classes/ScrollContainer.xml b/doc/classes/ScrollContainer.xml index ea1d972d14..95255ed79f 100644 --- a/doc/classes/ScrollContainer.xml +++ b/doc/classes/ScrollContainer.xml @@ -5,7 +5,7 @@ </brief_description> <description> A ScrollContainer node meant to contain a [Control] child. - ScrollContainers will automatically create a scrollbar child ([HScrollBar], [VScrollBar], or both) when needed and will only draw the Control within the ScrollContainer area. Scrollbars will automatically be drawn at the right (for vertical) or bottom (for horizontal) and will enable dragging to move the viewable Control (and its children) within the ScrollContainer. Scrollbars will also automatically resize the grabber based on the [member Control.rect_min_size] of the Control relative to the ScrollContainer. + ScrollContainers will automatically create a scrollbar child ([HScrollBar], [VScrollBar], or both) when needed and will only draw the Control within the ScrollContainer area. Scrollbars will automatically be drawn at the right (for vertical) or bottom (for horizontal) and will enable dragging to move the viewable Control (and its children) within the ScrollContainer. Scrollbars will also automatically resize the grabber based on the [member Control.minimum_size] of the Control relative to the ScrollContainer. Works great with a [Panel] control. You can set [code]EXPAND[/code] on the children's size flags, so they will upscale to the ScrollContainer's size if it's larger (scroll is invisible for the chosen dimension). </description> <tutorials> @@ -40,13 +40,13 @@ </method> </methods> <members> + <member name="clip_contents" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" /> <member name="follow_focus" type="bool" setter="set_follow_focus" getter="is_following_focus" default="false"> If [code]true[/code], the ScrollContainer will automatically scroll to focused children (including indirect children) to make sure they are fully visible. </member> <member name="horizontal_scroll_mode" type="int" setter="set_horizontal_scroll_mode" getter="get_horizontal_scroll_mode" enum="ScrollContainer.ScrollMode" default="1"> Controls whether horizontal scrollbar can be used and when it should be visible. See [enum ScrollMode] for options. </member> - <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" /> <member name="scroll_deadzone" type="int" setter="set_deadzone" getter="get_deadzone" default="0"> </member> <member name="scroll_horizontal" type="int" setter="set_h_scroll" getter="get_h_scroll" default="0"> diff --git a/doc/classes/SubViewportContainer.xml b/doc/classes/SubViewportContainer.xml index c8babb8f43..77aa7e3ff4 100644 --- a/doc/classes/SubViewportContainer.xml +++ b/doc/classes/SubViewportContainer.xml @@ -5,7 +5,7 @@ </brief_description> <description> A [Container] node that holds a [SubViewport]. It uses the [SubViewport]'s size as minimum size, unless [member stretch] is enabled. - [b]Note:[/b] Changing a SubViewportContainer's [member Control.rect_scale] will cause its contents to appear distorted. To change its visual size without causing distortion, adjust the node's margins instead (if it's not already in a container). + [b]Note:[/b] Changing a SubViewportContainer's [member Control.scale] will cause its contents to appear distorted. To change its visual size without causing distortion, adjust the node's margins instead (if it's not already in a container). [b]Note:[/b] The SubViewportContainer forwards mouse-enter and mouse-exit notifications to its sub-viewports. </description> <tutorials> diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml index 3ff4dffe65..bdc73ee3c4 100644 --- a/doc/classes/TabContainer.xml +++ b/doc/classes/TabContainer.xml @@ -121,7 +121,7 @@ <argument index="0" name="tab_idx" type="int" /> <argument index="1" name="title" type="String" /> <description> - Sets a custom title for the tab at index [code]tab_idx[/code] (tab titles default to the name of the indexed child node). Set it to blank to make it the child's name again. + Sets a custom title for the tab at index [code]tab_idx[/code] (tab titles default to the name of the indexed child node). Set it back to the child's name to make the tab default to it again. </description> </method> </methods> diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml index 25e6f553ca..b8c39bee49 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -323,6 +323,7 @@ <member name="allow_rmb_select" type="bool" setter="set_allow_rmb_select" getter="get_allow_rmb_select" default="false"> If [code]true[/code], a right mouse button click can select items. </member> + <member name="clip_contents" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" /> <member name="column_titles_visible" type="bool" setter="set_column_titles_visible" getter="are_column_titles_visible" default="false"> If [code]true[/code], column titles are visible. </member> @@ -340,7 +341,6 @@ <member name="hide_root" type="bool" setter="set_hide_root" getter="is_root_hidden" default="false"> If [code]true[/code], the tree's root is hidden. </member> - <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" /> <member name="scroll_horizontal_enabled" type="bool" setter="set_h_scroll_enabled" getter="is_h_scroll_enabled" default="true"> If [code]true[/code], enables horizontal scrolling. </member> diff --git a/doc/classes/VisualShaderNodeCustom.xml b/doc/classes/VisualShaderNodeCustom.xml index 7b992abe24..0a962a4aa4 100644 --- a/doc/classes/VisualShaderNodeCustom.xml +++ b/doc/classes/VisualShaderNodeCustom.xml @@ -44,6 +44,17 @@ Defining this method is [b]optional[/b]. </description> </method> + <method name="_get_func_code" qualifiers="virtual const"> + <return type="String" /> + <argument index="0" name="mode" type="int" enum="Shader.Mode" /> + <argument index="1" name="type" type="int" enum="VisualShader.Type" /> + <description> + Override this method to add a shader code to the beginning of each shader function (once). The shader code should be returned as a string, which can have multiple lines (the [code]"""[/code] multiline string construct can be used for convenience). + If there are multiple custom nodes of different types which use this feature the order of each insertion is undefined. + You can customize the generated code based on the shader [code]mode[/code] (see [enum Shader.Mode]) and/or [code]type[/code] (see [enum VisualShader.Type]). + Defining this method is [b]optional[/b]. + </description> + </method> <method name="_get_global_code" qualifiers="virtual const"> <return type="String" /> <argument index="0" name="mode" type="int" enum="Shader.Mode" /> @@ -114,11 +125,20 @@ Defining this method is [b]optional[/b]. If not overridden, no return icon is shown. </description> </method> + <method name="_is_available" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="mode" type="int" enum="Shader.Mode" /> + <argument index="1" name="type" type="int" enum="VisualShader.Type" /> + <description> + Override this method to prevent the node to be visible in the member dialog for the certain [code]mode[/code] (see [enum Shader.Mode]) and/or [code]type[/code] (see [enum VisualShader.Type]). + Defining this method is [b]optional[/b]. If not overridden, it's [code]true[/code]. + </description> + </method> <method name="_is_highend" qualifiers="virtual const"> <return type="bool" /> <description> Override this method to enable high-end mark in the Visual Shader Editor's members dialog. - Defining this method is [b]optional[/b]. If not overridden, it's false. + Defining this method is [b]optional[/b]. If not overridden, it's [code]false[/code]. </description> </method> </methods> diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 8e0b7bc9b8..dce515a96d 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -2255,9 +2255,6 @@ void RasterizerStorageGLES3::light_set_param(RID p_light, RS::LightParam p_param void RasterizerStorageGLES3::light_set_shadow(RID p_light, bool p_enabled) { } -void RasterizerStorageGLES3::light_set_shadow_color(RID p_light, const Color &p_color) { -} - void RasterizerStorageGLES3::light_set_projector(RID p_light, RID p_texture) { } diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 64ed36ddd7..de984fa8df 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -898,7 +898,6 @@ public: void light_set_color(RID p_light, const Color &p_color) override; void light_set_param(RID p_light, RS::LightParam p_param, float p_value) override; void light_set_shadow(RID p_light, bool p_enabled) override; - void light_set_shadow_color(RID p_light, const Color &p_color) override; void light_set_projector(RID p_light, RID p_texture) override; void light_set_negative(RID p_light, bool p_enable) override; void light_set_cull_mask(RID p_light, uint32_t p_mask) override; diff --git a/editor/editor_toaster.cpp b/editor/editor_toaster.cpp index 319b4709fe..7ca88bd2a2 100644 --- a/editor/editor_toaster.cpp +++ b/editor/editor_toaster.cpp @@ -385,12 +385,19 @@ Control *EditorToaster::popup(Control *p_control, Severity p_severity, double p_ } void EditorToaster::popup_str(String p_message, Severity p_severity, String p_tooltip) { + if (is_processing_error) { + return; + } + // Since "_popup_str" adds nodes to the tree, and since the "add_child" method is not // thread-safe, it's better to defer the call to the next cycle to be thread-safe. + is_processing_error = true; call_deferred(SNAME("_popup_str"), p_message, p_severity, p_tooltip); + is_processing_error = false; } void EditorToaster::_popup_str(String p_message, Severity p_severity, String p_tooltip) { + is_processing_error = true; // Check if we already have a popup with the given message. Control *control = nullptr; for (KeyValue<Control *, Toast> element : toasts) { @@ -432,6 +439,7 @@ void EditorToaster::_popup_str(String p_message, Severity p_severity, String p_t } else { label->set_text(vformat("%s (%d)", p_message, toasts[control].count)); } + is_processing_error = false; } void EditorToaster::close(Control *p_control) { diff --git a/editor/editor_toaster.h b/editor/editor_toaster.h index 2ad8752bee..059245ce66 100644 --- a/editor/editor_toaster.h +++ b/editor/editor_toaster.h @@ -82,6 +82,8 @@ private: }; Map<Control *, Toast> toasts; + bool is_processing_error = false; // Makes sure that we don't handle errors that are triggered within the EditorToaster error processing. + const double default_message_duration = 5.0; static void _error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, bool p_editor_notify, ErrorHandlerType p_type); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index e43d1feb08..75f97efdbc 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -3580,7 +3580,7 @@ void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p return; } CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); - if (canvas_item && !canvas_item->is_visible()) { + if (canvas_item && !canvas_item->is_visible_in_tree()) { return; } diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index 282ee9a5b7..aadc7a2e66 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -530,18 +530,23 @@ void Skeleton3DEditor::_joint_tree_selection_changed() { TreeItem *selected = joint_tree->get_selected(); if (selected) { const String path = selected->get_metadata(0); - - if (path.begins_with("bones/")) { - const int b_idx = path.get_slicec('/', 1).to_int(); + if (!path.begins_with("bones/")) { + return; + } + const int b_idx = path.get_slicec('/', 1).to_int(); + selected_bone = b_idx; + if (pose_editor) { const String bone_path = "bones/" + itos(b_idx) + "/"; - pose_editor->set_target(bone_path); pose_editor->set_keyable(keyable); - selected_bone = b_idx; } } - pose_editor->set_visible(selected); + + if (pose_editor && pose_editor->is_inside_tree()) { + pose_editor->set_visible(selected); + } set_bone_options_enabled(selected); + _update_properties(); _update_gizmo_visible(); } diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 94906acb63..7f30dd91e5 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -1082,6 +1082,10 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) { } } +void VisualShaderEditor::update_nodes() { + _update_nodes(); +} + void VisualShaderEditor::add_plugin(const Ref<VisualShaderNodePlugin> &p_plugin) { if (plugins.has(p_plugin)) { return; @@ -1165,10 +1169,7 @@ bool VisualShaderEditor::_is_available(int p_mode) { return (p_mode == -1 || (p_mode & current_mode) != 0); } -void VisualShaderEditor::update_custom_nodes() { - if (members_dialog->is_visible()) { - return; - } +void VisualShaderEditor::_update_nodes() { clear_custom_types(); List<StringName> class_list; ScriptServer::get_global_class_list(&class_list); @@ -1184,6 +1185,9 @@ void VisualShaderEditor::update_custom_nodes() { Ref<VisualShaderNodeCustom> ref; ref.instantiate(); ref->set_script(script); + if (!ref->is_available(visual_shader->get_mode(), visual_shader->get_shader_type())) { + continue; + } String name; if (ref->has_method("_get_name")) { @@ -1240,6 +1244,32 @@ void VisualShaderEditor::update_custom_nodes() { } } + // Disables not-supported copied items. + { + for (CopyItem &item : copy_items_buffer) { + Ref<VisualShaderNodeCustom> custom = Object::cast_to<VisualShaderNodeCustom>(item.node.ptr()); + + if (custom.is_valid()) { + if (!custom->is_available(visual_shader->get_mode(), visual_shader->get_shader_type())) { + item.disabled = true; + } else { + item.disabled = false; + } + } else { + for (int i = 0; i < add_options.size(); i++) { + if (add_options[i].type == item.node->get_class_name()) { + if ((add_options[i].func != visual_shader->get_mode() && add_options[i].func != -1) || !_is_available(add_options[i].mode)) { + item.disabled = true; + } else { + item.disabled = false; + } + break; + } + } + } + } + } + Array keys = added.keys(); keys.sort(); @@ -3370,15 +3400,23 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { selected_float_constant = -1; } - if (to_change.is_empty() && copy_items_buffer.is_empty()) { + bool copy_buffer_empty = true; + for (const CopyItem &item : copy_items_buffer) { + if (!item.disabled) { + copy_buffer_empty = false; + break; + } + } + + if (to_change.is_empty() && copy_buffer_empty) { _show_members_dialog(true); } else { popup_menu->set_item_disabled(NodeMenuOptions::CUT, to_change.is_empty()); popup_menu->set_item_disabled(NodeMenuOptions::COPY, to_change.is_empty()); - popup_menu->set_item_disabled(NodeMenuOptions::PASTE, copy_items_buffer.is_empty()); + popup_menu->set_item_disabled(NodeMenuOptions::PASTE, copy_buffer_empty); popup_menu->set_item_disabled(NodeMenuOptions::DELETE, to_change.is_empty()); popup_menu->set_item_disabled(NodeMenuOptions::DUPLICATE, to_change.is_empty()); - popup_menu->set_item_disabled(NodeMenuOptions::CLEAR_COPY_BUFFER, copy_items_buffer.is_empty()); + popup_menu->set_item_disabled(NodeMenuOptions::CLEAR_COPY_BUFFER, copy_buffer_empty); int temp = popup_menu->get_item_index(NodeMenuOptions::SEPARATOR2); if (temp != -1) { @@ -3715,6 +3753,17 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, List<CopyItem> &r_items, c if (p_duplicate) { undo_redo->create_action(TTR("Duplicate VisualShader Node(s)")); } else { + bool copy_buffer_empty = true; + for (const CopyItem &item : copy_items_buffer) { + if (!item.disabled) { + copy_buffer_empty = false; + break; + } + } + if (copy_buffer_empty) { + return; + } + undo_redo->create_action(TTR("Paste VisualShader Node(s)")); } @@ -3727,16 +3776,7 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, List<CopyItem> &r_items, c Set<int> added_set; for (CopyItem &item : r_items) { - bool unsupported = false; - for (int i = 0; i < add_options.size(); i++) { - if (add_options[i].type == item.node->get_class_name()) { - if (!_is_available(add_options[i].mode)) { - unsupported = true; - } - break; - } - } - if (unsupported) { + if (item.disabled) { unsupported_set.insert(item.id); continue; } @@ -3777,7 +3817,10 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, List<CopyItem> &r_items, c } id_from = base_id; - for (int i = 0; i < r_items.size(); i++) { + for (const CopyItem &item : r_items) { + if (item.disabled) { + continue; + } undo_redo->add_undo_method(visual_shader.ptr(), "remove_node", type, id_from); undo_redo->add_undo_method(graph_plugin.ptr(), "remove_node", type, id_from); id_from++; @@ -3878,7 +3921,7 @@ void VisualShaderEditor::_mode_selected(int p_id) { } visual_shader->set_shader_type(VisualShader::Type(p_id + offset)); - _update_options_menu(); + _update_nodes(); _update_graph(); graph->grab_focus(); @@ -4465,8 +4508,8 @@ void VisualShaderEditor::_visibility_changed() { } void VisualShaderEditor::_bind_methods() { + ClassDB::bind_method("_update_nodes", &VisualShaderEditor::_update_nodes); ClassDB::bind_method("_update_graph", &VisualShaderEditor::_update_graph); - ClassDB::bind_method("_update_options_menu", &VisualShaderEditor::_update_options_menu); ClassDB::bind_method("_add_node", &VisualShaderEditor::_add_node); ClassDB::bind_method("_node_changed", &VisualShaderEditor::_node_changed); ClassDB::bind_method("_input_select_item", &VisualShaderEditor::_input_select_item); @@ -5439,7 +5482,7 @@ void VisualShaderEditorPlugin::make_visible(bool p_visible) { //editor->animation_panel_make_visible(true); button->show(); EditorNode::get_singleton()->make_bottom_panel_item_visible(visual_shader_editor); - visual_shader_editor->update_custom_nodes(); + visual_shader_editor->update_nodes(); visual_shader_editor->set_process_input(true); //visual_shader_editor->set_process(true); } else { @@ -5919,8 +5962,8 @@ void EditorPropertyShaderMode::_option_selected(int p_which) { } } - undo_redo->add_do_method(editor, "_update_options_menu"); - undo_redo->add_undo_method(editor, "_update_options_menu"); + undo_redo->add_do_method(editor, "_update_nodes"); + undo_redo->add_undo_method(editor, "_update_nodes"); undo_redo->add_do_method(editor, "_update_graph"); undo_redo->add_undo_method(editor, "_update_graph"); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index e26b606397..4087fc583c 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -262,6 +262,7 @@ class VisualShaderEditor : public VBoxContainer { void _show_add_varying_dialog(); void _show_remove_varying_dialog(); + void _update_nodes(); void _update_graph(); struct AddOption { @@ -394,6 +395,7 @@ class VisualShaderEditor : public VBoxContainer { String group_inputs; String group_outputs; String expression; + bool disabled = false; }; void _dup_copy_nodes(int p_type, List<CopyItem> &r_nodes, List<VisualShader::Connection> &r_connections); @@ -476,7 +478,7 @@ protected: static void _bind_methods(); public: - void update_custom_nodes(); + void update_nodes(); void add_plugin(const Ref<VisualShaderNodePlugin> &p_plugin); void remove_plugin(const Ref<VisualShaderNodePlugin> &p_plugin); diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs index 56fca6b5cb..bfc807c01a 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs @@ -350,7 +350,7 @@ namespace GodotTools.Build if (_issuesListContextMenu.ItemCount > 0) { - _issuesListContextMenu.Position = (Vector2i)(_issuesList.RectGlobalPosition + atPosition); + _issuesListContextMenu.Position = (Vector2i)(_issuesList.GlobalPosition + atPosition); _issuesListContextMenu.Popup(); } } diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs index 2dbc78ab77..9e8f7ef1b1 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs @@ -126,7 +126,7 @@ namespace GodotTools.Build { base._Ready(); - RectMinSize = new Vector2(0, 228) * EditorScale; + MinimumSize = new Vector2(0, 228) * EditorScale; SizeFlagsVertical = (int)SizeFlags.ExpandFill; var toolBarHBox = new HBoxContainer { SizeFlagsHorizontal = (int)SizeFlags.ExpandFill }; diff --git a/modules/svg/SCsub b/modules/svg/SCsub index bb03147731..93262f4f87 100644 --- a/modules/svg/SCsub +++ b/modules/svg/SCsub @@ -34,6 +34,7 @@ thirdparty_sources = [ "src/loaders/svg/tvgSvgSceneBuilder.cpp", "src/loaders/svg/tvgSvgPath.cpp", "src/loaders/svg/tvgSvgLoader.cpp", + "src/loaders/svg/tvgSvgCssStyle.cpp", "src/loaders/tvg/tvgTvgBinInterpreter.cpp", "src/loaders/tvg/tvgTvgLoader.cpp", "src/loaders/jpg/tvgJpgLoader.cpp", diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 1ed4d8fb32..07cb6a23e8 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -2094,7 +2094,7 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo XGetWindowAttributes(x11_display, wd.x11_window, &xwa); ERR_FAIL_COND_MSG(p_window == MAIN_WINDOW_ID, "Main window can't be popup."); - ERR_FAIL_COND_MSG((xwa.map_state == IsViewable) && (wd.is_popup != p_enabled), "Pupup flag can't changed while window is opened."); + ERR_FAIL_COND_MSG((xwa.map_state == IsViewable) && (wd.is_popup != p_enabled), "Popup flag can't changed while window is opened."); wd.is_popup = p_enabled; } break; default: { @@ -3660,10 +3660,14 @@ void DisplayServerX11::process_events() { const WindowData &wd = windows[window_id]; + XWindowAttributes xwa; + XSync(x11_display, False); + XGetWindowAttributes(x11_display, wd.x11_window, &xwa); + // Set focus when menu window is re-used. // RevertToPointerRoot is used to make sure we don't lose all focus in case // a subwindow and its parent are both destroyed. - if (!wd.no_focus && !wd.is_popup) { + if ((xwa.map_state == IsViewable) && !wd.no_focus && !wd.is_popup) { XSetInputFocus(x11_display, wd.x11_window, RevertToPointerRoot, CurrentTime); } diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index a4cd8f58bd..89ca6e50ec 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -1864,7 +1864,7 @@ void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo } break; case WINDOW_FLAG_POPUP: { ERR_FAIL_COND_MSG(p_window == MAIN_WINDOW_ID, "Main window can't be popup."); - ERR_FAIL_COND_MSG([wd.window_object isVisible] && (wd.is_popup != p_enabled), "Pupup flag can't changed while window is opened."); + ERR_FAIL_COND_MSG([wd.window_object isVisible] && (wd.is_popup != p_enabled), "Popup flag can't changed while window is opened."); wd.is_popup = p_enabled; } break; default: { diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 163f5c350b..27b4a2018f 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1238,7 +1238,7 @@ void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, W } break; case WINDOW_FLAG_POPUP: { ERR_FAIL_COND_MSG(p_window == MAIN_WINDOW_ID, "Main window can't be popup."); - ERR_FAIL_COND_MSG(IsWindowVisible(wd.hWnd) && (wd.is_popup != p_enabled), "Pupup flag can't changed while window is opened."); + ERR_FAIL_COND_MSG(IsWindowVisible(wd.hWnd) && (wd.is_popup != p_enabled), "Popup flag can't changed while window is opened."); wd.is_popup = p_enabled; } break; case WINDOW_FLAG_MAX: diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index 0dd3fc8a23..f2021aa3d5 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -131,15 +131,6 @@ Color Light3D::get_color() const { return color; } -void Light3D::set_shadow_color(const Color &p_shadow_color) { - shadow_color = p_shadow_color; - RS::get_singleton()->light_set_shadow_color(light, p_shadow_color); -} - -Color Light3D::get_shadow_color() const { - return shadow_color; -} - void Light3D::set_shadow_reverse_cull_face(bool p_enable) { reverse_cull = p_enable; RS::get_singleton()->light_set_reverse_cull_face_mode(light, reverse_cull); @@ -232,7 +223,7 @@ bool Light3D::is_editor_only() const { } void Light3D::_validate_property(PropertyInfo &property) const { - if (!shadow && (property.name == "shadow_color" || property.name == "shadow_bias" || property.name == "shadow_normal_bias" || property.name == "shadow_reverse_cull_face" || property.name == "shadow_transmittance_bias" || property.name == "shadow_fog_fade" || property.name == "shadow_blur" || property.name == "distance_fade_shadow")) { + if (!shadow && (property.name == "shadow_bias" || property.name == "shadow_normal_bias" || property.name == "shadow_reverse_cull_face" || property.name == "shadow_transmittance_bias" || property.name == "shadow_fog_fade" || property.name == "shadow_blur" || property.name == "distance_fade_shadow")) { property.usage = PROPERTY_USAGE_NO_EDITOR; } @@ -282,9 +273,6 @@ void Light3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_reverse_cull_face", "enable"), &Light3D::set_shadow_reverse_cull_face); ClassDB::bind_method(D_METHOD("get_shadow_reverse_cull_face"), &Light3D::get_shadow_reverse_cull_face); - ClassDB::bind_method(D_METHOD("set_shadow_color", "shadow_color"), &Light3D::set_shadow_color); - ClassDB::bind_method(D_METHOD("get_shadow_color"), &Light3D::get_shadow_color); - ClassDB::bind_method(D_METHOD("set_bake_mode", "bake_mode"), &Light3D::set_bake_mode); ClassDB::bind_method(D_METHOD("get_bake_mode"), &Light3D::get_bake_mode); @@ -304,7 +292,6 @@ void Light3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "light_cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); ADD_GROUP("Shadow", "shadow_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled"), "set_shadow", "has_shadow"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_shadow_color", "get_shadow_color"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_bias", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_BIAS); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_normal_bias", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_reverse_cull_face"), "set_shadow_reverse_cull_face", "get_shadow_reverse_cull_face"); diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index 21d785e2f7..11a9fcfc55 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -70,7 +70,6 @@ public: private: Color color; real_t param[PARAM_MAX] = {}; - Color shadow_color; bool shadow = false; bool negative = false; bool reverse_cull = false; @@ -129,9 +128,6 @@ public: void set_color(const Color &p_color); Color get_color() const; - void set_shadow_color(const Color &p_shadow_color); - Color get_shadow_color() const; - void set_shadow_reverse_cull_face(bool p_enable); bool get_shadow_reverse_cull_face() const; diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 0338326bbe..ab86face7e 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -349,7 +349,7 @@ Ref<Shortcut> BaseButton::get_shortcut() const { void BaseButton::unhandled_key_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); - if (!_is_focus_owner_in_shorcut_context()) { + if (!_is_focus_owner_in_shortcut_context()) { return; } @@ -404,7 +404,7 @@ Node *BaseButton::get_shortcut_context() const { return ctx_node; } -bool BaseButton::_is_focus_owner_in_shorcut_context() const { +bool BaseButton::_is_focus_owner_in_shortcut_context() const { if (shortcut_context == ObjectID()) { // No context, therefore global - always "in" context. return true; diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h index 6bfffe7575..a2b6ee0845 100644 --- a/scene/gui/base_button.h +++ b/scene/gui/base_button.h @@ -80,7 +80,7 @@ protected: virtual void unhandled_key_input(const Ref<InputEvent> &p_event) override; void _notification(int p_what); - bool _is_focus_owner_in_shorcut_context() const; + bool _is_focus_owner_in_shortcut_context() const; GDVIRTUAL0(_pressed) GDVIRTUAL1(_toggled, bool) diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 3c712a89bb..d8659b1f18 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -190,10 +190,10 @@ String Control::properties_managed_by_container[] = { "anchor_top", "anchor_right", "anchor_bottom", - "rect_position", - "rect_rotation", - "rect_scale", - "rect_size" + "position", + "rotation", + "scale", + "size" }; void Control::accept_event() { @@ -490,7 +490,7 @@ void Control::_validate_property(PropertyInfo &property) const { } else if (Object::cast_to<Container>(parent_node)) { // If the parent is a container, display only container-related properties. if (property.name.begins_with("anchor_") || property.name.begins_with("offset_") || property.name.begins_with("grow_") || property.name == "anchors_preset" || - (property.name.begins_with("rect_") && property.name != "rect_min_size" && property.name != "rect_clip_content" && property.name != "rect_global_position")) { + property.name == "position" || property.name == "rotation" || property.name == "scale" || property.name == "size" || property.name == "pivot_offset") { property.usage ^= PROPERTY_USAGE_EDITOR; } else if (property.name == "layout_mode") { @@ -3342,8 +3342,8 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("is_auto_translating"), &Control::is_auto_translating); ADD_GROUP("Layout", ""); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rect_clip_content"), "set_clip_contents", "is_clipping_contents"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_min_size"), "set_custom_minimum_size", "get_custom_minimum_size"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_contents"), "set_clip_contents", "is_clipping_contents"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "minimum_size"), "set_custom_minimum_size", "get_custom_minimum_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_direction", PROPERTY_HINT_ENUM, "Inherited,Locale,Left-to-Right,Right-to-Left"), "set_layout_direction", "get_layout_direction"); ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_mode", PROPERTY_HINT_ENUM, "Position,Anchors,Container,Uncontrolled", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_layout_mode", "_get_layout_mode"); ADD_PROPERTY_DEFAULT("layout_mode", LayoutMode::LAYOUT_MODE_POSITION); @@ -3372,15 +3372,13 @@ void Control::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "grow_horizontal", PROPERTY_HINT_ENUM, "Left,Right,Both"), "set_h_grow_direction", "get_h_grow_direction"); ADD_PROPERTY(PropertyInfo(Variant::INT, "grow_vertical", PROPERTY_HINT_ENUM, "Top,Bottom,Both"), "set_v_grow_direction", "get_v_grow_direction"); - ADD_SUBGROUP("Rectangle", "rect_"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_position", "get_position"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_global_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "_set_global_position", "get_global_position"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_size", "get_size"); - - ADD_SUBGROUP("Transform", "rect_"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rect_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians"), "set_rotation", "get_rotation"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_scale"), "set_scale", "get_scale"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_pivot_offset"), "set_pivot_offset", "get_pivot_offset"); + ADD_SUBGROUP("Transform", ""); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_size", "get_size"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_position", "get_position"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "_set_global_position", "get_global_position"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians"), "set_rotation", "get_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "pivot_offset"), "set_pivot_offset", "get_pivot_offset"); ADD_SUBGROUP("Container Sizing", "size_flags_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_horizontal", PROPERTY_HINT_FLAGS, "Fill:1,Expand:2,Shrink Center:4,Shrink End:8"), "set_h_size_flags", "get_h_size_flags"); diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index c04690cdb3..7e724e4d71 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -36,7 +36,7 @@ void MenuButton::unhandled_key_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); - if (!_is_focus_owner_in_shorcut_context()) { + if (!_is_focus_owner_in_shortcut_context()) { return; } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 1c9eb14a24..bad7be7d42 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -3250,6 +3250,10 @@ void RichTextLabel::append_text(const String &p_bbcode) { push_paragraph(HORIZONTAL_ALIGNMENT_FILL); pos = brk_end + 1; tag_stack.push_front(tag); + } else if (tag == "left") { + push_paragraph(HORIZONTAL_ALIGNMENT_LEFT); + pos = brk_end + 1; + tag_stack.push_front(tag); } else if (tag == "right") { push_paragraph(HORIZONTAL_ALIGNMENT_RIGHT); pos = brk_end + 1; diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp index a11248ec6b..2f5df9b756 100644 --- a/scene/gui/tab_bar.cpp +++ b/scene/gui/tab_bar.cpp @@ -71,7 +71,7 @@ Size2 TabBar::get_minimum_size() const { Ref<Texture2D> tex = tabs[i].icon; if (tex.is_valid()) { - ms.height = MAX(ms.height, tex->get_size().height); + ms.height = MAX(ms.height, tex->get_size().height + y_margin); ms.width += tex->get_size().width + hseparation; } @@ -91,13 +91,13 @@ Size2 TabBar::get_minimum_size() const { ms.width += button_highlight->get_margin(SIDE_LEFT) + rb->get_width() + hseparation; } - ms.height = MAX(rb->get_height() + style->get_minimum_size().height, ms.height); + ms.height = MAX(ms.height, rb->get_height() + y_margin); } if (close_visible) { ms.width += button_highlight->get_margin(SIDE_LEFT) + close->get_width() + hseparation; - ms.height = MAX(close->get_height() + style->get_minimum_size().height, ms.height); + ms.height = MAX(ms.height, close->get_height() + y_margin); } if (ms.width - ofs > style->get_minimum_size().width) { diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index 102fe18502..ee61c862b7 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -624,7 +624,7 @@ void TabContainer::set_all_tabs_in_front(bool p_in_front) { all_tabs_in_front = p_in_front; remove_child(tab_bar); - add_child(tab_bar, false, all_tabs_in_front ? INTERNAL_MODE_BACK : INTERNAL_MODE_FRONT); + add_child(tab_bar, false, all_tabs_in_front ? INTERNAL_MODE_FRONT : INTERNAL_MODE_BACK); } bool TabContainer::is_all_tabs_in_front() const { @@ -635,14 +635,13 @@ void TabContainer::set_tab_title(int p_tab, const String &p_title) { Control *child = get_tab_control(p_tab); ERR_FAIL_COND(!child); - if (p_title.is_empty()) { - tab_bar->set_tab_title(p_tab, String(child->get_name())); + tab_bar->set_tab_title(p_tab, p_title); + if (p_title == child->get_name()) { if (child->has_meta("_tab_name")) { child->remove_meta("_tab_name"); } } else { - tab_bar->set_tab_title(p_tab, p_title); child->set_meta("_tab_name", p_title); } diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 0b66ff004b..a396ef01f4 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -1016,7 +1016,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("SpringArm", "SpringArm3D"); ClassDB::add_compatibility_class("Sprite", "Sprite2D"); ClassDB::add_compatibility_class("StaticBody", "StaticBody3D"); - ClassDB::add_compatibility_class("CompressedTexture", "CompressedTexture2D"); + ClassDB::add_compatibility_class("StreamTexture", "CompressedTexture2D"); ClassDB::add_compatibility_class("TextureProgress", "TextureProgressBar"); ClassDB::add_compatibility_class("VehicleBody", "VehicleBody3D"); ClassDB::add_compatibility_class("VehicleWheel", "VehicleWheel3D"); @@ -1046,6 +1046,14 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisualShaderNodeScalarDerivativeFunc", "VisualShaderNodeDerivativeFunc"); ClassDB::add_compatibility_class("VisualShaderNodeVectorDerivativeFunc", "VisualShaderNodeDerivativeFunc"); ClassDB::add_compatibility_class("World", "World3D"); + + // Renamed during 4.0 alpha, added to ease transition between alphas. + ClassDB::add_compatibility_class("StreamCubemap", "CompressedCubemap"); + ClassDB::add_compatibility_class("StreamCubemapArray", "CompressedCubemapArray"); + ClassDB::add_compatibility_class("StreamTexture2D", "CompressedTexture2D"); + ClassDB::add_compatibility_class("StreamTexture2DArray", "CompressedTexture2DArray"); + ClassDB::add_compatibility_class("StreamTexture3D", "CompressedTexture3D"); + ClassDB::add_compatibility_class("StreamTextureLayered", "CompressedTextureLayered"); #endif /* DISABLE_DEPRECATED */ OS::get_singleton()->yield(); // may take time to init diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 03b768e869..d3e61dbc84 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -455,32 +455,69 @@ String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader:: for (int i = 0; i < get_output_port_count(); i++) { output_vars.push_back(p_output_vars[i]); } - String code = " {\n"; + String _code; GDVIRTUAL_CALL(_get_code, input_vars, output_vars, p_mode, p_type, _code); - bool nend = _code.ends_with("\n"); - _code = _code.insert(0, " "); - _code = _code.replace("\n", "\n "); - code += _code; - if (!nend) { - code += "\n }"; - } else { - code.remove_at(code.size() - 1); - code += "}"; + if (_is_valid_code(_code)) { + String code = " {\n"; + bool nend = _code.ends_with("\n"); + _code = _code.insert(0, " "); + _code = _code.replace("\n", "\n "); + code += _code; + if (!nend) { + code += "\n }"; + } else { + code.remove_at(code.size() - 1); + code += "}"; + } + code += "\n"; + return code; } - code += "\n"; - return code; + return String(); } String VisualShaderNodeCustom::generate_global_per_node(Shader::Mode p_mode, int p_id) const { - String ret; - if (GDVIRTUAL_CALL(_get_global_code, p_mode, ret)) { - String code = "// " + get_caption() + "\n"; - code += ret; - code += "\n"; - return code; + String _code; + if (GDVIRTUAL_CALL(_get_global_code, p_mode, _code)) { + if (_is_valid_code(_code)) { + String code = "// " + get_caption() + "\n"; + code += _code; + code += "\n"; + return code; + } } - return ""; + return String(); +} + +String VisualShaderNodeCustom::generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String _code; + if (GDVIRTUAL_CALL(_get_func_code, p_mode, p_type, _code)) { + if (_is_valid_code(_code)) { + bool nend = _code.ends_with("\n"); + String code = "// " + get_caption() + "\n"; + code += " {\n"; + _code = _code.insert(0, " "); + _code = _code.replace("\n", "\n "); + code += _code; + if (!nend) { + code += "\n }"; + } else { + code.remove_at(code.size() - 1); + code += "}"; + } + code += "\n"; + return code; + } + } + return String(); +} + +bool VisualShaderNodeCustom::is_available(Shader::Mode p_mode, VisualShader::Type p_type) const { + bool ret; + if (GDVIRTUAL_CALL(_is_available, p_mode, p_type, ret)) { + return ret; + } + return true; } void VisualShaderNodeCustom::set_input_port_default_value(int p_port, const Variant &p_value, const Variant &p_prev_value) { @@ -511,6 +548,13 @@ void VisualShaderNodeCustom::_set_input_port_default_value(int p_port, const Var VisualShaderNode::set_input_port_default_value(p_port, p_value); } +bool VisualShaderNodeCustom::_is_valid_code(const String &p_code) const { + if (p_code.is_empty() || p_code == "null") { + return false; + } + return true; +} + bool VisualShaderNodeCustom::_is_initialized() { return is_initialized; } @@ -531,8 +575,10 @@ void VisualShaderNodeCustom::_bind_methods() { GDVIRTUAL_BIND(_get_output_port_type, "port"); GDVIRTUAL_BIND(_get_output_port_name, "port"); GDVIRTUAL_BIND(_get_code, "input_vars", "output_vars", "mode", "type"); + GDVIRTUAL_BIND(_get_func_code, "mode", "type"); GDVIRTUAL_BIND(_get_global_code, "mode"); GDVIRTUAL_BIND(_is_highend); + GDVIRTUAL_BIND(_is_available, "mode", "type"); ClassDB::bind_method(D_METHOD("_set_initialized", "enabled"), &VisualShaderNodeCustom::_set_initialized); ClassDB::bind_method(D_METHOD("_is_initialized"), &VisualShaderNodeCustom::_is_initialized); diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 5cad5fc95b..2d4b2852e9 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -383,14 +383,20 @@ protected: GDVIRTUAL1RC(int, _get_output_port_type, int) GDVIRTUAL1RC(String, _get_output_port_name, int) GDVIRTUAL4RC(String, _get_code, TypedArray<String>, TypedArray<String>, Shader::Mode, VisualShader::Type) + GDVIRTUAL2RC(String, _get_func_code, Shader::Mode, VisualShader::Type) GDVIRTUAL1RC(String, _get_global_code, Shader::Mode) GDVIRTUAL0RC(bool, _is_highend) + GDVIRTUAL2RC(bool, _is_available, Shader::Mode, VisualShader::Type) + + bool _is_valid_code(const String &p_code) const; protected: void _set_input_port_default_value(int p_port, const Variant &p_value); + bool is_available(Shader::Mode p_mode, VisualShader::Type p_type) const; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override; + virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; static void _bind_methods(); diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index a6aa6d8c49..7b4d7e66d4 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -5696,7 +5696,7 @@ String VisualShaderNodeTextureUniformTriplanar::get_input_port_name(int p_port) String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader::Mode p_mode, int p_id) const { String code; - code += "// TRIPLANAR FUNCTION GLOBAL CODE\n"; + code += "// " + get_caption() + "\n"; code += " vec4 triplanar_texture(sampler2D p_sampler, vec3 p_weights, vec3 p_triplanar_pos) {\n"; code += " vec4 samp = vec4(0.0);\n"; code += " samp += texture(p_sampler, p_triplanar_pos.xy) * p_weights.z;\n"; @@ -5719,11 +5719,13 @@ String VisualShaderNodeTextureUniformTriplanar::generate_global_per_func(Shader: String code; if (p_type == VisualShader::TYPE_VERTEX) { - code += " // TRIPLANAR FUNCTION VERTEX CODE\n"; + code += "// " + get_caption() + "\n"; + code += " {\n"; code += " triplanar_power_normal = pow(abs(NORMAL), vec3(triplanar_sharpness));\n"; code += " triplanar_power_normal /= dot(triplanar_power_normal, vec3(1.0));\n"; code += " triplanar_pos = VERTEX * triplanar_scale + triplanar_offset;\n"; code += " triplanar_pos *= vec3(1.0, -1.0, 1.0);\n"; + code += " }\n"; } return code; diff --git a/servers/rendering/rasterizer_dummy.h b/servers/rendering/rasterizer_dummy.h index 987f2f4342..8f82356d11 100644 --- a/servers/rendering/rasterizer_dummy.h +++ b/servers/rendering/rasterizer_dummy.h @@ -408,7 +408,6 @@ public: void light_set_color(RID p_light, const Color &p_color) override {} void light_set_param(RID p_light, RS::LightParam p_param, float p_value) override {} void light_set_shadow(RID p_light, bool p_enabled) override {} - void light_set_shadow_color(RID p_light, const Color &p_color) override {} void light_set_projector(RID p_light, RID p_texture) override {} void light_set_negative(RID p_light, bool p_enable) override {} void light_set_cull_mask(RID p_light, uint32_t p_mask) override {} diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h index 25f0dca3b7..f2d1a17099 100644 --- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h @@ -250,8 +250,6 @@ private: float cos_spot_angle; float inv_spot_attenuation; float radius; - - float shadow_color[4]; }; struct DirectLightPushConstant { diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 0fa9f6ee7f..6296e10962 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -3316,43 +3316,8 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.size = 1.0 - Math::cos(Math::deg2rad(size)); //angle to cosine offset - Color shadow_col = storage->light_get_shadow_color(base).to_linear(); - if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_PSSM_SPLITS) { - light_data.shadow_color1[0] = 1.0; - light_data.shadow_color1[1] = 0.0; - light_data.shadow_color1[2] = 0.0; - light_data.shadow_color1[3] = 1.0; - light_data.shadow_color2[0] = 0.0; - light_data.shadow_color2[1] = 1.0; - light_data.shadow_color2[2] = 0.0; - light_data.shadow_color2[3] = 1.0; - light_data.shadow_color3[0] = 0.0; - light_data.shadow_color3[1] = 0.0; - light_data.shadow_color3[2] = 1.0; - light_data.shadow_color3[3] = 1.0; - light_data.shadow_color4[0] = 1.0; - light_data.shadow_color4[1] = 1.0; - light_data.shadow_color4[2] = 0.0; - light_data.shadow_color4[3] = 1.0; - - } else { - light_data.shadow_color1[0] = shadow_col.r; - light_data.shadow_color1[1] = shadow_col.g; - light_data.shadow_color1[2] = shadow_col.b; - light_data.shadow_color1[3] = 1.0; - light_data.shadow_color2[0] = shadow_col.r; - light_data.shadow_color2[1] = shadow_col.g; - light_data.shadow_color2[2] = shadow_col.b; - light_data.shadow_color2[3] = 1.0; - light_data.shadow_color3[0] = shadow_col.r; - light_data.shadow_color3[1] = shadow_col.g; - light_data.shadow_color3[2] = shadow_col.b; - light_data.shadow_color3[3] = 1.0; - light_data.shadow_color4[0] = shadow_col.r; - light_data.shadow_color4[1] = shadow_col.g; - light_data.shadow_color4[2] = shadow_col.b; - light_data.shadow_color4[3] = 1.0; + WARN_PRINT_ONCE("The DirectionalLight3D PSSM splits debug draw mode is not reimplemented yet."); } light_data.shadow_enabled = p_using_shadows && storage->light_has_shadow(base); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 47bc0af1db..4a86ced322 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -678,10 +678,6 @@ private: float shadow_range_begin[4]; float shadow_split_offsets[4]; float shadow_matrices[4][16]; - float shadow_color1[4]; - float shadow_color2[4]; - float shadow_color3[4]; - float shadow_color4[4]; float uv_scale1[2]; float uv_scale2[2]; float uv_scale3[2]; diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index edf2113c2a..e4ddc1b41f 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -6555,12 +6555,6 @@ void RendererStorageRD::light_set_shadow(RID p_light, bool p_enabled) { light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT); } -void RendererStorageRD::light_set_shadow_color(RID p_light, const Color &p_color) { - Light *light = light_owner.get_or_null(p_light); - ERR_FAIL_COND(!light); - light->shadow_color = p_color; -} - void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) { Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h index 95aa547a02..9416d04cdd 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.h +++ b/servers/rendering/renderer_rd/renderer_storage_rd.h @@ -1025,7 +1025,6 @@ private: RS::LightType type; float param[RS::LIGHT_PARAM_MAX]; Color color = Color(1, 1, 1, 1); - Color shadow_color; RID projector; bool shadow = false; bool negative = false; @@ -1841,7 +1840,6 @@ public: void light_set_color(RID p_light, const Color &p_color); void light_set_param(RID p_light, RS::LightParam p_param, float p_value); void light_set_shadow(RID p_light, bool p_enabled); - void light_set_shadow_color(RID p_light, const Color &p_color); void light_set_projector(RID p_light, RID p_texture); void light_set_negative(RID p_light, bool p_enable); void light_set_cull_mask(RID p_light, uint32_t p_mask); @@ -1890,13 +1888,6 @@ public: return light->color; } - _FORCE_INLINE_ Color light_get_shadow_color(RID p_light) { - const Light *light = light_owner.get_or_null(p_light); - ERR_FAIL_COND_V(!light, Color()); - - return light->shadow_color; - } - _FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) { const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, 0); diff --git a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl index 52787bb204..61c8488a05 100644 --- a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl @@ -76,10 +76,6 @@ struct DirectionalLightData { highp mat4 shadow_matrix2; highp mat4 shadow_matrix3; highp mat4 shadow_matrix4; - mediump vec4 shadow_color1; - mediump vec4 shadow_color2; - mediump vec4 shadow_color3; - mediump vec4 shadow_color4; highp vec2 uv_scale1; highp vec2 uv_scale2; highp vec2 uv_scale3; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index 21b8f2d4b5..0fcf449659 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -1130,7 +1130,6 @@ void main() { float depth_z = -vertex.z; vec4 pssm_coord; - vec3 shadow_color = vec3(0.0); vec3 light_dir = directional_lights.data[i].direction; #define BIAS_FUNC(m_var, m_idx) \ @@ -1156,9 +1155,6 @@ void main() { } else { shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); } - - shadow_color = directional_lights.data[i].shadow_color1.rgb; - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { vec4 v = vec4(vertex, 1.0); @@ -1176,8 +1172,6 @@ void main() { } else { shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); } - - shadow_color = directional_lights.data[i].shadow_color2.rgb; } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { vec4 v = vec4(vertex, 1.0); @@ -1195,9 +1189,6 @@ void main() { } else { shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); } - - shadow_color = directional_lights.data[i].shadow_color3.rgb; - } else { vec4 v = vec4(vertex, 1.0); @@ -1215,12 +1206,9 @@ void main() { } else { shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); } - - shadow_color = directional_lights.data[i].shadow_color4.rgb; } if (directional_lights.data[i].blend_splits) { - vec3 shadow_color_blend = vec3(0.0); float pssm_blend; float shadow2; @@ -1241,7 +1229,6 @@ void main() { } pssm_blend = smoothstep(0.0, directional_lights.data[i].shadow_split_offsets.x, depth_z); - shadow_color_blend = directional_lights.data[i].shadow_color2.rgb; } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 2) @@ -1259,8 +1246,6 @@ void main() { } pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.x, directional_lights.data[i].shadow_split_offsets.y, depth_z); - - shadow_color_blend = directional_lights.data[i].shadow_color3.rgb; } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 3) @@ -1277,7 +1262,6 @@ void main() { } pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.y, directional_lights.data[i].shadow_split_offsets.z, depth_z); - shadow_color_blend = directional_lights.data[i].shadow_color4.rgb; } else { pssm_blend = 0.0; //if no blend, same coord will be used (divide by z will result in same value, and already cached) } @@ -1285,7 +1269,6 @@ void main() { pssm_blend = sqrt(pssm_blend); shadow = mix(shadow, shadow2, pssm_blend); - shadow_color = mix(shadow_color, shadow_color_blend, pssm_blend); } shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl index 5bda15236c..b95fad650e 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl @@ -70,8 +70,6 @@ struct Light { float cos_spot_angle; float inv_spot_attenuation; float radius; - - vec4 shadow_color; }; layout(set = 0, binding = 9, std140) buffer restrict readonly Lights { diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl index 7a0cea421e..347fd13b28 100644 --- a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl +++ b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl @@ -382,7 +382,6 @@ void main() { float depth_z = -view_pos.z; vec4 pssm_coord; - vec3 shadow_color = directional_lights.data[i].shadow_color1.rgb; vec3 light_dir = directional_lights.data[i].direction; vec4 v = vec4(view_pos, 1.0); float z_range; @@ -413,7 +412,7 @@ void main() { shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, view_pos.z)); //done with negative values for performance - shadow_attenuation = mix(shadow_color, vec3(1.0), shadow); + shadow_attenuation = mix(vec3(0.0), vec3(1.0), shadow); } total_light += shadow_attenuation * directional_lights.data[i].color * directional_lights.data[i].energy * henyey_greenstein(dot(normalize(view_pos), normalize(directional_lights.data[i].direction)), params.phase_g); diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h index 762362afed..ca3d3a048d 100644 --- a/servers/rendering/renderer_storage.h +++ b/servers/rendering/renderer_storage.h @@ -317,7 +317,6 @@ public: virtual void light_set_color(RID p_light, const Color &p_color) = 0; virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) = 0; virtual void light_set_shadow(RID p_light, bool p_enabled) = 0; - virtual void light_set_shadow_color(RID p_light, const Color &p_color) = 0; virtual void light_set_projector(RID p_light, RID p_texture) = 0; virtual void light_set_negative(RID p_light, bool p_enable) = 0; virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) = 0; diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 9ed2b2ad4f..4a8944ccdd 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -342,7 +342,6 @@ public: FUNC2(light_set_color, RID, const Color &) FUNC3(light_set_param, RID, LightParam, float) FUNC2(light_set_shadow, RID, bool) - FUNC2(light_set_shadow_color, RID, const Color &) FUNC2(light_set_projector, RID, RID) FUNC2(light_set_negative, RID, bool) FUNC2(light_set_cull_mask, RID, uint32_t) diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 39a0acb2bd..d34fd572ad 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1879,7 +1879,6 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("light_set_color", "light", "color"), &RenderingServer::light_set_color); ClassDB::bind_method(D_METHOD("light_set_param", "light", "param", "value"), &RenderingServer::light_set_param); ClassDB::bind_method(D_METHOD("light_set_shadow", "light", "enabled"), &RenderingServer::light_set_shadow); - ClassDB::bind_method(D_METHOD("light_set_shadow_color", "light", "color"), &RenderingServer::light_set_shadow_color); ClassDB::bind_method(D_METHOD("light_set_projector", "light", "texture"), &RenderingServer::light_set_projector); ClassDB::bind_method(D_METHOD("light_set_negative", "light", "enable"), &RenderingServer::light_set_negative); ClassDB::bind_method(D_METHOD("light_set_cull_mask", "light", "mask"), &RenderingServer::light_set_cull_mask); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 533c000166..94d9cb8800 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -439,7 +439,6 @@ public: virtual void light_set_color(RID p_light, const Color &p_color) = 0; virtual void light_set_param(RID p_light, LightParam p_param, float p_value) = 0; virtual void light_set_shadow(RID p_light, bool p_enabled) = 0; - virtual void light_set_shadow_color(RID p_light, const Color &p_color) = 0; virtual void light_set_projector(RID p_light, RID p_texture) = 0; virtual void light_set_negative(RID p_light, bool p_enable) = 0; virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) = 0; diff --git a/thirdparty/README.md b/thirdparty/README.md index d591d2cbd8..7800e220a1 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -627,7 +627,7 @@ instead of `miniz.h` as an external dependency. ## thorvg - Upstream: https://github.com/Samsung/thorvg -- Version: 0.7.1 (d53eb2a880002cb770ace1c1ace9c5dfcfc28252, 2022) +- Version: 0.8.0 (41093c17b3cac440bdcc53f8b69abeb5734696b5, 2022) - License: MIT Files extracted from upstream source: diff --git a/thirdparty/thorvg/AUTHORS b/thirdparty/thorvg/AUTHORS index ec06c49118..0f8ba2dd7d 100644 --- a/thirdparty/thorvg/AUTHORS +++ b/thirdparty/thorvg/AUTHORS @@ -1,4 +1,4 @@ -Hermet Park <chuneon.park@samsung.com> +Hermet Park <hermetpark@gmail.com> Prudhvi Raj Vasireddi <prudhvi.raj@samsung.com> Junsu Choi <jsuya.choi@samsung.com> Pranay Samanta <pranay.ks@samsung.com> diff --git a/thirdparty/thorvg/LICENSE b/thirdparty/thorvg/LICENSE index b096b0888e..2f0361a864 100644 --- a/thirdparty/thorvg/LICENSE +++ b/thirdparty/thorvg/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020 - 2021 notice for the ThorVG Project (see AUTHORS) +Copyright (c) 2020 - 2022 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: diff --git a/thirdparty/thorvg/inc/config.h b/thirdparty/thorvg/inc/config.h index 41e8f6dafa..d72574bc65 100644 --- a/thirdparty/thorvg/inc/config.h +++ b/thirdparty/thorvg/inc/config.h @@ -13,5 +13,5 @@ #define THORVG_JPG_LOADER_SUPPORT 1 -#define THORVG_VERSION_STRING "0.7.1" +#define THORVG_VERSION_STRING "0.8.0" #endif diff --git a/thirdparty/thorvg/inc/thorvg.h b/thirdparty/thorvg/inc/thorvg.h index e542d36555..b08356d9d5 100644 --- a/thirdparty/thorvg/inc/thorvg.h +++ b/thirdparty/thorvg/inc/thorvg.h @@ -145,8 +145,9 @@ 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. + AlphaMask, ///< The pixels of the source and the target are alpha blended. As a result, only the part of the source, which alpha 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 alpha is not covered by the target is visible. + LumaMask ///< @BETA_API The source pixels are converted to the grayscale (luma value) and alpha blended with the target. As a result, only the part of the source, which intersects with the target is visible. }; /** diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwCommon.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwCommon.h index e0ffc1fb97..be7042d6de 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwCommon.h +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwCommon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 @@ -235,6 +235,7 @@ struct SwImage struct SwBlender { uint32_t (*join)(uint8_t r, uint8_t g, uint8_t b, uint8_t a); + uint32_t (*lumaValue)(uint32_t c); }; struct SwCompositor; diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwFill.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwFill.cpp index 0bf051c17f..04014a9ec3 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwFill.cpp +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwFill.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp index f9974d9847..f24d2d6f27 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwMath.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwMath.cpp index 7a3529bd69..7f13609525 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwMath.cpp +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwMath.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwMemPool.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwMemPool.cpp index a44be85bbb..3ab0b6069e 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwMemPool.cpp +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwMemPool.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp index 56bc2f77dc..e3deebe24f 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 @@ -47,6 +47,18 @@ static inline uint32_t _ialpha(uint32_t c) } +static inline uint32_t _abgrLumaValue(uint32_t c) +{ + return ((((c&0xff)*54) + (((c>>8)&0xff)*183) + (((c>>16)&0xff)*19))) >> 8; //0.2125*R + 0.7154*G + 0.0721*B +} + + +static inline uint32_t _argbLumaValue(uint32_t c) +{ + return ((((c&0xff)*19) + (((c>>8)&0xff)*183) + (((c>>16)&0xff)*54))) >> 8; //0.0721*B + 0.7154*G + 0.2125*R +} + + 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); @@ -139,7 +151,7 @@ static bool _rasterMaskedRect(SwSurface* surface, const SwBBox& region, uint32_t 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 + 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]; @@ -173,6 +185,8 @@ static bool _rasterRect(SwSurface* surface, const SwBBox& region, uint32_t color return _rasterMaskedRect(surface, region, color, _alpha); } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterMaskedRect(surface, region, color, _ialpha); + } else if (surface->compositor->method == CompositeMethod::LumaMask) { + return _rasterMaskedRect(surface, region, color, surface->blender.lumaValue); } } else { if (opacity == 255) { @@ -246,6 +260,8 @@ static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint32_t color, uint8 return _rasterMaskedRle(surface, rle, color, _alpha); } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterMaskedRle(surface, rle, color, _ialpha); + } else if (surface->compositor->method == CompositeMethod::LumaMask) { + return _rasterMaskedRle(surface, rle, color, surface->blender.lumaValue); } } else { if (opacity == 255) { @@ -275,6 +291,8 @@ static bool _transformedRleRGBAImage(SwSurface* surface, const SwImage* image, c return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, _alpha); } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, _ialpha); + } else if (surface->compositor->method == CompositeMethod::LumaMask) { + return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, surface->blender.lumaValue); } } else { return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, nullptr); @@ -494,12 +512,16 @@ static bool _scaledRleRGBAImage(SwSurface* surface, const SwImage* image, const 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::LumaMask) { + return _rasterScaledMaskedRleRGBAImage(surface, image, &itransform, region, halfScale, surface->blender.lumaValue); } } 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 (surface->compositor->method == CompositeMethod::LumaMask) { + return _rasterScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, region, opacity, halfScale, surface->blender.lumaValue); } } } else { @@ -616,12 +638,16 @@ static bool _directRleRGBAImage(SwSurface* surface, const SwImage* image, uint32 return _rasterDirectMaskedRleRGBAImage(surface, image, _alpha); } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterDirectMaskedRleRGBAImage(surface, image, _ialpha); + } else if (surface->compositor->method == CompositeMethod::LumaMask) { + return _rasterDirectMaskedRleRGBAImage(surface, image, surface->blender.lumaValue); } } 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 (surface->compositor->method == CompositeMethod::LumaMask) { + return _rasterDirectMaskedTranslucentRleRGBAImage(surface, image, opacity, surface->blender.lumaValue); } } } else { @@ -643,6 +669,8 @@ static bool _transformedRGBAImage(SwSurface* surface, const SwImage* image, cons return _rasterTexmapPolygon(surface, image, transform, ®ion, opacity, _alpha); } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterTexmapPolygon(surface, image, transform, ®ion, opacity, _ialpha); + } else if (surface->compositor->method == CompositeMethod::LumaMask) { + return _rasterTexmapPolygon(surface, image, transform, ®ion, opacity, surface->blender.lumaValue); } } else { return _rasterTexmapPolygon(surface, image, transform, ®ion, opacity, nullptr); @@ -832,12 +860,16 @@ static bool _scaledRGBAImage(SwSurface* surface, const SwImage* image, const Mat 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::LumaMask) { + return _rasterScaledMaskedRGBAImage(surface, image, &itransform, region, halfScale, surface->blender.lumaValue); } } 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 (surface->compositor->method == CompositeMethod::LumaMask) { + return _rasterScaledMaskedTranslucentRGBAImage(surface, image, &itransform, region, opacity, halfScale, surface->blender.lumaValue); } } } else { @@ -861,7 +893,7 @@ static bool _rasterDirectMaskedRGBAImage(SwSurface* surface, const SwImage* imag 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 + 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; @@ -888,7 +920,7 @@ static bool _rasterDirectMaskedTranslucentRGBAImage(SwSurface* surface, const Sw 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 + 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; @@ -952,12 +984,16 @@ static bool _directRGBAImage(SwSurface* surface, const SwImage* image, const SwB 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::LumaMask) { + return _rasterDirectMaskedRGBAImage(surface, image, region, surface->blender.lumaValue); } } 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 (surface->compositor->method == CompositeMethod::LumaMask) { + return _rasterDirectMaskedTranslucentRGBAImage(surface, image, region, opacity, surface->blender.lumaValue); } } } else { @@ -1062,6 +1098,8 @@ static bool _rasterLinearGradientRect(SwSurface* surface, const SwBBox& region, return _rasterLinearGradientMaskedRect(surface, region, fill, _alpha); } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterLinearGradientMaskedRect(surface, region, fill, _ialpha); + } else if (surface->compositor->method == CompositeMethod::LumaMask) { + return _rasterLinearGradientMaskedRect(surface, region, fill, surface->blender.lumaValue); } } else { if (fill->translucent) return _rasterTranslucentLinearGradientRect(surface, region, fill); @@ -1166,6 +1204,8 @@ static bool _rasterLinearGradientRle(SwSurface* surface, const SwRleData* rle, c return _rasterLinearGradientMaskedRle(surface, rle, fill, _alpha); } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterLinearGradientMaskedRle(surface, rle, fill, _ialpha); + } else if (surface->compositor->method == CompositeMethod::LumaMask) { + return _rasterLinearGradientMaskedRle(surface, rle, fill, surface->blender.lumaValue); } } else { if (fill->translucent) return _rasterTranslucentLinearGradientRle(surface, rle, fill); @@ -1253,6 +1293,8 @@ static bool _rasterRadialGradientRect(SwSurface* surface, const SwBBox& region, return _rasterRadialGradientMaskedRect(surface, region, fill, _alpha); } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterRadialGradientMaskedRect(surface, region, fill, _ialpha); + } else if (surface->compositor->method == CompositeMethod::LumaMask) { + return _rasterRadialGradientMaskedRect(surface, region, fill, surface->blender.lumaValue); } } else { if (fill->translucent) return _rasterTranslucentRadialGradientRect(surface, region, fill); @@ -1356,6 +1398,8 @@ static bool _rasterRadialGradientRle(SwSurface* surface, const SwRleData* rle, c return _rasterRadialGradientMaskedRle(surface, rle, fill, _alpha); } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterRadialGradientMaskedRle(surface, rle, fill, _ialpha); + } else if (surface->compositor->method == CompositeMethod::LumaMask) { + return _rasterRadialGradientMaskedRle(surface, rle, fill, surface->blender.lumaValue); } } else { if (fill->translucent) _rasterTranslucentRadialGradientRle(surface, rle, fill); @@ -1385,8 +1429,10 @@ bool rasterCompositor(SwSurface* surface) { if (surface->cs == SwCanvas::ABGR8888 || surface->cs == SwCanvas::ABGR8888_STRAIGHT) { surface->blender.join = _abgrJoin; + surface->blender.lumaValue = _abgrLumaValue; } else if (surface->cs == SwCanvas::ARGB8888 || surface->cs == SwCanvas::ARGB8888_STRAIGHT) { surface->blender.join = _argbJoin; + surface->blender.lumaValue = _argbLumaValue; } else { //What Color Space ??? return false; @@ -1500,4 +1546,4 @@ bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, co //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 index 1d6552f3e9..7a129a3a80 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterAvx.h +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterAvx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterC.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterC.h index 6d60957eb9..d479ede15f 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterC.h +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterC.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterNeon.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterNeon.h index c74a6b309c..a4b3cdaeb2 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterNeon.h +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterNeon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 @@ -26,8 +26,8 @@ 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); + uint16x8_t t = vmull_u8(c, a); + return vshrn_n_u16(t, 8); } diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmap.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmap.h index 2cf9fb4e93..1faedd60aa 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmap.h +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h index e96307c874..f31ea1eb97 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp index c75e73760e..c3872f3207 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 @@ -19,11 +19,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include <math.h> +#include "tvgMath.h" #include "tvgSwCommon.h" #include "tvgTaskScheduler.h" #include "tvgSwRenderer.h" -#include "tvgMath.h" /************************************************************************/ /* Internal Class Implementation */ diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h index 3f883ac409..574d9d488f 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRle.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRle.cpp index b41e48b7ca..aa975869e0 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRle.cpp +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRle.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwShape.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwShape.cpp index 7b49c232b1..2a2c6a1da3 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwShape.cpp +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwShape.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwStroke.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwStroke.cpp index c0cfc1be26..04aa9a36ec 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwStroke.cpp +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwStroke.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgAccessor.cpp b/thirdparty/thorvg/src/lib/tvgAccessor.cpp index 085c8a3cbc..9fd564dd23 100644 --- a/thirdparty/thorvg/src/lib/tvgAccessor.cpp +++ b/thirdparty/thorvg/src/lib/tvgAccessor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgArray.h b/thirdparty/thorvg/src/lib/tvgArray.h index d04e68e73c..04ddbaee2b 100644 --- a/thirdparty/thorvg/src/lib/tvgArray.h +++ b/thirdparty/thorvg/src/lib/tvgArray.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgBezier.cpp b/thirdparty/thorvg/src/lib/tvgBezier.cpp index 2290afa728..95e2055943 100644 --- a/thirdparty/thorvg/src/lib/tvgBezier.cpp +++ b/thirdparty/thorvg/src/lib/tvgBezier.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgBezier.h b/thirdparty/thorvg/src/lib/tvgBezier.h index 866e39148e..7d7c84e34e 100644 --- a/thirdparty/thorvg/src/lib/tvgBezier.h +++ b/thirdparty/thorvg/src/lib/tvgBezier.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgBinaryDesc.h b/thirdparty/thorvg/src/lib/tvgBinaryDesc.h index 30ba2d5a29..f139def470 100644 --- a/thirdparty/thorvg/src/lib/tvgBinaryDesc.h +++ b/thirdparty/thorvg/src/lib/tvgBinaryDesc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgCanvas.cpp b/thirdparty/thorvg/src/lib/tvgCanvas.cpp index bb42441c62..e8529e47c2 100644 --- a/thirdparty/thorvg/src/lib/tvgCanvas.cpp +++ b/thirdparty/thorvg/src/lib/tvgCanvas.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgCanvasImpl.h b/thirdparty/thorvg/src/lib/tvgCanvasImpl.h index 848c03aaed..0adec8fa52 100644 --- a/thirdparty/thorvg/src/lib/tvgCanvasImpl.h +++ b/thirdparty/thorvg/src/lib/tvgCanvasImpl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgCommon.h b/thirdparty/thorvg/src/lib/tvgCommon.h index b1c586188c..1d66f2e1a2 100644 --- a/thirdparty/thorvg/src/lib/tvgCommon.h +++ b/thirdparty/thorvg/src/lib/tvgCommon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgFill.cpp b/thirdparty/thorvg/src/lib/tvgFill.cpp index 4bfb93c102..0c0581a180 100644 --- a/thirdparty/thorvg/src/lib/tvgFill.cpp +++ b/thirdparty/thorvg/src/lib/tvgFill.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgFill.h b/thirdparty/thorvg/src/lib/tvgFill.h index 912091f8cb..fff2475c4f 100644 --- a/thirdparty/thorvg/src/lib/tvgFill.h +++ b/thirdparty/thorvg/src/lib/tvgFill.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgGlCanvas.cpp b/thirdparty/thorvg/src/lib/tvgGlCanvas.cpp index 3a88b6d799..56feb69541 100644 --- a/thirdparty/thorvg/src/lib/tvgGlCanvas.cpp +++ b/thirdparty/thorvg/src/lib/tvgGlCanvas.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgInitializer.cpp b/thirdparty/thorvg/src/lib/tvgInitializer.cpp index 83ec50be95..42997c3493 100644 --- a/thirdparty/thorvg/src/lib/tvgInitializer.cpp +++ b/thirdparty/thorvg/src/lib/tvgInitializer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgIteratorAccessor.h b/thirdparty/thorvg/src/lib/tvgIteratorAccessor.h index 10b55a536d..8e566acb72 100644 --- a/thirdparty/thorvg/src/lib/tvgIteratorAccessor.h +++ b/thirdparty/thorvg/src/lib/tvgIteratorAccessor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgLinearGradient.cpp b/thirdparty/thorvg/src/lib/tvgLinearGradient.cpp index 6ec7ddab20..df34af3aa1 100644 --- a/thirdparty/thorvg/src/lib/tvgLinearGradient.cpp +++ b/thirdparty/thorvg/src/lib/tvgLinearGradient.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgLoadModule.h b/thirdparty/thorvg/src/lib/tvgLoadModule.h index 0c34ecbf6a..bfcc165f31 100644 --- a/thirdparty/thorvg/src/lib/tvgLoadModule.h +++ b/thirdparty/thorvg/src/lib/tvgLoadModule.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgLoader.cpp b/thirdparty/thorvg/src/lib/tvgLoader.cpp index fb93e0faec..991c260159 100644 --- a/thirdparty/thorvg/src/lib/tvgLoader.cpp +++ b/thirdparty/thorvg/src/lib/tvgLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgLoader.h b/thirdparty/thorvg/src/lib/tvgLoader.h index 8ba3c139fa..ab32f89a2f 100644 --- a/thirdparty/thorvg/src/lib/tvgLoader.h +++ b/thirdparty/thorvg/src/lib/tvgLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgLzw.cpp b/thirdparty/thorvg/src/lib/tvgLzw.cpp index 0049c89962..1aaf37831a 100644 --- a/thirdparty/thorvg/src/lib/tvgLzw.cpp +++ b/thirdparty/thorvg/src/lib/tvgLzw.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgLzw.h b/thirdparty/thorvg/src/lib/tvgLzw.h index 3fdb439a02..1bd5c61fac 100644 --- a/thirdparty/thorvg/src/lib/tvgLzw.h +++ b/thirdparty/thorvg/src/lib/tvgLzw.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgMath.h b/thirdparty/thorvg/src/lib/tvgMath.h index 423fb6eb1b..6120216d74 100644 --- a/thirdparty/thorvg/src/lib/tvgMath.h +++ b/thirdparty/thorvg/src/lib/tvgMath.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgPaint.cpp b/thirdparty/thorvg/src/lib/tvgPaint.cpp index 30e82fbc60..d0e908ddf2 100644 --- a/thirdparty/thorvg/src/lib/tvgPaint.cpp +++ b/thirdparty/thorvg/src/lib/tvgPaint.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 @@ -79,8 +79,8 @@ static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, 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); + viewport.w = static_cast<int32_t>(ceil(v2.x - viewport.x)); + viewport.h = static_cast<int32_t>(ceil(v2.y - viewport.y)); if (viewport.w < 0) viewport.w = 0; if (viewport.h < 0) viewport.h = 0; @@ -404,4 +404,4 @@ uint8_t Paint::opacity() const noexcept 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 index 4003bdbeac..c170559a37 100644 --- a/thirdparty/thorvg/src/lib/tvgPaint.h +++ b/thirdparty/thorvg/src/lib/tvgPaint.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgPicture.cpp b/thirdparty/thorvg/src/lib/tvgPicture.cpp index 1d9776363c..1125b1eb58 100644 --- a/thirdparty/thorvg/src/lib/tvgPicture.cpp +++ b/thirdparty/thorvg/src/lib/tvgPicture.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgPictureImpl.h b/thirdparty/thorvg/src/lib/tvgPictureImpl.h index 00e8aa6dd9..b2e097d400 100644 --- a/thirdparty/thorvg/src/lib/tvgPictureImpl.h +++ b/thirdparty/thorvg/src/lib/tvgPictureImpl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgRadialGradient.cpp b/thirdparty/thorvg/src/lib/tvgRadialGradient.cpp index 42a83461e3..7aba550e48 100644 --- a/thirdparty/thorvg/src/lib/tvgRadialGradient.cpp +++ b/thirdparty/thorvg/src/lib/tvgRadialGradient.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgRender.cpp b/thirdparty/thorvg/src/lib/tvgRender.cpp index a48075dd04..145f974cee 100644 --- a/thirdparty/thorvg/src/lib/tvgRender.cpp +++ b/thirdparty/thorvg/src/lib/tvgRender.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgRender.h b/thirdparty/thorvg/src/lib/tvgRender.h index f927947aa6..ed66f393da 100644 --- a/thirdparty/thorvg/src/lib/tvgRender.h +++ b/thirdparty/thorvg/src/lib/tvgRender.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgSaveModule.h b/thirdparty/thorvg/src/lib/tvgSaveModule.h index 2a0f427f11..3531662fdd 100644 --- a/thirdparty/thorvg/src/lib/tvgSaveModule.h +++ b/thirdparty/thorvg/src/lib/tvgSaveModule.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgSaver.cpp b/thirdparty/thorvg/src/lib/tvgSaver.cpp index 1a3e8614a6..e71953700c 100644 --- a/thirdparty/thorvg/src/lib/tvgSaver.cpp +++ b/thirdparty/thorvg/src/lib/tvgSaver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgScene.cpp b/thirdparty/thorvg/src/lib/tvgScene.cpp index 4b2f77dde9..ff43d3c881 100644 --- a/thirdparty/thorvg/src/lib/tvgScene.cpp +++ b/thirdparty/thorvg/src/lib/tvgScene.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgSceneImpl.h b/thirdparty/thorvg/src/lib/tvgSceneImpl.h index de94a66e2f..6a7614c667 100644 --- a/thirdparty/thorvg/src/lib/tvgSceneImpl.h +++ b/thirdparty/thorvg/src/lib/tvgSceneImpl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgShape.cpp b/thirdparty/thorvg/src/lib/tvgShape.cpp index 8db5635932..3a3af5f76e 100644 --- a/thirdparty/thorvg/src/lib/tvgShape.cpp +++ b/thirdparty/thorvg/src/lib/tvgShape.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgShapeImpl.h b/thirdparty/thorvg/src/lib/tvgShapeImpl.h index dcf4e6e954..738b21ed70 100644 --- a/thirdparty/thorvg/src/lib/tvgShapeImpl.h +++ b/thirdparty/thorvg/src/lib/tvgShapeImpl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgSwCanvas.cpp b/thirdparty/thorvg/src/lib/tvgSwCanvas.cpp index f7a03b819c..8c9de8cb51 100644 --- a/thirdparty/thorvg/src/lib/tvgSwCanvas.cpp +++ b/thirdparty/thorvg/src/lib/tvgSwCanvas.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgTaskScheduler.cpp b/thirdparty/thorvg/src/lib/tvgTaskScheduler.cpp index 780127b87b..8c07dc3859 100644 --- a/thirdparty/thorvg/src/lib/tvgTaskScheduler.cpp +++ b/thirdparty/thorvg/src/lib/tvgTaskScheduler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/lib/tvgTaskScheduler.h b/thirdparty/thorvg/src/lib/tvgTaskScheduler.h index f30bdf9a8f..163e387f29 100644 --- a/thirdparty/thorvg/src/lib/tvgTaskScheduler.h +++ b/thirdparty/thorvg/src/lib/tvgTaskScheduler.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.cpp b/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.cpp index 6f9416b69c..522c3c71a6 100644 --- a/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.cpp +++ b/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.h b/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.h index 7d35e57d72..3f82af8003 100644 --- a/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.h +++ b/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp index c3d281482a..05db65cb23 100644 --- a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp +++ b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 @@ -93,7 +93,10 @@ bool PngLoader::read() png_image_free(image); return false; } - if (!png_image_finish_read(image, NULL, buffer, 0, NULL)) return false; + if (!png_image_finish_read(image, NULL, buffer, 0, NULL)) { + free(buffer); + return false; + } content = reinterpret_cast<uint32_t*>(buffer); _premultiply(reinterpret_cast<uint32_t*>(buffer), image->width, image->height); diff --git a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h index b42537c73f..8beff0a3b3 100644 --- a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h +++ b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp index f27881da42..7b90b4aef9 100644 --- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp +++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h index 39732dbc3a..d6b886cb29 100644 --- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h +++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp index 4ccc5788d5..dacd45ed03 100644 --- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp +++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 @@ -382,8 +382,8 @@ struct Row 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 tmp0 = static_cast<unsigned int>(ACCESS_COL(0) + ACCESS_COL(4)) << CONST_BITS; + const int tmp1 = static_cast<unsigned int>(ACCESS_COL(0) - ACCESS_COL(4)) << CONST_BITS; const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; @@ -461,8 +461,8 @@ struct Col 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 tmp0 = static_cast<unsigned int>(ACCESS_ROW(0) + ACCESS_ROW(4)) << CONST_BITS; + const int tmp1 = static_cast<unsigned int>(ACCESS_ROW(0) - ACCESS_ROW(4)) << CONST_BITS; const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; @@ -2557,7 +2557,7 @@ void jpeg_decoder::decode_block_dc_first(jpeg_decoder *pD, int component_id, int 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); + p[0] = static_cast<jpgd_block_t>(static_cast<unsigned int>(s) << pD->m_successive_low); } @@ -2588,7 +2588,7 @@ void jpeg_decoder::decode_block_ac_first(jpeg_decoder *pD, int component_id, int 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); + p[g_ZAG[k]] = static_cast<jpgd_block_t>(static_cast<unsigned int>(s) << pD->m_successive_low); } else { if (r == 15) { if ((k += 15) > 63) pD->stop_decoding(JPGD_DECODE_ERROR); @@ -2607,7 +2607,7 @@ void jpeg_decoder::decode_block_ac_refine(jpeg_decoder *pD, int component_id, in { int s, k, r; int p1 = 1 << pD->m_successive_low; - int m1 = (-1) << pD->m_successive_low; + int m1 = static_cast<unsigned int>(-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); diff --git a/thirdparty/thorvg/src/loaders/png/tvgLodePng.cpp b/thirdparty/thorvg/src/loaders/png/tvgLodePng.cpp index f2dfa02875..5c01c5a1e2 100644 --- a/thirdparty/thorvg/src/loaders/png/tvgLodePng.cpp +++ b/thirdparty/thorvg/src/loaders/png/tvgLodePng.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/png/tvgLodePng.h b/thirdparty/thorvg/src/loaders/png/tvgLodePng.h index 02e1feeec5..c9f0e56ab6 100644 --- a/thirdparty/thorvg/src/loaders/png/tvgLodePng.h +++ b/thirdparty/thorvg/src/loaders/png/tvgLodePng.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp index 3cc08e902b..3e293176b7 100644 --- a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp +++ b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.h b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.h index 34dbeed012..8f07f6418f 100644 --- a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.h +++ b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp index d7d425b119..2da399d8c3 100644 --- a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp +++ b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h index 20fa332981..e4f3423b41 100644 --- a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h +++ b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.cpp new file mode 100644 index 0000000000..e537cfa27f --- /dev/null +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.cpp @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2022 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 "tvgSvgCssStyle.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static void _copyStyle(SvgStyleProperty* to, const SvgStyleProperty* from) +{ + if (from == nullptr) return; + //Copy the properties of 'from' only if they were explicitly set (not the default ones). + if (from->curColorSet && !((int)to->flags & (int)SvgStyleFlags::Color)) { + to->color = from->color; + to->curColorSet = true; + to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::Color); + } + //Fill + if (((int)from->fill.flags & (int)SvgFillFlags::Paint) && !((int)to->flags & (int)SvgStyleFlags::Fill)) { + to->fill.paint.color = from->fill.paint.color; + to->fill.paint.none = from->fill.paint.none; + to->fill.paint.curColor = from->fill.paint.curColor; + if (from->fill.paint.url) to->fill.paint.url = strdup(from->fill.paint.url); + to->fill.flags = (SvgFillFlags)((int)to->fill.flags | (int)SvgFillFlags::Paint); + to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::Fill); + } + if (((int)from->fill.flags & (int)SvgFillFlags::Opacity) && !((int)to->flags & (int)SvgStyleFlags::FillOpacity)) { + to->fill.opacity = from->fill.opacity; + to->fill.flags = (SvgFillFlags)((int)to->fill.flags | (int)SvgFillFlags::Opacity); + to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::FillOpacity); + } + if (((int)from->fill.flags & (int)SvgFillFlags::FillRule) && !((int)to->flags & (int)SvgStyleFlags::FillRule)) { + to->fill.fillRule = from->fill.fillRule; + to->fill.flags = (SvgFillFlags)((int)to->fill.flags | (int)SvgFillFlags::FillRule); + to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::FillRule); + } + //Stroke + if (((int)from->stroke.flags & (int)SvgStrokeFlags::Paint) && !((int)to->flags & (int)SvgStyleFlags::Stroke)) { + to->stroke.paint.color = from->stroke.paint.color; + to->stroke.paint.none = from->stroke.paint.none; + to->stroke.paint.curColor = from->stroke.paint.curColor; + if (from->stroke.paint.url) to->stroke.paint.url = strdup(from->stroke.paint.url); + to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)SvgStrokeFlags::Paint); + to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::Stroke); + } + if (((int)from->stroke.flags & (int)SvgStrokeFlags::Opacity) && !((int)to->flags & (int)SvgStyleFlags::StrokeOpacity)) { + to->stroke.opacity = from->stroke.opacity; + to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)SvgStrokeFlags::Opacity); + to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::StrokeOpacity); + } + if (((int)from->stroke.flags & (int)SvgStrokeFlags::Width) && !((int)to->flags & (int)SvgStyleFlags::StrokeWidth)) { + to->stroke.width = from->stroke.width; + to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)SvgStrokeFlags::Width); + to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::StrokeWidth); + } + if (((int)from->stroke.flags & (int)SvgStrokeFlags::Dash) && !((int)to->flags & (int)SvgStyleFlags::StrokeDashArray)) { + if (from->stroke.dash.array.count > 0) { + to->stroke.dash.array.clear(); + to->stroke.dash.array.reserve(from->stroke.dash.array.count); + for (uint32_t i = 0; i < from->stroke.dash.array.count; ++i) { + to->stroke.dash.array.push(from->stroke.dash.array.data[i]); + } + to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)SvgStrokeFlags::Dash); + to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::StrokeDashArray); + } + } + if (((int)from->stroke.flags & (int)SvgStrokeFlags::Cap) && !((int)to->flags & (int)SvgStyleFlags::StrokeLineCap)) { + to->stroke.cap = from->stroke.cap; + to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)SvgStrokeFlags::Cap); + to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::StrokeLineCap); + } + if (((int)from->stroke.flags & (int)SvgStrokeFlags::Join) && !((int)to->flags & (int)SvgStyleFlags::StrokeLineJoin)) { + to->stroke.join = from->stroke.join; + to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)SvgStrokeFlags::Join); + to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::StrokeLineJoin); + } + //Opacity + //TODO: it can be set to be 255 and shouldn't be changed by attribute 'opacity' + if (from->opacity < 255 && !((int)to->flags & (int)SvgStyleFlags::Opacity)) { + to->opacity = from->opacity; + to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::Opacity); + } +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +void cssCopyStyleAttr(SvgNode* to, const SvgNode* from) +{ + //Copy matrix attribute + if (from->transform && !((int)to->style->flags & (int)SvgStyleFlags::Transform)) { + to->transform = (Matrix*)malloc(sizeof(Matrix)); + if (to->transform) { + *to->transform = *from->transform; + to->style->flags = (SvgStyleFlags)((int)to->style->flags | (int)SvgStyleFlags::Transform); + } + } + //Copy style attribute + _copyStyle(to->style, from->style); + + 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); +} + + +SvgNode* cssFindStyleNode(const SvgNode* style, const char* title, SvgNodeType type) +{ + if (!style) return nullptr; + + auto child = style->child.data; + for (uint32_t i = 0; i < style->child.count; ++i, ++child) { + if ((*child)->type == type) { + if ((!title && !(*child)->id) || (title && (*child)->id && !strcmp((*child)->id, title))) return (*child); + } + } + return nullptr; +} + + +SvgNode* cssFindStyleNode(const SvgNode* style, const char* title) +{ + if (!style) return nullptr; + + auto child = style->child.data; + for (uint32_t i = 0; i < style->child.count; ++i, ++child) { + if ((*child)->type == SvgNodeType::CssStyle) { + if ((title && (*child)->id && !strcmp((*child)->id, title))) return (*child); + } + } + return nullptr; +} + + +void cssUpdateStyle(SvgNode* doc, SvgNode* style) +{ + if (doc->child.count > 0) { + auto child = doc->child.data; + for (uint32_t i = 0; i < doc->child.count; ++i, ++child) { + if (auto cssNode = cssFindStyleNode(style, nullptr, (*child)->type)) { + cssCopyStyleAttr(*child, cssNode); + } + if (auto cssNode = cssFindStyleNode(style, nullptr)) { + cssCopyStyleAttr(*child, cssNode); + } + cssUpdateStyle(*child, style); + } + } +} + + +void cssApplyStyleToPostponeds(Array<SvgNodeIdPair>& postponeds, SvgNode* style) +{ + for (uint32_t i = 0; i < postponeds.count; ++i) { + auto nodeIdPair = postponeds.data[i]; + + //css styling: tag.name has higher priority than .name + if (auto cssNode = cssFindStyleNode(style, nodeIdPair.id, nodeIdPair.node->type)) { + cssCopyStyleAttr(nodeIdPair.node, cssNode); + } + if (auto cssNode = cssFindStyleNode(style, nodeIdPair.id)) { + cssCopyStyleAttr(nodeIdPair.node, cssNode); + } + } +}
\ No newline at end of file diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.h new file mode 100644 index 0000000000..66477c1a32 --- /dev/null +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022 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_CSS_STYLE_H_ +#define _TVG_SVG_CSS_STYLE_H_ + +#include "tvgSvgLoaderCommon.h" + +void cssCopyStyleAttr(SvgNode* to, const SvgNode* from); +SvgNode* cssFindStyleNode(const SvgNode* style, const char* title, SvgNodeType type); +SvgNode* cssFindStyleNode(const SvgNode* style, const char* title); +void cssUpdateStyle(SvgNode* doc, SvgNode* style); +void cssApplyStyleToPostponeds(Array<SvgNodeIdPair>& postponeds, SvgNode* style); + +#endif //_TVG_SVG_CSS_STYLE_H_ diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp index 08b3308165..a842b7fa8b 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 @@ -60,6 +60,8 @@ #include "tvgSvgLoader.h" #include "tvgSvgSceneBuilder.h" #include "tvgSvgUtil.h" +#include "tvgSvgCssStyle.h" +#include "tvgMath.h" /************************************************************************/ /* Internal Class Implementation */ @@ -75,11 +77,10 @@ #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 bool (*parseAttributes)(const char* buf, unsigned bufLength, simpleXMLAttributeCb func, const void* data); +typedef SvgNode* (*FactoryMethod)(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func); 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)) { @@ -200,6 +201,14 @@ static int _toOpacity(const char* str) } +static SvgMaskType _toMaskType(const char* str) +{ + if (!strcmp(str, "Alpha")) return SvgMaskType::Alpha; + + return SvgMaskType::Luminance; +} + + #define _PARSE_TAG(Type, Name, Name1, Tags_Array, Default) \ static Type _to##Name1(const char* str) \ { \ @@ -726,6 +735,12 @@ error: } +static void _postpone(Array<SvgNodeIdPair>& nodes, SvgNode *node, char* id) +{ + nodes.push({node, id}); +} + + /* // TODO - remove? static constexpr struct @@ -786,14 +801,12 @@ static bool _attrParseSvgNode(void* data, const char* key, const char* value) } else if (!strcmp(key, "preserveAspectRatio")) { if (!strcmp(value, "none")) doc->preserveAspect = false; } else if (!strcmp(key, "style")) { - return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); - } + return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); #ifdef THORVG_LOG_ENABLED - else if ((!strcmp(key, "x") || !strcmp(key, "y")) && fabsf(svgUtilStrtof(value, nullptr)) > FLT_EPSILON) { + } 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 { + } else { return _parseStyleAttr(loader, key, value, false); } return true; @@ -922,6 +935,12 @@ static void _handleMaskAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, con } +static void _handleMaskTypeAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + node->node.mask.type = _toMaskType(value); +} + + static void _handleDisplayAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) { //TODO : The display attribute can have various values as well as "none". @@ -933,6 +952,29 @@ static void _handleDisplayAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, } +static void _handleCssClassAttr(SvgLoaderData* loader, SvgNode* node, const char* value) +{ + auto cssClass = &node->style->cssClass; + + if (*cssClass && value) free(*cssClass); + *cssClass = _copyId(value); + + bool cssClassFound = false; + + //css styling: tag.name has higher priority than .name + if (auto cssNode = cssFindStyleNode(loader->cssStyle, *cssClass, node->type)) { + cssClassFound = true; + cssCopyStyleAttr(node, cssNode); + } + if (auto cssNode = cssFindStyleNode(loader->cssStyle, *cssClass)) { + cssClassFound = true; + cssCopyStyleAttr(node, cssNode); + } + + if (!cssClassFound) _postpone(loader->nodesToStyle, node, *cssClass); +} + + typedef void (*styleMethod)(SvgLoaderData* loader, SvgNode* node, const char* value); #define STYLE_DEF(Name, Name1, Flag) { #Name, sizeof(#Name), _handle##Name1##Attr, Flag } @@ -959,6 +1001,7 @@ static constexpr struct STYLE_DEF(transform, Transform, SvgStyleFlags::Transform), STYLE_DEF(clip-path, ClipPath, SvgStyleFlags::ClipPath), STYLE_DEF(mask, Mask, SvgStyleFlags::Mask), + STYLE_DEF(mask-type, MaskType, SvgStyleFlags::MaskType), STYLE_DEF(display, Display, SvgStyleFlags::Display) }; @@ -1006,12 +1049,14 @@ static bool _attrParseGNode(void* data, const char* key, const char* value) SvgNode* node = loader->svgParse->node; if (!strcmp(key, "style")) { - return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + return simpleXmlParseW3CAttribute(value, strlen(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, "class")) { + _handleCssClassAttr(loader, node, value); } else if (!strcmp(key, "clip-path")) { _handleClipPathAttr(loader, node, value); } else if (!strcmp(key, "mask")) { @@ -1030,17 +1075,19 @@ static bool _attrParseClipPathNode(void* data, const char* key, const char* valu { SvgLoaderData* loader = (SvgLoaderData*)data; SvgNode* node = loader->svgParse->node; - SvgCompositeNode* comp = &(node->node.comp); + SvgClipNode* clip = &(node->node.clip); if (!strcmp(key, "style")) { - return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + return simpleXmlParseW3CAttribute(value, strlen(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, "class")) { + _handleCssClassAttr(loader, node, value); } else if (!strcmp(key, "clipPathUnits")) { - if (!strcmp(value, "objectBoundingBox")) comp->userSpace = false; + if (!strcmp(value, "objectBoundingBox")) clip->userSpace = false; } else { return _parseStyleAttr(loader, key, value, false); } @@ -1052,17 +1099,36 @@ 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); + SvgMaskNode* mask = &(node->node.mask); if (!strcmp(key, "style")) { - return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + return simpleXmlParseW3CAttribute(value, strlen(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, "class")) { + _handleCssClassAttr(loader, node, value); } else if (!strcmp(key, "maskContentUnits")) { - if (!strcmp(value, "objectBoundingBox")) comp->userSpace = false; + if (!strcmp(value, "objectBoundingBox")) mask->userSpace = false; + } else if (!strcmp(key, "mask-type")) { + mask->type = _toMaskType(value); + } else { + return _parseStyleAttr(loader, key, value, false); + } + return true; +} + + +static bool _attrParseCssStyleNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + + if (!strcmp(key, "id")) { + if (node->id && value) free(node->id); + node->id = _copyId(value); } else { return _parseStyleAttr(loader, key, value, false); } @@ -1070,6 +1136,31 @@ static bool _attrParseMaskNode(void* data, const char* key, const char* value) } +static bool _attrParseSymbolNode(void* data, const char* key, const char* value) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + SvgNode* node = loader->svgParse->node; + SvgSymbolNode* symbol = &(node->node.symbol); + + if (!strcmp(key, "viewBox")) { + if (!_parseNumber(&value, &symbol->vx) || !_parseNumber(&value, &symbol->vy)) return false; + if (!_parseNumber(&value, &symbol->vw) || !_parseNumber(&value, &symbol->vh)) return false; + } else if (!strcmp(key, "width")) { + symbol->w = _toFloat(loader->svgParse, value, SvgParserLengthType::Horizontal); + } else if (!strcmp(key, "height")) { + symbol->h = _toFloat(loader->svgParse, value, SvgParserLengthType::Vertical); + } else if (!strcmp(key, "preserveAspectRatio")) { + if (!strcmp(value, "none")) symbol->preserveAspect = false; + } else if (!strcmp(key, "overflow")) { + if (!strcmp(value, "visible")) symbol->overflowVisible = true; + } else { + return _attrParseGNode(data, key, value); + } + + return true; +} + + static SvgNode* _createNode(SvgNode* parent, SvgNodeType type) { SvgNode* node = (SvgNode*)calloc(1, sizeof(SvgNode)); @@ -1121,7 +1212,7 @@ static SvgNode* _createNode(SvgNode* parent, SvgNodeType type) } -static SvgNode* _createDefsNode(TVG_UNUSED SvgLoaderData* loader, TVG_UNUSED SvgNode* parent, const char* buf, unsigned bufLength) +static SvgNode* _createDefsNode(TVG_UNUSED SvgLoaderData* loader, TVG_UNUSED SvgNode* parent, const char* buf, unsigned bufLength, TVG_UNUSED parseAttributes func) { if (loader->def && loader->doc->node.doc.defs) return loader->def; SvgNode* node = _createNode(nullptr, SvgNodeType::Defs); @@ -1132,17 +1223,17 @@ static SvgNode* _createDefsNode(TVG_UNUSED SvgLoaderData* loader, TVG_UNUSED Svg } -static SvgNode* _createGNode(TVG_UNUSED SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +static SvgNode* _createGNode(TVG_UNUSED SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) { loader->svgParse->node = _createNode(parent, SvgNodeType::G); if (!loader->svgParse->node) return nullptr; - simpleXmlParseAttributes(buf, bufLength, _attrParseGNode, loader); + func(buf, bufLength, _attrParseGNode, loader); return loader->svgParse->node; } -static SvgNode* _createSvgNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +static SvgNode* _createSvgNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) { loader->svgParse->node = _createNode(parent, SvgNodeType::Doc); if (!loader->svgParse->node) return nullptr; @@ -1152,7 +1243,7 @@ static SvgNode* _createSvgNode(SvgLoaderData* loader, SvgNode* parent, const cha loader->svgParse->global.h = 0; doc->preserveAspect = true; - simpleXmlParseAttributes(buf, bufLength, _attrParseSvgNode, loader); + func(buf, bufLength, _attrParseSvgNode, loader); if (loader->svgParse->global.w == 0) { if (doc->w < FLT_EPSILON) loader->svgParse->global.w = 1; @@ -1167,32 +1258,60 @@ static SvgNode* _createSvgNode(SvgLoaderData* loader, SvgNode* parent, const cha } -static SvgNode* _createMaskNode(SvgLoaderData* loader, SvgNode* parent, TVG_UNUSED const char* buf, TVG_UNUSED unsigned bufLength) +static SvgNode* _createMaskNode(SvgLoaderData* loader, SvgNode* parent, TVG_UNUSED const char* buf, TVG_UNUSED unsigned bufLength, parseAttributes func) { loader->svgParse->node = _createNode(parent, SvgNodeType::Mask); if (!loader->svgParse->node) return nullptr; - loader->svgParse->node->node.comp.userSpace = true; + loader->svgParse->node->node.mask.userSpace = true; + loader->svgParse->node->node.mask.type = SvgMaskType::Luminance; - simpleXmlParseAttributes(buf, bufLength, _attrParseMaskNode, loader); + func(buf, bufLength, _attrParseMaskNode, loader); return loader->svgParse->node; } -static SvgNode* _createClipPathNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +static SvgNode* _createClipPathNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) { 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; + loader->svgParse->node->node.clip.userSpace = true; - simpleXmlParseAttributes(buf, bufLength, _attrParseClipPathNode, loader); + func(buf, bufLength, _attrParseClipPathNode, loader); return loader->svgParse->node; } + +static SvgNode* _createCssStyleNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::CssStyle); + if (!loader->svgParse->node) return nullptr; + + func(buf, bufLength, _attrParseCssStyleNode, loader); + + return loader->svgParse->node; +} + + +static SvgNode* _createSymbolNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) +{ + loader->svgParse->node = _createNode(parent, SvgNodeType::Symbol); + if (!loader->svgParse->node) return nullptr; + + loader->svgParse->node->display = false; + loader->svgParse->node->node.symbol.preserveAspect = true; + loader->svgParse->node->node.symbol.overflowVisible = false; + + func(buf, bufLength, _attrParseSymbolNode, loader); + + return loader->svgParse->node; +} + + static bool _attrParsePathNode(void* data, const char* key, const char* value) { SvgLoaderData* loader = (SvgLoaderData*)data; @@ -1203,7 +1322,7 @@ static bool _attrParsePathNode(void* data, const char* key, const char* value) //Temporary: need to copy path->path = _copyId(value); } else if (!strcmp(key, "style")) { - return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); } else if (!strcmp(key, "clip-path")) { _handleClipPathAttr(loader, node, value); } else if (!strcmp(key, "mask")) { @@ -1211,6 +1330,8 @@ static bool _attrParsePathNode(void* data, const char* key, const char* value) } else if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else { return _parseStyleAttr(loader, key, value, false); } @@ -1218,13 +1339,13 @@ static bool _attrParsePathNode(void* data, const char* key, const char* value) } -static SvgNode* _createPathNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +static SvgNode* _createPathNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) { loader->svgParse->node = _createNode(parent, SvgNodeType::Path); if (!loader->svgParse->node) return nullptr; - simpleXmlParseAttributes(buf, bufLength, _attrParsePathNode, loader); + func(buf, bufLength, _attrParsePathNode, loader); return loader->svgParse->node; } @@ -1263,7 +1384,7 @@ static bool _attrParseCircleNode(void* data, const char* key, const char* value) } if (!strcmp(key, "style")) { - return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); } else if (!strcmp(key, "clip-path")) { _handleClipPathAttr(loader, node, value); } else if (!strcmp(key, "mask")) { @@ -1271,6 +1392,8 @@ static bool _attrParseCircleNode(void* data, const char* key, const char* value) } else if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else { return _parseStyleAttr(loader, key, value, false); } @@ -1278,13 +1401,13 @@ static bool _attrParseCircleNode(void* data, const char* key, const char* value) } -static SvgNode* _createCircleNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +static SvgNode* _createCircleNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) { loader->svgParse->node = _createNode(parent, SvgNodeType::Circle); if (!loader->svgParse->node) return nullptr; - simpleXmlParseAttributes(buf, bufLength, _attrParseCircleNode, loader); + func(buf, bufLength, _attrParseCircleNode, loader); return loader->svgParse->node; } @@ -1325,8 +1448,10 @@ static bool _attrParseEllipseNode(void* data, const char* key, const char* value if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else if (!strcmp(key, "style")) { - return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); } else if (!strcmp(key, "clip-path")) { _handleClipPathAttr(loader, node, value); } else if (!strcmp(key, "mask")) { @@ -1338,13 +1463,13 @@ static bool _attrParseEllipseNode(void* data, const char* key, const char* value } -static SvgNode* _createEllipseNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +static SvgNode* _createEllipseNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) { loader->svgParse->node = _createNode(parent, SvgNodeType::Ellipse); if (!loader->svgParse->node) return nullptr; - simpleXmlParseAttributes(buf, bufLength, _attrParseEllipseNode, loader); + func(buf, bufLength, _attrParseEllipseNode, loader); return loader->svgParse->node; } @@ -1400,7 +1525,7 @@ static bool _attrParsePolygonNode(void* data, const char* key, const char* value if (!strcmp(key, "points")) { return _attrParsePolygonPoints(value, &polygon->points, &polygon->pointsCount); } else if (!strcmp(key, "style")) { - return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); } else if (!strcmp(key, "clip-path")) { _handleClipPathAttr(loader, node, value); } else if (!strcmp(key, "mask")) { @@ -1408,6 +1533,8 @@ static bool _attrParsePolygonNode(void* data, const char* key, const char* value } else if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else { return _parseStyleAttr(loader, key, value, false); } @@ -1415,24 +1542,24 @@ static bool _attrParsePolygonNode(void* data, const char* key, const char* value } -static SvgNode* _createPolygonNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +static SvgNode* _createPolygonNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) { loader->svgParse->node = _createNode(parent, SvgNodeType::Polygon); if (!loader->svgParse->node) return nullptr; - simpleXmlParseAttributes(buf, bufLength, _attrParsePolygonNode, loader); + func(buf, bufLength, _attrParsePolygonNode, loader); return loader->svgParse->node; } -static SvgNode* _createPolylineNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +static SvgNode* _createPolylineNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) { loader->svgParse->node = _createNode(parent, SvgNodeType::Polyline); if (!loader->svgParse->node) return nullptr; - simpleXmlParseAttributes(buf, bufLength, _attrParsePolygonNode, loader); + func(buf, bufLength, _attrParsePolygonNode, loader); return loader->svgParse->node; } @@ -1482,8 +1609,10 @@ static bool _attrParseRectNode(void* data, const char* key, const char* value) if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else if (!strcmp(key, "style")) { - ret = simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + ret = simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); } else if (!strcmp(key, "clip-path")) { _handleClipPathAttr(loader, node, value); } else if (!strcmp(key, "mask")) { @@ -1496,7 +1625,7 @@ static bool _attrParseRectNode(void* data, const char* key, const char* value) } -static SvgNode* _createRectNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +static SvgNode* _createRectNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) { loader->svgParse->node = _createNode(parent, SvgNodeType::Rect); @@ -1504,7 +1633,7 @@ static SvgNode* _createRectNode(SvgLoaderData* loader, SvgNode* parent, const ch loader->svgParse->node->node.rect.hasRx = loader->svgParse->node->node.rect.hasRy = false; - simpleXmlParseAttributes(buf, bufLength, _attrParseRectNode, loader); + func(buf, bufLength, _attrParseRectNode, loader); return loader->svgParse->node; } @@ -1545,8 +1674,10 @@ static bool _attrParseLineNode(void* data, const char* key, const char* value) if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else if (!strcmp(key, "style")) { - return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); } else if (!strcmp(key, "clip-path")) { _handleClipPathAttr(loader, node, value); } else if (!strcmp(key, "mask")) { @@ -1558,13 +1689,13 @@ static bool _attrParseLineNode(void* data, const char* key, const char* value) } -static SvgNode* _createLineNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +static SvgNode* _createLineNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) { loader->svgParse->node = _createNode(parent, SvgNodeType::Line); if (!loader->svgParse->node) return nullptr; - simpleXmlParseAttributes(buf, bufLength, _attrParseLineNode, loader); + func(buf, bufLength, _attrParseLineNode, loader); return loader->svgParse->node; } @@ -1616,12 +1747,16 @@ static bool _attrParseImageNode(void* data, const char* key, const char* value) } else if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else if (!strcmp(key, "style")) { - return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); + return simpleXmlParseW3CAttribute(value, strlen(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, "transform")) { + node->transform = _parseTransformationMatrix(value); } else { return _parseStyleAttr(loader, key, value); } @@ -1629,13 +1764,13 @@ static bool _attrParseImageNode(void* data, const char* key, const char* value) } -static SvgNode* _createImageNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +static SvgNode* _createImageNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) { loader->svgParse->node = _createNode(parent, SvgNodeType::Image); if (!loader->svgParse->node) return nullptr; - simpleXmlParseAttributes(buf, bufLength, _attrParseImageNode, loader); + func(buf, bufLength, _attrParseImageNode, loader); return loader->svgParse->node; } @@ -1941,12 +2076,6 @@ static void _cloneNode(SvgNode* from, SvgNode* parent, int depth) } -static void _postponeCloneNode(SvgLoaderData* loader, SvgNode *node, char* id) -{ - loader->cloneNodes.push({node, id}); -} - - static void _clonePostponedNodes(Array<SvgNodeIdPair>* cloneNodes, SvgNode* doc) { for (uint32_t i = 0; i < cloneNodes->count; ++i) { @@ -1955,6 +2084,9 @@ static void _clonePostponedNodes(Array<SvgNodeIdPair>* cloneNodes, SvgNode* doc) auto nodeFrom = _findChildById(defs, nodeIdPair.id); if (!nodeFrom) nodeFrom = _findChildById(doc, nodeIdPair.id); _cloneNode(nodeFrom, nodeIdPair.node, 0); + if (nodeFrom && nodeFrom->type == SvgNodeType::Symbol && nodeIdPair.node->type == SvgNodeType::Use) { + nodeIdPair.node->node.use.symbol = nodeFrom; + } free(nodeIdPair.id); } } @@ -1967,10 +2099,10 @@ static constexpr struct 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)} + {"x", SvgParserLengthType::Horizontal, sizeof("x"), offsetof(SvgUseNode, x)}, + {"y", SvgParserLengthType::Vertical, sizeof("y"), offsetof(SvgUseNode, y)}, + {"width", SvgParserLengthType::Horizontal, sizeof("width"), offsetof(SvgUseNode, w)}, + {"height", SvgParserLengthType::Vertical, sizeof("height"), offsetof(SvgUseNode, h)} }; @@ -1986,6 +2118,10 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value) 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); + + if (useTags[i].offset == offsetof(SvgUseNode, w)) use->isWidthSet = true; + else if (useTags[i].offset == offsetof(SvgUseNode, h)) use->isHeightSet = true; + return true; } } @@ -1996,12 +2132,13 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value) nodeFrom = _findChildById(defs, id); if (nodeFrom) { _cloneNode(nodeFrom, node, 0); + if (nodeFrom->type == SvgNodeType::Symbol) use->symbol = nodeFrom; 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); + _postpone(loader->cloneNodes, node, id); } } else { return _attrParseGNode(data, key, value); @@ -2010,16 +2147,20 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value) } -static SvgNode* _createUseNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength) +static SvgNode* _createUseNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func) { loader->svgParse->node = _createNode(parent, SvgNodeType::Use); if (!loader->svgParse->node) return nullptr; - simpleXmlParseAttributes(buf, bufLength, _attrParseUseNode, loader); + loader->svgParse->node->node.use.isWidthSet = false; + loader->svgParse->node->node.use.isHeightSet = false; + + func(buf, bufLength, _attrParseUseNode, loader); return loader->svgParse->node; } + //TODO: Implement 'text' primitive static constexpr struct { @@ -2049,7 +2190,9 @@ static constexpr struct {"g", sizeof("g"), _createGNode}, {"svg", sizeof("svg"), _createSvgNode}, {"mask", sizeof("mask"), _createMaskNode}, - {"clipPath", sizeof("clipPath"), _createClipPathNode} + {"clipPath", sizeof("clipPath"), _createClipPathNode}, + {"style", sizeof("style"), _createCssStyleNode}, + {"symbol", sizeof("symbol"), _createSymbolNode} }; @@ -2204,8 +2347,8 @@ static bool _attrParseRadialGradientNode(void* data, const char* key, const char } else if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) { if (grad->ref && value) free(grad->ref); grad->ref = _idFromHref(value); - } else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse")) { - grad->userSpace = true; + } else if (!strcmp(key, "gradientUnits")) { + if (!strcmp(value, "userSpaceOnUse")) grad->userSpace = true; } else if (!strcmp(key, "gradientTransform")) { grad->transform = _parseTransformationMatrix(value); } else { @@ -2291,7 +2434,7 @@ static bool _attrParseStops(void* data, const char* key, const char* value) _toColor(value, &stop->r, &stop->g, &stop->b, nullptr); } } else if (!strcmp(key, "style")) { - simpleXmlParseW3CAttribute(value, _attrParseStopsStyle, data); + simpleXmlParseW3CAttribute(value, strlen(value), _attrParseStopsStyle, data); } else { return false; } @@ -2394,8 +2537,8 @@ static bool _attrParseLinearGradientNode(void* data, const char* key, const char } else if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) { if (grad->ref && value) free(grad->ref); grad->ref = _idFromHref(value); - } else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse")) { - grad->userSpace = true; + } else if (!strcmp(key, "gradientUnits")) { + if (!strcmp(value, "userSpaceOnUse")) grad->userSpace = true; } else if (!strcmp(key, "gradientTransform")) { grad->transform = _parseTransformationMatrix(value); } else { @@ -2479,11 +2622,13 @@ static constexpr struct {"svg", sizeof("svg")}, {"defs", sizeof("defs")}, {"mask", sizeof("mask")}, - {"clipPath", sizeof("clipPath")} + {"clipPath", sizeof("clipPath")}, + {"style", sizeof("style")}, + {"symbol", sizeof("symbol")} }; -static void _svgLoaderParerXmlClose(SvgLoaderData* loader, const char* content) +static void _svgLoaderParserXmlClose(SvgLoaderData* loader, const char* content) { content = _skipSpace(content, nullptr); @@ -2531,13 +2676,20 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content, if (empty) return; if (!loader->doc) { if (strcmp(tagName, "svg")) return; //Not a valid svg document - node = method(loader, nullptr, attrs, attrsLength); + node = method(loader, nullptr, attrs, attrsLength, simpleXmlParseAttributes); 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 (!strcmp(tagName, "style")) { + node = method(loader, nullptr, attrs, attrsLength, simpleXmlParseAttributes); + loader->cssStyle = node; + loader->doc->node.doc.style = node; + loader->style = true; + } else { + node = method(loader, parent, attrs, attrsLength, simpleXmlParseAttributes); + } } if (!node) return; @@ -2547,7 +2699,7 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content, } 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); + node = method(loader, parent, attrs, attrsLength, simpleXmlParseAttributes); } else if ((gradientMethod = _findGradientFactory(tagName))) { SvgStyleGradient* gradient; gradient = gradientMethod(loader, attrs, attrsLength); @@ -2578,6 +2730,42 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content, } +static void _svgLoaderParserXmlCssStyle(SvgLoaderData* loader, const char* content, unsigned int length) +{ + char* tag; + char* name; + const char* attrs = nullptr; + unsigned int attrsLength = 0; + + FactoryMethod method; + GradientFactoryMethod gradientMethod; + SvgNode *node = nullptr; + + while (auto next = simpleXmlParseCSSAttribute(content, length, &tag, &name, &attrs, &attrsLength)) { + if ((method = _findGroupFactory(tag))) { + if ((node = method(loader, loader->cssStyle, attrs, attrsLength, simpleXmlParseW3CAttribute))) node->id = _copyId(name); + } else if ((method = _findGraphicsFactory(tag))) { + if ((node = method(loader, loader->cssStyle, attrs, attrsLength, simpleXmlParseW3CAttribute))) node->id = _copyId(name); + } else if ((gradientMethod = _findGradientFactory(tag))) { + TVGLOG("SVG", "Unsupported elements used in the internal CSS style sheets [Elements: %s]", tag); + } else if (!strcmp(tag, "stop")) { + TVGLOG("SVG", "Unsupported elements used in the internal CSS style sheets [Elements: %s]", tag); + } else if (!strcmp(tag, "all")) { + if ((node = _createCssStyleNode(loader, loader->cssStyle, attrs, attrsLength, simpleXmlParseW3CAttribute))) node->id = _copyId(name); + } else if (!isIgnoreUnsupportedLogElements(tag)) { + TVGLOG("SVG", "Unsupported elements used in the internal CSS style sheets [Elements: %s]", tag); + } + + length -= next - content; + content = next; + + free(tag); + free(name); + } + loader->style = false; +} + + static bool _svgLoaderParser(void* data, SimpleXMLType type, const char* content, unsigned int length) { SvgLoaderData* loader = (SvgLoaderData*)data; @@ -2592,11 +2780,14 @@ static bool _svgLoaderParser(void* data, SimpleXMLType type, const char* content break; } case SimpleXMLType::Close: { - _svgLoaderParerXmlClose(loader, content); + _svgLoaderParserXmlClose(loader, content); break; } case SimpleXMLType::Data: - case SimpleXMLType::CData: + case SimpleXMLType::CData: { + if (loader->style) _svgLoaderParserXmlCssStyle(loader, content, length); + break; + } case SimpleXMLType::DoctypeChild: { break; } @@ -2619,7 +2810,7 @@ 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->display && node->type != SvgNodeType::ClipPath && node->type != SvgNodeType::Symbol) 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); @@ -2749,6 +2940,7 @@ static void _freeNodeStyle(SvgStyleProperty* style) //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); + free(style->cssClass); if (style->fill.paint.gradient) { style->fill.paint.gradient->clear(); @@ -2793,6 +2985,7 @@ static void _freeNode(SvgNode* node) } case SvgNodeType::Doc: { _freeNode(node->node.doc.defs); + _freeNode(node->node.doc.style); break; } case SvgNodeType::Defs: { @@ -2846,7 +3039,7 @@ static bool _svgLoaderParserForValidCheckXmlOpen(SvgLoaderData* loader, const ch if ((method = _findGroupFactory(tagName))) { if (!loader->doc) { if (strcmp(tagName, "svg")) return true; //Not a valid svg document - node = method(loader, nullptr, attrs, attrsLength); + node = method(loader, nullptr, attrs, attrsLength, simpleXmlParseAttributes); loader->doc = node; loader->stack.push(node); return false; @@ -2906,16 +3099,20 @@ 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; - _updateComposite(loaderData.doc, loaderData.doc); - if (defs) _updateComposite(loaderData.doc, defs); + if (loaderData.nodesToStyle.count > 0) cssApplyStyleToPostponeds(loaderData.nodesToStyle, loaderData.cssStyle); + if (loaderData.cssStyle) cssUpdateStyle(loaderData.doc, loaderData.cssStyle); if (loaderData.cloneNodes.count > 0) _clonePostponedNodes(&loaderData.cloneNodes, loaderData.doc); + _updateComposite(loaderData.doc, loaderData.doc); + if (defs) _updateComposite(loaderData.doc, defs); + if (loaderData.gradients.count > 0) _updateGradient(loaderData.doc, &loaderData.gradients); if (defs) _updateGradient(loaderData.doc, &defs->node.defs.gradients); + + _updateStyle(loaderData.doc, nullptr); } root = svgSceneBuild(loaderData.doc, vx, vy, vw, vh, w, h, preserveAspect, svgPath); } diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h index 468f05801d..093fb671b3 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h index cceef915f0..1f25e82adc 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 @@ -51,6 +51,8 @@ enum class SvgNodeType Video, ClipPath, Mask, + CssStyle, + Symbol, Unknown }; @@ -111,7 +113,8 @@ enum class SvgStyleFlags Transform = 0x800, ClipPath = 0x1000, Mask = 0x2000, - Display = 0x4000 + MaskType = 0x4000, + Display = 0x8000 }; enum class SvgStopStyleFlags @@ -127,6 +130,12 @@ enum class SvgFillRule OddEven = 1 }; +enum class SvgMaskType +{ + Luminance = 0, + Alpha +}; + //Length type to recalculate %, pt, pc, mm, cm etc enum class SvgParserLengthType { @@ -145,6 +154,7 @@ struct SvgDocNode float vw; float vh; SvgNode* defs; + SvgNode* style; bool preserveAspect; }; @@ -157,12 +167,22 @@ struct SvgDefsNode Array<SvgStyleGradient*> gradients; }; +struct SvgSymbolNode +{ + float w, h; + float vx, vy, vw, vh; + bool preserveAspect; + bool overflowVisible; +}; + struct SvgUseNode { float x, y, w, h; + bool isWidthSet; + bool isHeightSet; + SvgNode* symbol; }; - struct SvgEllipseNode { float cx; @@ -215,11 +235,21 @@ struct SvgPolygonNode float* points; }; -struct SvgCompositeNode +struct SvgClipNode { bool userSpace; }; +struct SvgMaskNode +{ + SvgMaskType type; + bool userSpace; +}; + +struct SvgCssStyleNode +{ +}; + struct SvgLinearGradient { float x1; @@ -328,6 +358,7 @@ struct SvgStyleProperty int opacity; SvgColor color; bool curColorSet; + char* cssClass; SvgStyleFlags flags; }; @@ -352,7 +383,10 @@ struct SvgNode SvgPathNode path; SvgLineNode line; SvgImageNode image; - SvgCompositeNode comp; + SvgMaskNode mask; + SvgClipNode clip; + SvgCssStyleNode cssStyle; + SvgSymbolNode symbol; } node; bool display; ~SvgNode(); @@ -384,15 +418,18 @@ struct SvgNodeIdPair struct SvgLoaderData { - Array<SvgNode *> stack = {nullptr, 0, 0}; + Array<SvgNode*> stack = {nullptr, 0, 0}; SvgNode* doc = nullptr; SvgNode* def = nullptr; + SvgNode* cssStyle = nullptr; Array<SvgStyleGradient*> gradients; SvgStyleGradient* latestGradient = nullptr; //For stops SvgParser* svgParse = nullptr; Array<SvgNodeIdPair> cloneNodes; + Array<SvgNodeIdPair> nodesToStyle; int level = 0; bool result = false; + bool style = false; }; /* diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp index 32685ee620..a09a2797d0 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.h index 7f26c4a213..8f5f9035dc 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp index ae17634f31..90705f2523 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 @@ -68,12 +68,12 @@ struct Box 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 unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, bool* isMaskWhite = nullptr); static inline bool _isGroupType(SvgNodeType type) { - if (type == SvgNodeType::Doc || type == SvgNodeType::G || type == SvgNodeType::Use || type == SvgNodeType::ClipPath) return true; + if (type == SvgNodeType::Doc || type == SvgNodeType::G || type == SvgNodeType::Use || type == SvgNodeType::ClipPath || type == SvgNodeType::Symbol) return true; return false; } @@ -276,15 +276,21 @@ static void _applyComposition(Paint* paint, const SvgNode* node, const Box& vBox 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 { + } 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); + bool isMaskWhite = true; + auto comp = _sceneBuildHelper(compNode, vBox, svgPath, true, &isMaskWhite); if (comp) { if (node->transform) comp->transform(*node->transform); - paint->composite(move(comp), CompositeMethod::AlphaMask); + + if (compNode->node.mask.type == SvgMaskType::Luminance && !isMaskWhite) { + paint->composite(move(comp), CompositeMethod::LumaMask); + } else { + paint->composite(move(comp), CompositeMethod::AlphaMask); + } } node->style->mask.applying = false; @@ -534,57 +540,137 @@ static unique_ptr<Picture> _imageBuildHelper(SvgNode* node, const Box& vBox, con string imagePath = href; if (strncmp(href, "/", 1)) { auto last = svgPath.find_last_of("/"); - imagePath = svgPath.substr(0, (last == string::npos ? 0 : last + 1 )) + imagePath; + imagePath = svgPath.substr(0, (last == string::npos ? 0 : last + 1)) + imagePath; } if (picture->load(imagePath) != Result::Success) return nullptr; } float w, h; + Matrix m = {1, 0, 0, 0, 1, 0, 0, 0, 1}; 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); + m = {sx, 0, node->node.image.x, 0, sy, node->node.image.y, 0, 0, 1}; } + if (node->transform) m = mathMultiply(node->transform, &m); + 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) +static unique_ptr<Scene> _useBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool* isMaskWhite) { - auto scene = _sceneBuildHelper(node, vBox, svgPath, false); + unique_ptr<Scene> finalScene; + auto scene = _sceneBuildHelper(node, vBox, svgPath, false, isMaskWhite); + + // mUseTransform = mUseTransform * mTranslate + Matrix mUseTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + if (node->transform) mUseTransform = *node->transform; if (node->node.use.x != 0.0f || node->node.use.y != 0.0f) { - scene->translate(node->node.use.x, node->node.use.y); + Matrix mTranslate = {1, 0, node->node.use.x, 0, 1, node->node.use.y, 0, 0, 1}; + mUseTransform = mathMultiply(&mUseTransform, &mTranslate); } - if (node->node.use.w > 0.0f && node->node.use.h > 0.0f) { - //TODO: handle width/height properties + + if (node->node.use.symbol) { + auto symbol = node->node.use.symbol->node.symbol; + + auto width = symbol.w; + if (node->node.use.isWidthSet) width = node->node.use.w; + auto height = symbol.h; + if (node->node.use.isHeightSet) height = node->node.use.h; + + Matrix mViewBox = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + if ((!mathEqual(width, symbol.vw) || !mathEqual(height, symbol.vh)) && symbol.vw > 0 && symbol.vh > 0) { + auto sx = width / symbol.vw; + auto sy = height / symbol.vh; + if (symbol.preserveAspect) { + if (sx < sy) sy = sx; + else sx = sy; + } + + auto tvx = symbol.vx * sx; + auto tvy = symbol.vy * sy; + auto tvw = symbol.vw * sx; + auto tvh = symbol.vh * sy; + tvy -= (symbol.h - tvh) * 0.5f; + tvx -= (symbol.w - tvw) * 0.5f; + mViewBox = {sx, 0, -tvx, 0, sy, -tvy, 0, 0, 1}; + } else if (!mathZero(symbol.vx) || !mathZero(symbol.vy)) { + mViewBox = {1, 0, -symbol.vx, 0, 1, -symbol.vy, 0, 0, 1}; + } + + // mSceneTransform = mUseTransform * mSymbolTransform * mViewBox + Matrix mSceneTransform = mViewBox; + if (node->node.use.symbol->transform) { + mSceneTransform = mathMultiply(node->node.use.symbol->transform, &mViewBox); + } + mSceneTransform = mathMultiply(&mUseTransform, &mSceneTransform); + scene->transform(mSceneTransform); + + if (node->node.use.symbol->node.symbol.overflowVisible) { + finalScene = move(scene); + } else { + auto viewBoxClip = Shape::gen(); + viewBoxClip->appendRect(0, 0, width, height, 0, 0); + + // mClipTransform = mUseTransform * mSymbolTransform + Matrix mClipTransform = mUseTransform; + if (node->node.use.symbol->transform) { + mClipTransform = mathMultiply(&mUseTransform, node->node.use.symbol->transform); + } + viewBoxClip->transform(mClipTransform); + + auto compositeLayer = Scene::gen(); + compositeLayer->composite(move(viewBoxClip), CompositeMethod::ClipPath); + compositeLayer->push(move(scene)); + + auto root = Scene::gen(); + root->push(move(compositeLayer)); + + finalScene = move(root); + } + } else { + if (!mathIdentity((const Matrix*)(&mUseTransform))) scene->transform(mUseTransform); + finalScene = move(scene); } - return scene; + + return finalScene; } -static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask) +static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, bool* isMaskWhite) { if (_isGroupType(node->type) || mask) { auto scene = Scene::gen(); - if (!mask && node->transform) scene->transform(*node->transform); + // For a Symbol node, the viewBox transformation has to be applied first - see _useBuildHelper() + if (!mask && node->transform && node->type != SvgNodeType::Symbol) 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)); + scene->push(_useBuildHelper(*child, vBox, svgPath, isMaskWhite)); else - scene->push(_sceneBuildHelper(*child, vBox, svgPath, false)); + scene->push(_sceneBuildHelper(*child, vBox, svgPath, false, isMaskWhite)); } 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)); + if (shape) { + if (isMaskWhite) { + uint8_t r, g, b; + shape->fillColor(&r, &g, &b, nullptr); + if (shape->fill() || r < 255 || g < 255 || b < 255 || shape->strokeFill() || + (shape->strokeColor(&r, &g, &b, nullptr) == Result::Success && (r < 255 || g < 255 || b < 255))) { + *isMaskWhite = false; + } + } + scene->push(move(shape)); + } } } _applyComposition(scene.get(), node, vBox, svgPath); @@ -620,17 +706,13 @@ unique_ptr<Scene> svgSceneBuild(SvgNode* node, float vx, float vy, float vw, flo 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; + tvx -= (w - tvw) * 0.5f; + tvy -= (h - tvh) * 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); } diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h index 4232aca612..cecbbf02a8 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp index 9f269b29a2..1f1fe2a718 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.h index 4320cfed4e..b5e6e1bdb2 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp index ee199da231..a12689c7dd 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 @@ -236,6 +236,14 @@ static SimpleXMLType _getXMLType(const char* itr, const char* itrEnd, size_t &to } +static char* _strndup(const char* src, unsigned len) +{ + auto ret = (char*)malloc(len + 1); + if (!ret) return nullptr; + ret[len] = '\0'; + return (char*)memcpy(ret, src, len); +} + /************************************************************************/ /* External Class Implementation */ /************************************************************************/ @@ -264,6 +272,7 @@ const char* simpleXmlNodeTypeToString(TVG_UNUSED SvgNodeType type) "Video", "ClipPath", "Mask", + "Symbol", "Unknown", }; return TYPE_NAMES[(int) type]; @@ -450,7 +459,7 @@ bool simpleXmlParse(const char* buf, unsigned bufLength, bool strip, simpleXMLCb } -bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLAttributeCb func, const void* data) +bool simpleXmlParseW3CAttribute(const char* buf, unsigned bufLength, simpleXMLAttributeCb func, const void* data) { const char* end; char* key; @@ -459,7 +468,7 @@ bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLAttributeCb func, cons if (!buf) return false; - end = buf + strlen(buf); + end = buf + bufLength; key = (char*)alloca(end - buf + 1); val = (char*)alloca(end - buf + 1); @@ -468,6 +477,11 @@ bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLAttributeCb func, cons do { char* sep = (char*)strchr(buf, ':'); next = (char*)strchr(buf, ';'); + if (sep >= end) { + next = nullptr; + sep = nullptr; + } + if (next >= end) next = nullptr; key[0] = '\0'; val[0] = '\0'; @@ -509,6 +523,47 @@ bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLAttributeCb func, cons } +/* + * Supported formats: + * tag {}, .name {}, tag.name{} + */ +const char* simpleXmlParseCSSAttribute(const char* buf, unsigned bufLength, char** tag, char** name, const char** attrs, unsigned* attrsLength) +{ + if (!buf) return nullptr; + + *tag = *name = nullptr; + *attrsLength = 0; + + auto itr = _simpleXmlSkipWhiteSpace(buf, buf + bufLength); + auto itrEnd = (const char*)memchr(buf, '{', bufLength); + + if (!itrEnd || itr == itrEnd) return nullptr; + + auto nextElement = (const char*)memchr(itrEnd, '}', bufLength - (itrEnd - buf)); + if (!nextElement) return nullptr; + + *attrs = itrEnd + 1; + *attrsLength = nextElement - *attrs; + + const char *p; + + itrEnd = _simpleXmlUnskipWhiteSpace(itrEnd, itr); + if (*(itrEnd - 1) == '.') return nullptr; + + for (p = itr; p < itrEnd; p++) { + if (*p == '.') break; + } + + if (p == itr) *tag = strdup("all"); + else *tag = _strndup(itr, p - itr); + + if (p == itrEnd) *name = nullptr; + else *name = _strndup(p + 1, itrEnd - p - 1); + + return (nextElement ? nextElement + 1 : nullptr); +} + + const char* simpleXmlFindAttributesTag(const char* buf, unsigned bufLength) { const char *itr = buf, *itrEnd = buf + bufLength; diff --git a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h index d96a631528..e2761ca8da 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020 - 2022 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 @@ -32,7 +32,7 @@ const int xmlEntityLength[] = {6, 6, 6, 5, 4, 4, 6, 6}; enum class SimpleXMLType { Open = 0, //!< \<tag attribute="value"\> - OpenEmpty, //!< \<tag attribute="value" /\> + OpenEmpty, //!< \<tag attribute="value" /\> Close, //!< \</tag\> Data, //!< tag text data CData, //!< \<![cdata[something]]\> @@ -41,16 +41,17 @@ enum class SimpleXMLType Doctype, //!< \<!doctype html Comment, //!< \<!-- something --\> Ignored, //!< whatever is ignored by parser, like whitespace - DoctypeChild //!< \<!doctype_child + 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 simpleXmlParseAttributes(const char* buf, unsigned bufLength, simpleXMLAttributeCb func, const void* data); +bool simpleXmlParse(const char* buf, unsigned bufLength, bool strip, simpleXMLCb func, const void* data); +bool simpleXmlParseW3CAttribute(const char* buf, unsigned bufLength, simpleXMLAttributeCb func, const void* data); +const char* simpleXmlParseCSSAttribute(const char* buf, unsigned bufLength, char** tag, char** name, const char** attrs, unsigned* attrsLength); +const char* simpleXmlFindAttributesTag(const char* buf, unsigned bufLength); bool isIgnoreUnsupportedLogElements(const char* tagName); const char* simpleXmlNodeTypeToString(SvgNodeType type); diff --git a/thirdparty/thorvg/src/loaders/tvg/tvgTvgBinInterpreter.cpp b/thirdparty/thorvg/src/loaders/tvg/tvgTvgBinInterpreter.cpp index b0364b1055..2b85342b2c 100644 --- a/thirdparty/thorvg/src/loaders/tvg/tvgTvgBinInterpreter.cpp +++ b/thirdparty/thorvg/src/loaders/tvg/tvgTvgBinInterpreter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/tvg/tvgTvgCommon.h b/thirdparty/thorvg/src/loaders/tvg/tvgTvgCommon.h index e7c3eba488..62181605a2 100644 --- a/thirdparty/thorvg/src/loaders/tvg/tvgTvgCommon.h +++ b/thirdparty/thorvg/src/loaders/tvg/tvgTvgCommon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.cpp b/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.cpp index d7f3184435..95d629d1f6 100644 --- a/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.cpp +++ b/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.h b/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.h index d276ded33a..3ae841aa85 100644 --- a/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.h +++ b/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp index 9dd57e5a89..aa54d21342 100644 --- a/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp +++ b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.h b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.h index 27186b5d4a..4acb35e76a 100644 --- a/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.h +++ b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2021 - 2022 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 diff --git a/thirdparty/thorvg/update-thorvg.sh b/thirdparty/thorvg/update-thorvg.sh index ce3d5eed1c..29b5677983 100755 --- a/thirdparty/thorvg/update-thorvg.sh +++ b/thirdparty/thorvg/update-thorvg.sh @@ -1,4 +1,4 @@ -VERSION=0.7.1 +VERSION=0.8.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 |