Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: hebrew and arabic strings  (Read 3578 times)

0 Members and 1 Guest are viewing this topic.

efife

  • Newbie
  • *
  • Posts: 5
    • View Profile
hebrew and arabic strings
« on: December 04, 2013, 11:30:14 pm »
Hey everybody!
First of all I must say I really enjoy working with sfml.

I want to create a program that read hebrew and arabic text from files (.txt files). The problem is that I can't hold the text in any string: not std::string, not std::wstring and not sf::String.
here is the minimal code:

#include <SFML/Graphics.hpp>
int main()
{
        sf::RenderWindow window(sf::VideoMode(500, 500), "SFML");
        sf::Font font;
        font.loadFromFile("ARIALN.ttf");
        sf::Text text;
        text.setFont(font);
        text.setPosition(200.0f, 200.0f);
        text.setString("&#1513;&#1500;&#1493;&#1501;");
        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                                window.close();
        }
                window.clear();
                window.draw(text);
                window.display();
    }
    return 0;
}

It displays "uiai" with weird sign above each char.
The font I chose supports hebrew letters.

What should I do to fix it?
Thanks.
edit: I noticed that here it changes my hebrew letters to &#1513;&#1500;&#1493;&#1501;
There should be the word "שלום" instead.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
AW: hebrew and arabic strings
« Reply #1 on: December 04, 2013, 11:59:30 pm »
Does it work if you put, an L infront of the string like: txt = L"ÜÆØΠ₱";
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

efife

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: AW: hebrew and arabic strings
« Reply #2 on: December 05, 2013, 10:09:26 am »
Does it work if you put, an L infront of the string like: txt = L"ÜÆØΠ₱";

Thanks for the answer but I already tried it and it doesn't work. it shows empty square for each letter.

Any other suggestions?

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: hebrew and arabic strings
« Reply #3 on: December 05, 2013, 11:09:57 am »
Upload the font (or say where we can get it) if it is freely available and a screenshot of your application with these "empty squares" so we know what they look like and can test it ourselves.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

efife

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: hebrew and arabic strings
« Reply #4 on: December 05, 2013, 01:03:08 pm »
I noticed i have picked the wrong "Arial" font for Hebrew (should be "arial" instead of "ARIALN"), and the code I gave in the first post works.
Now I want to read the text from file and display it on the screen.
So first of all here is the font:https://www.mediafire.com/?lr85ypt8lyajuy2.
Here is my code:
#include <SFML/Graphics.hpp>
#include <fstream>
#include <string>
int main()
{
        sf::RenderWindow window(sf::VideoMode(500, 500), "SFML");
        sf::Font font;
        font.loadFromFile("arial.ttf");
        sf::Text engText;
        sf::Text hebText;
        engText.setFont(font);
        hebText.setFont(font);
        engText.setPosition(200.0f, 200.0f);
        hebText.setPosition(200.0f, 240.0f);
        std::wifstream wifs("text.txt");
        std::wstring wEngStr;
        std::wstring wHebStr;
        while ( wifs >> wEngStr >> wHebStr)
        {
                engText.setString(wEngStr);
                hebText.setString(wHebStr);
        }
        wifs.close();
        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                                window.close();
        }
                window.clear();
                window.draw(engText);
                window.draw(hebText);
                window.display();
    }
    return 0;
}
On screen it looks like this:


The text.txt file contains:
hello שלום

Thanks.

wintertime

  • Sr. Member
  • ****
  • Posts: 255
    • View Profile
Re: hebrew and arabic strings
« Reply #5 on: December 05, 2013, 01:14:36 pm »
Looks like the text file is in a different encoding than you assume when reading it in your code.
Try to use a text editor to load the file and save it as UTF-8 (thats the most compatible format for files) without BOM (to avoid the 3 funny characters at start), then change your code to not use those w-things (because wide char is only vaguely defined in C and can be different on another system), then use the appropriate function to construct an sf::String (that internally is UTF-32) from UTF-8 data (I personally use sf::Utf but there may be a helper function in sf::String), then give that to sf::Text.

efife

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: hebrew and arabic strings
« Reply #6 on: December 05, 2013, 03:56:34 pm »
Looks like the text file is in a different encoding than you assume when reading it in your code.
Try to use a text editor to load the file and save it as UTF-8 (thats the most compatible format for files) without BOM (to avoid the 3 funny characters at start), then change your code to not use those w-things (because wide char is only vaguely defined in C and can be different on another system), then use the appropriate function to construct an sf::String (that internally is UTF-32) from UTF-8 data (I personally use sf::Utf but there may be a helper function in sf::String), then give that to sf::Text.
1) I fixed the format (it was UTF-8 but probably with BOM)
2) I changed the std::wstrings to normal std::strings
3) I didn't get all the sf::Utf stuff. I don't think I do it right. Can you give me an example of how to use it or how you use it please? I tried to work with it but I get compiler-errors which brings me to the definition of utf (utf.inl).
This is what I tried:
#include <SFML/Graphics.hpp>
#include <fstream>
#include <string>
int main()
{
        sf::RenderWindow window(sf::VideoMode(500, 500), "SFML");
        sf::Font font;
        font.loadFromFile("arial.ttf");
        sf::Text engText;
        sf::Text hebText;
        engText.setFont(font);
        hebText.setFont(font);
        engText.setPosition(200.0f, 200.0f);
        hebText.setPosition(200.0f, 240.0f);
        std::ifstream ifs("text.txt");
        std::string engStr;
        std::string hebStr;
        sf::String str;
        sf::Utf8 utf8;
        while ( ifs >> engStr >> hebStr)
        {      
                engText.setString(engStr);
                str = utf8.fromAnsi(hebStr.begin(),hebStr.end(),str);
                hebText.setString(hebStr);
        }
        ifs.close();
        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                                window.close();
        }
                window.clear();
                window.draw(engText);
                window.draw(hebText);
                window.display();
    }
    return 0;
}
This is the error:
Error   4   error C2676: binary '++' : 'sf::String' does not define this operator or a conversion to a type acceptable to the predefined operator.
I get this error 5 times exactly the same.
And this warning:
Warning   1   warning C4101: 'utf8' : unreferenced local variable

wintertime

  • Sr. Member
  • ****
  • Posts: 255
    • View Profile
Re: hebrew and arabic strings
« Reply #7 on: December 05, 2013, 05:27:12 pm »
fromAnsi is wrong. Ansi means it was text encoded in Latin-1, but you have UTF-8.
This is a function I copied from my code, its working but probably not the most efficient:
void UTF8_std_string_to_sf_String(const std::string& text,sf::String& sftext) {
  std::string::const_iterator i(text.cbegin());
  std::string::const_iterator e(text.cend());
  while(i!=e) {
    sf::Uint32 out;
    i=sf::Utf8::decode(i,e,out);
    sftext+=out;
  }
}
 

The good thing about Unicode is you dont need to check if part of it is English or other part is in other language, just feed the whole data through the same mechanism.
You also dont need to load the strings separately, sf::Text recognizes linefeed characters.