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

Hashing methods for Font's cache do not work correctly for similar strings with different font sizes #70512

Closed
DmitriySalnikov opened this issue Dec 24, 2022 · 0 comments · Fixed by #70519
Assignees
Milestone

Comments

@DmitriySalnikov
Copy link
Contributor

Godot version

v4.0.beta10.official [d0398f6]

System information

Windows 10, Vulkan

Issue description

When I was testing my debug_draw_3d extension, I noticed that the graph titles change their size strangely.
For example, here, with a font size of 41 for one of the titles, instead of fps5 it draws fps6 with a font size of 14.
But the ascent of the font is taken correctly, which is why the title goes down a lot.
godot windows editor dev x86_64_u0CvcAfqjh

I found that these hashing functions create the same hash for fps5: 41, fps6: 14 and fps8: 76.

uint64_t hash = p_text.hash64();
hash = hash_djb2_one_64(p_font_size, hash);
if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
hash = hash_djb2_one_64(p_jst_flags.operator int64_t(), hash);
}
hash = hash_djb2_one_64(p_direction, hash);
hash = hash_djb2_one_64(p_orientation, hash);
Ref<TextLine> buffer;
if (cache.has(hash)) {
buffer = cache.get(hash);
} else {
buffer.instantiate();
buffer->set_direction(p_direction);
buffer->set_orientation(p_orientation);
buffer->add_string(p_text, Ref<Font>(this), p_font_size);
cache.insert(hash, buffer);
}

uint64_t hash = p_text.hash64();
hash = hash_djb2_one_64(p_font_size, hash);
hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
hash = hash_djb2_one_64(p_brk_flags.operator int64_t(), hash);
hash = hash_djb2_one_64(p_jst_flags.operator int64_t(), hash);
hash = hash_djb2_one_64(p_direction, hash);
hash = hash_djb2_one_64(p_orientation, hash);
Ref<TextParagraph> lines_buffer;
if (cache_wrap.has(hash)) {
lines_buffer = cache_wrap.get(hash);
} else {
lines_buffer.instantiate();
lines_buffer->set_direction(p_direction);
lines_buffer->set_orientation(p_orientation);
lines_buffer->add_string(p_text, Ref<Font>(this), p_font_size);
lines_buffer->set_width(p_width);
lines_buffer->set_break_flags(p_brk_flags);
lines_buffer->set_justification_flags(p_jst_flags);
cache_wrap.insert(hash, lines_buffer);
}

(also both of these parts of the code are repeated 3 times)

Here's what I get in MRP:
image

Expected something like this:
image

Affected Font methods: get_string_size, get_multiline_string_size, draw_string, draw_multiline_string, draw_string_outline, draw_multiline_string_outline.

Steps to reproduce

  • Open MRP
  • Notice the gray rectangles and the text somewhere near them (the text should be on top of the rectangles)
  • Move the slider for the second_font_size parameter and watch glitches on some values.

Also, if you cache a lot of variants for second_font_size, and then change first_font_size(or vice versa), then there will be a more glitches:
Godot_v4 0-beta10_win64_r0jJoStkQd

Minimal reproduction project

Font Bad Hash.zip

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

Successfully merging a pull request may close this issue.

4 participants