Open rickyviking opened 3 years ago
I think I made a mistake in 9da53bcecdc2273fef86f032ad55c36393c38ebd should have used current font's ascent
value instead of dst_font->Ascent
. I believe changing it to ascent
would be a move in the good direction and may break lots of hardcoded GlyphOffset
value.
It's actually trickier than that. Current code ensure that all glyphs are sharing the same baseline, which is desirable e.g. when merging two text fonts (for western + asian language). I would argue it is probably similarly desirable when merging a text font + an icon font. (This is a weird example but in reality it would make sense when combining asian + non-asian glyphs)
Using destination font ascent (current code) = same baseline
[00000] src 0 size 20.00 -> dst 0: src_ascent/descent 16.00,-5.00 dst_ascent/descent 16.00/-5.00 -> font_off_y 16.00
[00000] src 1 size 20.00 -> dst 0: src_ascent/descent 21.00,-1.00 dst_ascent/descent 16.00/-5.00 -> font_off_y 16.00
[00000] src 2 size 15.00 -> dst 1: src_ascent/descent 12.00,-4.00 dst_ascent/descent 12.00/-4.00 -> font_off_y 12.00
[00000] src 3 size 20.00 -> dst 1: src_ascent/descent 21.00,-1.00 dst_ascent/descent 12.00/-4.00 -> font_off_y 12.00
[00000] src 4 size 20.00 -> dst 2: src_ascent/descent 16.00,-5.00 dst_ascent/descent 16.00/-5.00 -> font_off_y 16.00
[00000] src 5 size 15.00 -> dst 2: src_ascent/descent 16.00,-1.00 dst_ascent/descent 16.00/-5.00 -> font_off_y 16.00
Using source font ascent:
[00000] src 0 size 20.00 -> dst 0: src_ascent/descent 16.00,-5.00 dst_ascent/descent 16.00/-5.00 -> font_off_y 16.00
[00000] src 1 size 20.00 -> dst 0: src_ascent/descent 21.00,-1.00 dst_ascent/descent 16.00/-5.00 -> font_off_y 21.00
[00000] src 2 size 15.00 -> dst 1: src_ascent/descent 12.00,-4.00 dst_ascent/descent 12.00/-4.00 -> font_off_y 12.00
[00000] src 3 size 20.00 -> dst 1: src_ascent/descent 21.00,-1.00 dst_ascent/descent 12.00/-4.00 -> font_off_y 21.00
[00000] src 4 size 20.00 -> dst 2: src_ascent/descent 16.00,-5.00 dst_ascent/descent 16.00/-5.00 -> font_off_y 16.00
[00000] src 5 size 15.00 -> dst 2: src_ascent/descent 16.00,-1.00 dst_ascent/descent 16.00/-5.00 -> font_off_y 16.00
The code before 9da53bcecdc2273fef86f032ad55c36393c38ebd attempted perform centering (perhaps incorrectly) and removed it in favor of explicit GlyphOffset values.
I want to say current behavior is actually better BUT creates a change depending on whether the icon font is merged or not, which is not ideal. Genuine question: your post state "I'm seeing a vertical misalignment" but what constitute a "misalignment" is entirely depending on your expectation. How do you use that icon font in the first place? How/why did you even notice the misalignment?
As we are aiming to facilitate use of mixed fonts at any size (as we expect to make resizing automatic), we may want to find a solution for this where user indication (if any) can be suitably scaled, but I don't yet know how to design that solution.
Genuine answer :) I wanted to add some icons besides text, for instance to show a informative sign in a tooltip: or to indicate that a tree node is a folder in an asset browser:
Following the example to merge an icon font with the main text font, I expected that their baseline would be aligned, being the 2 fonts loaded at the same resolution (20px in my example). This is what the example shows as a result.
Say that I'd expect fonts (text or icon) merged with the same size would be aligned (as it happens to be when they're not merged). If that's not the case, I'd just add this info in the Fonts document.
The point is that their baseline ARE aligned in your two screenshots.
eheh right, because I am manually adding a 4px vertical alignment - case 2) in my original post.
My code to obtain the screenshots above is:
// load custom font
std::string fontFile = "path/to/RobotoCondensed-Regular.ttf";
ImFont* assetTreeFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(fontFile.c_str(), 20);
// merge google icons font
ImFontConfig imFontConfig;
imFontConfig.MergeMode = true;
imFontConfig.GlyphOffset = { 0.f, 4.f };
imFontConfig.GlyphMinAdvanceX = 20.0f; // Use if you want to make the icon monospaced
ImVector<ImWchar> icon_ranges;
ImFontGlyphRangesBuilder builder;
builder.AddChar(0xe2c7); // ICON_MD_FOLDER
// [...]
builder.BuildRanges(&icon_ranges); // Build the final result (ordered ranges with all the unique characters submitted)
fontFile = "path/to/MaterialIconsOutlined-Regular.otf";
ImGui::GetIO().Fonts->AddFontFromFileTTF(fontFile.c_str(), 20.f, &imFontConfig, icon_ranges.Data);
eheh right, because I am manually adding a 4px vertical alignment - case 2) in my original post.
Oops, right!
I think replacing
const float font_off_x = cfg.GlyphOffset.x;
const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
with
const float merged_off_y = cfg.MergeMode ? (descent - dst_font->Descent) * (cfg.SizePixels / dst_font->FontSize) : 0.0f;
const float font_off_x = cfg.GlyphOffset.x;
const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent + merged_off_y);
Might be good. EDIT No it's not, doesn't work as well when merging two text fonts in other tests.
The more I dig the more think there is no magic solution other than exposing a way to specify vertical alignment (for merged fonts) on a per font basis. This would be loosely equivalent to specifying the +4 here but in a way that would more naturally fit for scaling.
The equation above is merely a hack which happens to work for this font, but would fail at others. A good test case is to merge two copies for the same font but with different glyph sizes.
For now I would suggest keeping that GlyphOffset but this is a topic we will need to explore further in the future.
Didn't expect to create such a turmoil. I agree that leaving things as they are works just fine, I'd only suggest to mention the fact in the Fonts doc, as at the beginning I thought I was doing something wrong.
This issue is related to https://github.com/ocornut/imgui/issues/2857
When merging an icon font (Google Material Icons) to the Roboto fonts, both loaded at the same size (20px), I'm seeing a vertical misalignment (4px), as shown by the following images:
The misalignment is introduced only when merging the 2 fonts, probably due to the different value of Descent (-1 and -5) computed for the 2 fonts independently - not sure how this value is computed.
Using the vertical offset as in point 2) above solves the issue, not sure if this is an issue or an expected behavior. Dear ImGui Version 1.81
[merged font, no offset]
[merged font, 4px vertical offset]
[fonts loaded independently, no merge]