How to center differently sized characters.

Godot Version

v4.5.1.stable.official [f62fdbde1]

Question

I am trying to centre Arabic letters in their different forms (beginning, middle, end, standalone) in the middle of a colorRect as part of a cad for a card game. I have made a centre container and set it’s anchor to full rect. I have also tried to centre the text in the label by chaining the alignment but this seems to have no effect. The character, while centred horizontally, is not centred vertically. I also don’t want to centre it with manual offsets as i want to use code to put a large range of characters in the label. When I use English characters, it works normally, but am using the NotoSansArabic_Condensed-Regular font. How do I center the Arabic character? Thank you.

It won’t be possible to do that with a Label or any other Control as they don’t expose all the information needed for what you want to do.

There are a couple of ways of getting what you need. If you are using a font file (*.ttf, *.oft,…) then you can use the FontFile.get_glyph_size() to get the size of the glyph and FontFile.get_glyph_offset() to get the offset from the baseline. Then you can render it with Font.draw_char() which draws the character from its baseline. You can adjust then the position with the offset.

Example:

extends ColorRect


func _draw() -> void:
	# Load the font
	var font = preload("uid://dmfpl3cbubakd")
	# Get the unicode value
	var char_unicode = ord("ج")
	# Setup the font size. It's a Vector2i because the FontFile methods use it
	var font_size = Vector2i(120, 0)
	# Get the glyph index in the font from the unicode value
	var glyph_index = font.get_glyph_index(font_size.x, char_unicode, 0)
	# Get the baseline offset
	var baseline_offset = font.get_glyph_offset(0, font_size, glyph_index)
	# Get the glyph size
	var glyph_size = font.get_glyph_size(0, font_size, glyph_index)

	# Get the center position
	var pos = (size - glyph_size) / 2

	# Draw a debug rect
	draw_rect(Rect2(pos, glyph_size), Color.RED, true, 2)
	# Draw the glyph taking into account the offset
	font.draw_char(get_canvas_item(), pos - baseline_offset, char_unicode, font_size.x, Color.BLACK)

Result: