mirror of
https://github.com/ocornut/imgui.git
synced 2026-11-10 19:03:30 +00:00
Creating multi font with same data without set FontDataOwnedByAtlas false, will crash #6339
Labels
No labels
accidentally closed
android
backends
bug
building
clipper
coloredit
color spaces
cplusplus
data types
demo
disabled
doc
docking
dpi
drag drop
drawing/drawlist
dropped
dx12
enhancement
focus
font/text
gallery
help wanted
idle/power saving
ime
in progress
inputs
inputtext
internals
label/id and id stack
language bindings
layout
linux/bsd
menus
multi-contexts
multi-threading
multi-viewports
nav
news/info
opengl
optimization
osx/ios
overlap
plot/graph
popups
question
scrolling
selection
settings
sliders/drags
style
tables/columns
tabs
test wanted
tools
tooltips
tree
tricks & tips
useful widgets
vulkan
web
window pos/depth
window sizing
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
ocornut/imgui#6339
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
In recent days, I have been debugging a BUG.
In the process of switching the APP to the background and back again, the APP crashed randomly.
Sometimes it took dozens of minutes for the APP to crash.
After several days of digging and rewriting, I finally found the problem.
When using IMGUI to create multiple font sizes through the same TTF file data, the memory will be free twice when cleaning fontatlas!!
As a result, the memory has unexpected location crashes......
The location that causes the APP to crash is different each time.
I looked at all the possibilities... I even rewrote the entire framework from NDK-based to Java-based.
let the whole app just use IMGUI with only a small part of the code based on C++.
IMGUI has excellent performance, especially IMDRAWLIST, which I used separately as a drawing interface. I didn't use the UI part of IMGUI itself.
BELOW IS HOW I USED IMFONT----->
fontAtlas = IM_NEW(ImFontAtlas)();
long fontDataSize;
void* fontData = Platform.File.CreateDataFromResource("font.ttf", &fontDataSize);
fontDefault = fontAtlas->AddFontFromMemoryTTF(fontData, fontDataSize, 20.0f * uiScale(), &fontConfig, fontAtlas->GetGlyphRangesChineseFull());
fontPitch = fontAtlas->AddFontFromMemoryTTF(fontData, fontDataSize, 42.0f * uiScale(), &fontConfig, fontAtlas->GetGlyphRangesChineseFull());
HOW TO FIX ----->
fontAtlas = IM_NEW(ImFontAtlas)();
long fontDataSize;
void* fontData = Platform.File.CreateDataFromResource("font.ttf", &fontDataSize);
ImFontConfig fontConfig;
fontConfig.FontDataOwnedByAtlas = false;
fontDefault = fontAtlas->AddFontFromMemoryTTF(fontData, fontDataSize, 20.0f * uiScale(), &fontConfig, fontAtlas->GetGlyphRangesChineseFull());
fontPitch = fontAtlas->AddFontFromMemoryTTF(fontData, fontDataSize, 42.0f * uiScale(), &fontConfig, fontAtlas->GetGlyphRangesChineseFull());
free(fontData);
These three lines code fix the bug.
Of course, I'm trying to solve this problem from the user level. If who want to solve this problem from inside IMGUI, you need to determine whether the input TTFs data that belongs to the same memory, and then treat it differently. Or in the release process, determine whether the memory of a font has been released more than once. Of course, I won't go into that. I'm tired of debugging this random crash.
Hello,
By default the pointer passed to
AddFontFromMemoryTTF()gets its ownership moved to ImFontAtlas, by which I mean that ImFontAtlas can free it, in this case it will attempt to free it twice.Your fix is correct and exactly what is documented for this use case.
Therefore I am not sure what you are asking? You found the correct fix.
I agree this isn't a great default behavior that
AddFontFromMemoryTTF()takes ownership, I think this will evolve in a next iteration of the font API. I don't think it is desirable either to perform a search on previous font to avoid taking ownership twice, we should just eventually remove that ownership-by-default thing.