Special Character

Started by WiWo, 23 August 2017, 13:04:18

WiWo

I need to show some text I read from a file over an image on the screen.
So I used a text box with a personalized theme. (I can swap to something else, if necessary)

However, I need to display characters such as à, è, ° .

I read the post about Cyrillic characters, but I am using Arial as font and I'm sure these characters are included.

Is there any way to fix this? Thanks a lot.

p.s.: even sf::Text do not display that characters and I am using the 0.7.4 version of TGUI

texus

TGUI just uses sf::Text internally, so if sf::Text doesn't display it then TGUI definitely won't.
But the Arial.ttf file you attached definitely does contain these characters, so I see no reason why it wouldn't work. Could you also try with the DejaVuSans.ttf file that can be found in the fonts folder inside the downloaded TGUI folder? If it still doesn't work then you can be certain that it is not an issue with the Arial.ttf file itself.
If even the DejaVuSans.ttf font doesn't work then you should show some minimal example code. Just a simple main function that creates the text and draws it to the window. Then I can be certain that you didn't make a mistake somewhere in setting the font.

WiWo

This is the minimal code using DejaVuSans

Code (cpp) Select

#include <TGUI/TGUI.hpp>
#include <fstream>
#include <string>
using namespace sf;

int main() {
   
    tgui::Gui gui;
    tgui::Theme::Ptr theme;
    tgui::TextBox::Ptr textbox;
    RenderWindow window;
   
    window.create(VideoMode(1224,1224), "NotSoVisualNovel");
    gui.setWindow(window);
    theme = tgui::Theme::create("/Users/***/Desktop/TGUI\ Characters/TGUI\ Characters/WiWo.txt");
    textbox = theme->load("TextBox");
    textbox->setSize(1000,300);
    textbox->setPosition(100, 900);
    textbox->setReadOnly();
    textbox->setTextSize(30);
    gui.add(textbox, "textbox");
    gui.setFont("/Users/***/Desktop/TGUI\ Characters/TGUI\ Characters/DejaVuSans.ttf");
   
    std::fstream file;
    file.open("/Users/***/Desktop/TGUI\ Characters/TGUI\ Characters/input.txt");
    std::string line;
   
    while (window.isOpen()) {
       
        window.clear(sf::Color::Black);
       
        Event event;
        while (window.pollEvent(event)) {
            if(event.type == Event::Closed) {
                window.close();
            }
            else if (event.type == Event::KeyPressed && event.key.code == Keyboard::Space) {
                getline(file,line);
                textbox->addText("\n"+line);
            }
            gui.handleEvent(event);
        }
        gui.draw();
        window.display();
       
    }
   
}


I attached the external file that may be used to reproduce the code as well as a screen shot of issue when the program is launched.
Note that the WiWo.txt file is simply Black.txt with the text box's background changed.

Thanks for your help

texus

#3
The problem is not with the SFML rendering, it is with your loading. I didn't think of it until I was debugging the code, but the characters can't be stored in an std::string. If you do textbox->setText("à è ì ò ù") then it won't work, but it will display correctly when writing textbox->setText(L"à è ì ò ù").
I don't know exactly how to load wide chars from a file, but there seem to exist std::wfstream and std::wstring, so you should be able to figure it out by searching some more information about these types.

Edit: Actually std::string can store these characters, as std::cout prints them correctly. I guess the problem is with the way SFML converts the std::string to an sf::String then. But if you have an std::wstring then there shouldn't be any issues in the conversion to sf::String anymore.

texus

I figured out how to display the characters correctly. You can keep using std::fstream and std::string, but you have to explicitly inform SFML that the data you are giving it is not ANSI but UTF-8. This is done like this:
Code (cpp) Select
textbox->addText("\n" + sf::String::fromUtf8(line.begin(), line.end()));

About the code you posted earlier, make sure gui.setFont occurs before gui.add. The widget will inherit the font of its parent (in this case the Gui) when it is added to it. Changing the font of the gui after the widgets have already been added to it will not change the font of these widgets. Only the font of widgets added after gui.setFont is called will get the new font.

WiWo

Thanks A LOT

I tried fixing the problem using wfstream and wstring but I then had to use

Code (cpp) Select

file.imbue(std::locale(std::locale::classic() , new std::codecvt_utf8<wchar_t>))


So your solution is much neater.

Thanks again.