ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
60.8k stars 10.27k forks source link

Feature request: Ability to set additional line spacing for fonts #2945

Open codecat opened 4 years ago

codecat commented 4 years ago

Version/Branch of Dear ImGui:

Version: Latest Branch: docking

Back-end/Renderer/Compiler/OS

Back-ends: imgui_impl_win32.cpp + imgui_impl_dx11.cpp Compiler: MSVC Operating System: Windows

My Issue/Question:

I would like to be able to add additional spacing to lines rendered from fonts. For example, if I do ImGui::Text("Hello\nWorld"); I would like to control the spacing between the lines "Hello" and "World".

An additional "Line spacing" field in ImFont could be a very simple solution here. Actually, looks like ImFontConfig has a line that mentions this current limitation:

ImVec2          GlyphExtraSpacing;      // 0, 0     // Extra spacing (in pixels) between glyphs. Only X axis is supported for now.
ocornut commented 4 years ago

How often would you need to change it, how much and for which purpose?

One issue here is that lots of code is assuming that FontSize == height of a line. We could add support for GlyphExtraSpacing.y turned into extra height, that's fairly easy but it would be a build-time locked spacing for now, and would affect the height of framed items so not necessarily ok depending on what value you intend to use it for.

Otherwise, consider that:

ImGui::Text("Hello");
ImGui::Text("World");

Would be spaced by style.ItemSpacing.y.

Whereas

ImGui::Text("Hello\nWorld");

Would be spaced what whatever that new value would be (e.g. a font or style property, say, style.FontSpacing.y ? or something in the ImFont structure that has its own setters or stack).

Implicitely that value is currently zero. So even is there is a sort of inconsistency it's easier to understand and workaround than with a non-zero value.

One possibility is to make ImGui::Text("Hello\nWorld"); use style.ItemSpacing.y, which would make large blob of text, wrapped-text or multi-line text widget higher than what they currently are (so kind of a breaking change, but acceptable if deemed for the best). We would also need some sort of mechanism in ImGui to sync the ItemSpacing.y value (which is at ImGui:: level) with an equivalent in ImDrawList or ImFont (which are lower-level types not depending on ImGui::.).

Any suggestion?

codecat commented 4 years ago

My usecase would actually be solved by modifying FontSpacing for a single font config. In my case, I don't need to change the line spacing dynamically.

My icon font (which I use font merging for) is a little bit bigger than my regular font, so my log window looks like this:

image

While it could look like this: (I temporarily made the icon font size 1 pixel smaller to get this result)

image

(Colors are done in-line via my own extension, so that's all just a single TextUnformatted call.)

ocornut commented 4 years ago

While the feature/issue is perfectly legit and I would like to find better solution, it looks like for the specific issue you are having, you have a solution here? (make the icon font not bigger than the text).

codecat commented 4 years ago

Yes, that is a valid workaround for me right now. I would prefer not to have to do that though, as that extra pixel font size does increase the quality and readability of the icons.

ocornut commented 4 years ago

I think we can implement the additional spacing that will fix your case in a simple way first, but understand it means that every button and framed widgets will be taller by 1 pixels (unless you compensate by reducing FramePadding). Would that work for you?

codecat commented 4 years ago

Wait, do you mean using ItemSpacing for line spacing?

ocornut commented 4 years ago

No I mean adding ImFont/ImFontConfig settings maybe GlyphExtraSpacing.y to effectively increase the height of a text line (FontSize will be altered) without altering glyph size.

codecat commented 4 years ago

Ah yeah, then that would definitely be a good solution.