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

FreeType: enable colored-glyphs #3369

Closed
wants to merge 4 commits into from
Closed

FreeType: enable colored-glyphs #3369

wants to merge 4 commits into from

Conversation

pshurgal
Copy link
Contributor

Why?

FreeType supports color-layered glyphs since version 2.10.0. This feature allows render scalable icons. Different emoji, for, example.
Now any can use colored glyphs as icons in ImGui applications.

Screenshot

Annotation 2020-07-30 132631

@ocornut
Copy link
Owner

ocornut commented Jul 30, 2020

Hello,
This is looking nice, thanks for the PR!
I think we ought to make the allocation of the 32 bit buffer optional (only if eg LoadColor is enabled)?

@pshurgal
Copy link
Contributor Author

Done.

And also please notice that I have upgraded Ubuntu vertion till 20.04. Because Ubuntu 18.04 has only FreeType version 2.6 in a repository. And I wan't able to build it during preparation step because of all dependencies of version 2.10 are outdated too. So it was easier to upgrade Ubuntu version instead of building this all.

ocornut added a commit that referenced this pull request Aug 7, 2020
…eased ConfigDataCount. CI: Update Ubuntu 18.04 > 20.04 (motivated by #3369)

Fix Freetype warning.
@ocornut
Copy link
Owner

ocornut commented Aug 7, 2020

Thanks!

Do you have a specific font and test code in mind?
I'm currently trying to test with https://github.com/eosrei/twemoji-color-font and somehow all my output are still black & white... trying to figure out what's wrong with it.

static ImWchar ranges[] = { 0x1F000, 0x1FFFF, 0 };
ImFontConfig cfg;
cfg.OversampleH = cfg.OversampleV = 1;
cfg.RasterizerFlags |= ImGuiFreeType::LoadColor;
io.Fonts->AddFontFromFileTTF("../../misc/fonts/TwitterColorEmoji-SVGinOT.ttf", 16.0f, &cfg, ranges);

@pshurgal
Copy link
Contributor Author

pshurgal commented Aug 7, 2020

Hello, I have tested my solution on the same font and it worked.
I think your problem is that you pass flag ImGuiFreeType::LoadColor incorectly. Please try pass it as extra flag for ImGuiFreeType::BuildFontAtlas like this:

io.Fonts->AddFontFromFileTTF("../../misc/fonts/TwitterColorEmoji-SVGinOT.ttf", 16.0f, &cfg, ranges);
ImGuiFreeType::BuildFontAtlas(io.Fonts, ImGuiFreeType::LoadColor);

@ocornut
Copy link
Owner

ocornut commented Aug 7, 2020

This doesn't work either. It does set FT_LOAD_COLOR but none of the output bitmap are FT_PIXEL_MODE_BGRA here.

@ocornut
Copy link
Owner

ocornut commented Aug 7, 2020

I'm using freetype 2.10.2 under Windows.
I tried different things but nothing comes in FT_PIXEL_MODE_BGRA pixel format.
Search for how to use FT_LOAD_COLOR on forums gives variety of answers, but I'm assuming your code does it right (unless for some reasons, fonts formatted for Windows or other OS have different outline/bitmap contents?).

@pshurgal
Copy link
Contributor Author

pshurgal commented Aug 8, 2020

Hello, I have found the problem.
First of all, I'm sorry. I don't know why I thought I was using TwitterColorEmoji font for tests. I was wrong.
The font https://github.com/eosrei/twemoji-color-font does not contain CPAL and COLR tables inside as this is SVG font. It seems that FreeType still does not support colors in such files.
Please, try using default windows font C:\Windows\Fonts\seguiemj.ttf.
This works for me:
caption

@metarutaiga
Copy link

metarutaiga commented Aug 18, 2020

Hello, I suggest make a tag called "Microsoft style".
These Colored-glyphs can implement with one of the four styles.
We can read the web to know. https://www.colorfonts.wtf

Sometime we can't know what style implemented in the TTF.
But we can know it from size. Bitmap > SVG > Multi-layer Glyphs.
Microsoft style is the Multi-layer Glyphs.

If you want to use twitter emoji color font with Microsoft Style,
you can try this repository. https://github.com/mozilla/twemoji-colr

aiekick added a commit to aiekick/imgui that referenced this pull request Sep 14, 2020
@pshurgal
Copy link
Contributor Author

@ocornut hello, can we expect this PR will be merged soon? I mean, we are using ImGui with this changes, and it would be nice if colored glyphs will appear in master branch. If you see some problems in this PR I can fix them and help this PR to be merged faster. Thx.

@pshurgal
Copy link
Contributor Author

pshurgal commented Dec 5, 2020

@ocornut?

@ocornut
Copy link
Owner

ocornut commented Dec 5, 2020

Hello Petr,

I mean, we are using ImGui with this changes, and it would be nice if

I would like to look at this, but don't have resources to follow on every PR in a timely manner unfortunately. Please be patient! Since not all kind of colored glyphes are currently supported by FreeType I hadn't had time to evaluate if/how this may backfire into more support/feature requests and parachute us into a world of growing expectation in terms of unicode features and i18n support. Because next thing looming somebody will ask for emoji skin tone modifiers and other stateful feature. There's a enormous list of things following and I am not sure we can afford to get there.

Your patch is technically great and sound, and I appreciate it. But there is an unfortunate widespread misunderstanding with the state of maintaining OSS and the cost of initial code drop vs the cost of further maintenance and support. By accepting a PR, I'm effectively taking on the load to maintain this and its further ramifications forever. So I have to be cautious in order to protect this project, because we have 500+ other things competing for current and future attention. If it is critical for your company ("Estimated annual revenue ~$587.5M") to not carry the burden of maintaining a simple patch for a few months-years, you'd imagine in a fair world they would commit to contribute to the indefinite associated support and maintenance cost of us maintaining the patch. But somehow over time the narrative has been twisted for everyone, so it's really not personal but please appreciate merging a PR is the point where it starts to have a cost for me and I'm not superhuman.

One thing comes to mind would be to ensure this will still build with pre-2.10.

aiekick added a commit to aiekick/ImGuiFontStudio that referenced this pull request Jan 21, 2021
[IMP] : improvement of ImGuiFreetype, customized to take into account the color change of the PR ocornut/imgui#3369. static func copy from ImDraw for avoid modification of Imdraw
[FiX] : fix project change notif for some widget, was not take into account
[ADD] : add a black screen under the texture, because a colored glyph need to have a tint color of Vec4(1,1,1,1). else on light theme we can see only full ImGuiColText color
[IMP] : improvement of FontInfos for create a table who can say which glyph is colored or not. glyphInfos was modified for reflect this change. due to that, each glyphs is rendered differently regarding if colored or not
[FIX] : add COLR and partial CMAP parsing/display in fontParser
@aiekick
Copy link
Contributor

aiekick commented Jan 21, 2021

Hello,

i have customized ImGui_FreeType.cpp/.h for avoid modification of current ImDraw.cpp.
so i can load colored font without modification of ImGui.

ImGuiFontStudio_Msvc_x64_UmKUNaQrAH

btw there is an issue when the text must be rendered with a black color or other color than white.
as you know black is vec4(0,0,0,1) and in the current shader the texture result is multiplied by this color.
so with a color other than white (vec4(1,1,1,1)) the expected glyph color will be overwrited by this tint color.

i have tested a shader modification like :

void main()
{
    vec4 tex = texture(Texture, Frag_UV.st), col = Frag_Color;
    if (tex.r + tex.g + tex.b < 3.0) col = vec4(1);
    Out_Color = col * tex;
}

its not perfect because :

  • he replace the black color by Frag_Color, the other colors are ok. and in a colored glyph the black can be wanted to not be altered, especially for some gradient style
  • he add a conditionnal, just for that and its not a good idea for perf in general for massive UI

So on light theme its an issue.
On ImGuiFontStudio i solved that just by render the glyph with a white tint color only when the glyph is colored.

but its not usable for the rest of the ui without modification of ImGui.
for make it ok, i think, we need :

  • to add a flag in ImFontGlyph who can say if a glyph is colored or not. eventually we could just add a User data variable in ImFontGlyph for avoid modification by user regarding of user need.
  • to check this var in renderchar / rendertext for alterate the tint color and i not see a way for doing that without ImGui modification.

if we push the ImGuiCol_Text with vec4(1,1,1,1) before the text,
all the text except the colored icon will be white. but we can have only one char with the colored icon. so its not ok.

any other idea for avoid ImGui Modification / or without perf impact ?
maybe have a renderchar user callback or something, for let the user use his version ? :)

@ocornut
Copy link
Owner

ocornut commented Jan 21, 2021

That's an interesting issue indeed, particularly as we strive to facilitate both text color changes and merging of icons into main fonts.

I think in theory we may want the text render loop to do:

ImU32 glyph_col = col;
if (glyph->IgnoreTint)
   glyph_col |= ~IM_COL32_A_MASK;

It's probably an acceptable overhead, something to consider as we rewrite the text functions.

@aiekick
Copy link
Contributor

aiekick commented Jan 21, 2021

indeed it seem acceptable :)

if you want i can propose a PR for that

@ocornut
Copy link
Owner

ocornut commented Jan 28, 2021

I've been looking at this PR today.

One thing comes to mind would be to ensure this will still build with pre-2.10.

Tried 2.6.5 and 2.9.1 and with both things compiles and run, Freetype transparently just provide black and white outlines. I'll just add a few comments stating this requires 2.10+ but otherwise there's nothing to do on our side.

Will be looking at the tinting issue @aiekick mentioned, it's not a trivial change as we need to pass that information down.

@ocornut
Copy link
Owner

ocornut commented Jan 28, 2021

image

image

Will run perf measurements later.

@aiekick
Copy link
Contributor

aiekick commented Jan 28, 2021

nice i always using your trick in ImGuiFontStudio and i not see any perf issue.
btw not done a compared benchmark

@pshurgal
Copy link
Contributor Author

@ocornut I have found an issue when some fonts use colours and some don't. The flag LoadColor could be set by cfg.RasterizerFlags and extra_user_flags. So how do you think, should I roll back my commit 65ebfe4 then?

@ocornut
Copy link
Owner

ocornut commented Jan 28, 2021 via email

ocornut pushed a commit that referenced this pull request Feb 1, 2021
ocornut added a commit that referenced this pull request Feb 1, 2021
… untinted glyphs (#3369)

Amend 9499afd with missing static inline.
@ocornut
Copy link
Owner

ocornut commented Feb 1, 2021

This is now merged (24aa665 + amends 24be26e)

(Not directly related but note that imgui_freetype went through variety of tweaks and breaking integration changes in 1.81 WIP, see Changelog)

@ocornut ocornut closed this Feb 1, 2021
@ocornut
Copy link
Owner

ocornut commented Feb 1, 2021

Here's a test with seguiemj

imconfig

#define IMGUI_USE_WCHAR32
#define IMGUI_ENABLE_FREETYPE

In main.cpp

io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 16.0f);
{
    static ImWchar ranges[] = { 0x1, 0x1FFFF, 0 };
    static ImFontConfig cfg;
    cfg.OversampleH = cfg.OversampleV = 1;
    cfg.MergeMode = true;
    cfg.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_LoadColor;
    io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\seguiemj.ttf", 16.0f, &cfg, ranges);
}
 ImGui::Text("\xf0\x9f\x8d\x89 \xf0\x9f\x8d\x8a \xf0\x9f\x8d\x8b");

Shows the fruits above.

ocornut added a commit that referenced this pull request Mar 2, 2021
ocornut added a commit that referenced this pull request Mar 2, 2021
@Flix01
Copy link

Flix01 commented Mar 22, 2021

@ocornut: Do you think it's not portable to replace:

ImGui::Text("\xf0\x9f\x8d\x89 \xf0\x9f\x8d\x8a \xf0\x9f\x8d\x8b");

with just:

ImGui::Text("🍉 🍊 🍋");

if the file encoding is UTF8?

P.S. sorry if it's slightly OT.

@ocornut
Copy link
Owner

ocornut commented Mar 22, 2021

It doesn't work with all editors and toolsets. "If the file encoding is UTF8" is already an assumption. In Visual Studio it seems to tries to add the UTF-8 header which would then confuse some more basic text editor.

Note of that code is committed anyway, is was just a way to provide that text in a super-portable way.
If using actual unicode characters works in your own setup by all means of course do use it :)

@Flix01
Copy link

Flix01 commented Mar 22, 2021

Well, I'm on Ubuntu/QtCreator and it just works. But probably you're right... it's not super-safe to share source code like that.
Thanks.

Flix01 added a commit to Flix01/imgui that referenced this pull request Apr 11, 2021
…see: #61).

addons/imguicodeeditor/imguicodeeditor.cpp and addons/imguipanelmanager/imguipanelmanager.cpp: minimal changes to keep code up to date with Dear ImGui upstream repository.
examples/addons_examples/fonts/Icons/TwemojiMozilla/...: added this font from https://github.com/mozilla/twemoji-colr (color icons), together with some optional header files to make its use a bit easier in some contexts. Please note that it needs IMGUI_ENABLE_FREETRYPE plus a very recent version of the freetype library. Furthermore: a) it's not used by any examples, b) it does not contain many characters usable for GUI environment and c) composed glyphs (like country flags and many others) are not supported. In short: better stick to monochromatic icon fonts (like FontAwesome) in most cases.
examples/addons_examples/html/main.html and main2.html: rebuilt using a more recent version of emscripten.
examples/addons_examples/fonts/Icons/TwemojiMozilla/...: did I mention that together with IMGUI_ENABLE_FREETRYPE, the IMGUI_USE_WCHAR32 definition is required as well? Well, better fetch the 'reference link'. Here it is: ocornut#3369
ocornut added a commit that referenced this pull request May 24, 2021
…4169, #3369) + Add Fonts to Metrics. Removed IMGUI_HAS_TABLE markers.
@ocornut ocornut mentioned this pull request Apr 14, 2022
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 this pull request may close these issues.

None yet

5 participants