Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Godot 4.3-rc2 new function Label.get_character_bounds(character pos) not working as expected #95088

Closed
DanielJaramillo94 opened this issue Aug 3, 2024 · 4 comments · Fixed by #96919

Comments

@DanielJaramillo94
Copy link

Tested versions

4.3.rc2

System information

Windows 11

Issue description

Function introduced in PR-84185 (Label.get_character_bounds(character pos)) is not woking as expected.

Here can be seen that the Rect2 returned by the function has an offset
image

The offset occurs when I nest the Label node inside a tree of another nodes, in this case a MarginContainer. I was expecting the function return the global position of the character.

Steps to reproduce

Just open the MRP and run the project

Minimal reproduction project (MRP)

MRP.zip

@kleonc
Copy link
Member

kleonc commented Aug 3, 2024

Function introduced in PR-84185 (Label.get_character_bounds(character pos)) is not woking as expected.

Here can be seen that the Rect2 returned by the function has an offset
image

The offset occurs when I nest the Label node inside a tree of another nodes, in this case a MarginContainer. I was expecting the function return the global position of the character.

It works as intended, it's meant to return the bounding rect of the given character in the Label's local coordinate space. Not sure why would you assume the returned rect is in a coordinate space different than the local one, the docs do not state so:

<method name="get_character_bounds" qualifiers="const">
<return type="Rect2" />
<param index="0" name="pos" type="int" />
<description>
Returns the bounding rectangle of the character at position [param pos]. If the character is a non-visual character or [param pos] is outside the valid range, an empty [Rect2] is returned. If the character is a part of a composite grapheme, the bounding rectangle of the whole grapheme is returned.
</description>

AFAIK it's "local by default unless stated otherwise", and there's nothing special about this method. In the similar manner e.g. Label.get_line_height(line_index) returns the local height.

This could of course be clarified / explicitly stated in the docs, similarily like e.g. for Line2D.points:

<member name="points" type="PackedVector2Array" setter="set_points" getter="get_points" default="PackedVector2Array()">
The points of the polyline, interpreted in local 2D coordinates. Segments are drawn between the adjacent points in this array.
</member>


If you want the bounding rect in some other coordinate space (e.g. in canvas (aka global), viewport, screen, or some other CanvasItem's space; see the docs about different coordinate spaces/systems) then you'd need to transform it into such space.

E.g. in the MRP this:

extends Node2D

@onready var label_node: Label = %Label

func _ready() -> void:
	label_node.item_rect_changed.connect(queue_redraw)

func _draw():
	var label_local_to_self_local: Transform2D = get_global_transform_with_canvas().affine_inverse() * label_node.get_global_transform_with_canvas()
	
	var char_rect_label_local: Rect2 = label_node.get_character_bounds(0)
	var char_rect_self_local: Rect2 = label_local_to_self_local * char_rect_label_local
	
	draw_rect(char_rect_self_local, Color.RED, false)
	
	draw_set_transform_matrix(label_local_to_self_local)
	draw_rect(char_rect_label_local, Color.GREEN, false)

and rotating the MarginContainer (just for showcasing):
Godot_v4 3-rc2_win64_69EB1WMtIG
produces:
Godot_v4 3-rc2_win64_mxrPI98Kpr

@DanielJaramillo94
Copy link
Author

Thank you so much for the great explaination and clean example code.

@lpenguin
Copy link
Contributor

Hi! If would take this issue to implement what should be done in order to close it? Update the documentation?

@AThousandShips
Copy link
Member

That would be the solution yes, here in the file kleonc linked above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants