imgui cannot show utf-8 chinese character correctly,how to solve
aliule2020 opened this issue · 5 comments
//#include <SFML/Graphics.hpp>
//
//int main()
//{
// sf::RenderWindow window(sf::VideoMode(sf::Vector2u{200,200}), "SFML works!");
// sf::CircleShape shape(100.f);
// shape.setFillColor(sf::Color::Green);
//
// while (window.isOpen())
// {
// sf::Event event;
// while (window.pollEvent(event))
// {
// if (event.type == sf::Event::Closed)
// window.close();
// }
//
// window.clear();
// window.draw(shape);
// window.display();
// }
//
// return 0;
//}
#include <string>
using namespace std;
#include "imgui.h" // necessary for ImGui::*, imgui-SFML.h doesn't include imgui.h
#include "imgui-SFML.h" // for ImGui::SFML::* functions and SFML-specific overloads
#include <SFML/Graphics.hpp>
#include <SFML/Graphics/CircleShape.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/System/Clock.hpp>
#include <SFML/Window/Event.hpp>
int main() {
sf::RenderWindow window(sf::VideoMode(sf::Vector2u{ 1024,768 }), "SFML works!");
window.setFramerateLimit(60);
ImGui::SFML::Init(window);
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
sf::Text tx;
tx.setString( sf::String(L"你好") ); //here is ok
sf::Font font;
font.loadFromFile("C:\\Windows\\Fonts\\stsong.ttf");
tx.setFont(font);
tx.setCharacterSize(36);
tx.setFillColor(sf::Color::Red);
tx.setPosition(sf::Vector2f{ 400, 400 });
sf::Clock deltaClock;
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
ImGui::SFML::ProcessEvent(window, event);
if (event.type == sf::Event::Closed) {
window.close();
}
}
ImGui::SFML::Update(window, deltaClock.restart());
ImGui::BeginMainMenuBar();
ImGui::SetWindowFontScale(1);
if (ImGui::BeginMenu("File"))
{
if (ImGui::MenuItem("Open..", "Ctrl+O")) { /* Do stuff */ }
if (ImGui::MenuItem("Save", "Ctrl+S")) { /* Do stuff */ }
if (ImGui::MenuItem("Close", "Ctrl+W")) { }
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
ImGui::ShowDemoWindow();
ImGuiIO& io = ImGui::GetIO();
//io.Fonts->Clear();
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\stsong.ttf", 13.0f, NULL, io.Fonts->GetGlyphRangesChineseFull());
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\simhei.ttf", 13.0f, NULL, io.Fonts->GetGlyphRangesChineseFull());
//ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[0]);
ImGui::SFML::UpdateFontTexture();
ImGui::Begin("hello");
ImGui::SetWindowFontScale(4);
ImGui::SetWindowPos("hello", ImVec2{ 50,50 });
ImGui::SetWindowSize("hello", ImVec2{ 200,200 });
ImGui::Button((char*)u8"中文测试"); //here is failed
ImGui::End();
window.clear(sf::Color::White);
window.draw(shape);
ImGui::SFML::Render(window);
window.draw(tx);
window.display();
}
ImGui::SFML::Shutdown();
return 0;
}
Hello. Can you please show me what you're seeing instead?
What OS are you on, by the way?
P.S. Does the custom font work for ASCII characters?
Doing ImGui::PushFont
is important, by the way. I think you're using the default Dear ImGui's font by not doing this.
Try to get Dear ImGui to print simple English characters in this font (e.g. "ABC" should be printed in your custom font) and then try Chinese characters.
And you should only call AddFontFromFileTTF
and UpdateFontTexture
on the startup, not inside your main loop.
(if this doesn't help, I'll come up with a good starting example tomorrow)
Thank you for your help, but the problem is still on. At first, in my program the ImGui::PushFont cannot be used, or the exception will happen. Secondly, the English characters works well, you can see my picture below. Last, I correct my program following your instructions ,here is the result:
#include "string"
using namespace std;
#include "imgui.h" // necessary for ImGui::*, imgui-SFML.h doesn't include imgui.h
#include "imgui-SFML.h" // for ImGui::SFML::* functions and SFML-specific overloads
#include <SFML/Graphics.hpp>
#include <SFML/Graphics/CircleShape.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/System/Clock.hpp>
#include <SFML/Window/Event.hpp>
int main() {
sf::RenderWindow window(sf::VideoMode(sf::Vector2u{ 1024,768 }), "SFML works!");
window.setFramerateLimit(60);
ImGui::SFML::Init(window);
ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\stsong.ttf", 13.0f, NULL, io.Fonts->GetGlyphRangesChineseFull());
//io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\simhei.ttf", 13.0f, NULL, io.Fonts->GetGlyphRangesChineseFull());
//ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[0]);
ImGui::SFML::UpdateFontTexture();
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
sf::Text tx;
tx.setString( sf::String(L"你好") );
sf::Font font;
font.loadFromFile("C:\\Windows\\Fonts\\stsong.ttf");
tx.setFont(font);
tx.setCharacterSize(36);
tx.setFillColor(sf::Color::Red);
tx.setPosition(sf::Vector2f{ 400, 400 });
sf::Clock deltaClock;
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
ImGui::SFML::ProcessEvent(window, event);
if (event.type == sf::Event::Closed) {
window.close();
}
}
ImGui::SFML::Update(window, deltaClock.restart());
ImGui::BeginMainMenuBar();
ImGui::SetWindowFontScale(1);
if (ImGui::BeginMenu("File"))
{
if (ImGui::MenuItem("Open..", "Ctrl+O")) { /* Do stuff */ }
if (ImGui::MenuItem("Save", "Ctrl+S")) { /* Do stuff */ }
if (ImGui::MenuItem("Close", "Ctrl+W")) { }
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
ImGui::ShowDemoWindow();
ImGui::Begin("hello");
ImGui::SetWindowFontScale(4);
ImGui::SetWindowPos("hello", ImVec2{ 50,50 });
ImGui::SetWindowSize("hello", ImVec2{ 200,200 });
ImGui::Button((char*)u8"中文测试");
ImGui::Button("ABC");
ImGui::End();
window.clear(sf::Color::White);
window.draw(shape);
ImGui::SFML::Render(window);
window.draw(tx);
window.display();
}
ImGui::SFML::Shutdown();
return 0;
}
You're not calling io.Fonts->Build();
and BuildRanges
as in the official example before doing ImGui::SFML::UpdateFontTexture();
: https://github.com/ocornut/imgui/blob/master/docs/FONTS.md#using-custom-glyph-ranges
ImVector<ImWchar> ranges;
ImFontGlyphRangesBuilder builder;
builder.AddText("Hello world");
builder.AddChar(0x7262);
builder.AddRanges(io.Fonts->GetGlyphRangesJapanese());
builder.BuildRanges(&ranges);
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, NULL, ranges.Data);
io.Fonts->Build();
Works for me with i.e. cyrllic glyph ranges.