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

TextLine goes blank when changing window content_scale_mode and content_scale_factor. #104626

Open
Decapitated opened this issue Mar 25, 2025 · 3 comments

Comments

@Decapitated
Copy link

Tested versions

  • Tested on: v4.4.stable.official [4c311cb]

System information

Godot v4.4.stable - Windows 11 (build 22631) - Multi-window, 2 monitors - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 2070 SUPER (NVIDIA; 32.0.15.7247) - AMD Ryzen 7 5700X 8-Core Processor (16 threads)

Issue description

I didn't notice this issue at first because I was clearing the canvas item and redrawing the TextLine each update. I then realized I didn't need to redraw each update and removed the clear/draw:

-RenderingServer.canvas_item_clear(rid)
-text_line.draw(rid, Vector2.ZERO)
RenderingServer.canvas_item_set_transform(rid,
    Transform2D().scaled(Vector2(scale, scale)).translated(pos))

This optimization worked as expected. But when changing the window content_scale_mode and content_scale_factor, the drawn TextLine turns into a box.

Recording.2025-03-25.164319.mp4

Steps to reproduce

  1. Open MRP
  2. Press Play or run test.tscn
  3. Change mode and/or scale using provided controls.

Minimal reproduction project (MRP)

textline-bug-mrp.zip

@bruvzg
Copy link
Member

bruvzg commented Mar 25, 2025

This is expected, changing scale changes the font oversampling and old glyph images are cleared, so you do need to redraw in this case. Window will send queue_redraw to all nodes, but since you are not using _draw() to draw (which is intended place to draw) it won't do anything. And this is not the only case when redraw is needed.

Correct way to draw is something like this. Note that _draw will be only called if it's necessary to redraw, or you called queue_redraw, not every frame:

func _ready():
	text_rid = RenderingServer.canvas_item_create()
	RenderingServer.canvas_item_set_parent(text_rid, get_canvas_item())
	text_line.add_string("Hello World!", ThemeDB.fallback_font, 32)

func _draw() -> void:
	RenderingServer.canvas_item_clear(text_rid)
	text_line.draw(text_rid, Vector2.ZERO)

@Decapitated
Copy link
Author

Decapitated commented Mar 27, 2025

@bruvzg Is there any more granular way to know when the glyphs have been cleared? There are times when the TextLine doesn't need to be redrawn, but _draw() is still called. Also, something in the docs saying that the glyphs could be cleared and need redrawing would be nice.

@bruvzg
Copy link
Member

bruvzg commented Mar 27, 2025

Is there any more granular way to know when the glyphs have been cleared?

No, TextLine do some checks internally and won't do full text processing if it's not necessary.
In general if _draw() is called you should always redraw, it's not text specific.

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

No branches or pull requests

2 participants