godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.27k stars 21.04k forks source link

get_wordwrap_string_size reports wrong height with stretch_mode=2d and test_width and test_height set #48415

Open johnfn opened 3 years ago

johnfn commented 3 years ago

Godot version: 3.3.0

OS/device including version: MacOS 10.15.5

Issue description: With stretch_mode=2d and test_width/height set, get_wordwrap_string_size thinks my line of text has 2 lines when it actually has 3 when rendered.

Steps to reproduce:

  1. Made a new project
  2. Set width=1280, height=1280, test_width=800, test_height=800, stretch/mode="2d"
  3. Use the font I'm using (BalsamiqSans-Regular 28) and try to render the string I'm trying to render ("If there's anything scary out there, we'll handle it for sure!")
  4. Get a height of 70, but expect something >= 105 (each line is 35 high)

Note it works fine if I turn off either stretch_mode=2d or set test_width and test_height back to 0.

Minimal reproduction project:

Repro.zip

Calinou commented 3 years ago

This may be caused by DynamicFont oversampling. As a workaround, you can disable it in the project settings but this will make the font pixelated (or blurry if Filter is enabled on the font).

You could also try disabling hinting in the DynamicFontData resource (remember to save it to a .tres file afterwards) and see if that improves things. Due to how it works, hinting will likely cause font metrics to change when the window is resized and DynamicFont oversampling is enabled.

johnfn commented 3 years ago

Thanks - appreciate the tip and the fast response. :)

wareya commented 2 years ago

It looks like this doesn't necessarily have anything to do with the stretch mode or even dynamicfonts at all. It happens in a default-settings project with the built-in font, which is not a dynamicfont. It also happens both with normal Labels and RichTextLabels. (The oversampling text flow bug will still cause this, but this happens for reason other than just the oversampling text flow bug.)

This should probably get looked at more closely. It makes get_wordwrap_string_size basically unusable for anything but diagnostics.

Repro project:

WrapTest.zip

Video:

https://user-images.githubusercontent.com/585488/150584117-9d6a9b64-292a-49d4-90c5-d5d89f5a8d33.mp4

Notice that the panel does not resize itself to fit the label exactly when it's close to a line count boundary. It takes several pixels difference in width to actually wrap (so it's not a simple rounding issue that might go away with a judicious ceil() or float()).