SFML community forums

Help => System => Topic started by: tapule on January 25, 2015, 12:10:22 pm

Title: [SOLVED] How to convert from Glib::ustring to sf::String?
Post by: tapule on January 25, 2015, 12:10:22 pm
Hello, I'm new here.

I usually use Glib::ustring in my Linux projects so I have some code already using this class.
Now I'm doing things with SFML, and I searched in the forum and in google, with no luck, for a way to convert from Glib::ustring to sf::String.

Do you know any way to do this??

Greetings.
Title: AW: How to convert from Glib::ustring to sf::String?
Post by: eXpl0it3r on January 25, 2015, 12:21:42 pm
Any proper string class should be able to convert to standard strings, which then can be passed to SFML's sf::String class.
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: tapule on January 25, 2015, 12:40:04 pm
Yes Glib::ustring does it, but then you lose the encodings because std::string does not support it.
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: tapule on January 25, 2015, 12:54:36 pm
For example:

Glib::ustring text = "Text: ñáéíóúö";
sf::String string;

// raw() is defined as const std::string& raw () const
string = text.raw();
 

And the result using in a sf::Text:
(http://www.mediafire.com/convkey/3ce7/ol3emnc6oy6edbpzg.jpg)
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: Laurent on January 25, 2015, 01:26:31 pm
Don't just try random things. Read the docs, try to understand, and adapt your code ;)

Quote from: https://developer.gnome.org/glibmm/stable/classGlib_1_1ustring.html#details
Glib::ustring has much the same interface as std::string, but contains Unicode characters encoded as UTF-8.

And

Quote from: http://www.sfml-dev.org/documentation/2.2/classsf_1_1String.php#aa7beb7ae5b26e63dcbbfa390e27a9e4b
static String sf::String::fromUtf8(T begin, T end)      

Create a new sf::String from a UTF-8 encoded string.

So:

string = sf::String::fromUtf8(text.begin(), text.end());
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: tapule on January 25, 2015, 04:57:46 pm
Thank you for your help Laurent.

Seems that sf::String::fromUtf8 is new in SFML 2.2, I'm using 2.1 in my Linux box so I tried to mimic what it does using  sf::Utf8::toUtf32 but this seems that doesn't work directly with Glib::ustring:

/usr/include/SFML/System/Utf.inl:60:15: error: no match for ‘(operand operator+’ types are ‘Glib::ustring_Iterator<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> > >’ and ‘int’)

So I tried to simulate the behaviour with this code:

        Glib::ustring text = "Text: ñáéíóúö";
        std::basic_string<unsigned int> buffer;
        std::basic_string<unsigned int> basic_string;
        Glib::ustring::iterator iter;

        for (iter = text.begin(); iter!= text.end(); ++iter)
        {
                buffer.push_back(*iter);
        }

        sf::Utf8::toUtf32(buffer.begin(), buffer.end(), std::back_inserter(basic_string));

        sf::String sf_string(basic_string);

But when I use sf_string in a sf::Text, got the same result as I show in my previous post.

Any hint on this?

Greetings.
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: tapule on January 25, 2015, 05:57:02 pm
I think I solve it.
This is the way to convert from Glib::ustring to sf::String:

    Glib::ustring text = "Text: ñáéíóúö &#916;&#948;&#928;&#960;";
    Glib::ustring::iterator iter;
    std::basic_string<unsigned int> buffer;
    sf::String sf_string;

    for (iter = text.begin(); iter!= text.end(); ++iter)
    {
        buffer.push_back(*iter);
    }
    sf_string = buffer;

This is the result:

(http://www.mediafire.com/convkey/ba38/fs7g6uqhhcp5fr2zg.jpg)

Seems that there is no need to use the sf::Utf8 conversion because Glib::ustring is already in Utf8.

Thanks for the help and hope this also can help someone.
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: Gambit on January 25, 2015, 06:34:04 pm
Why dont you just install SFML 2.2 on your linux box?
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: Laurent on January 25, 2015, 06:38:41 pm
Sorry to say that, but... it's not supposed to work, and what you say doesn't make sense :P

Quote
Seems that there is no need to use the sf::Utf8 conversion because Glib::ustring is already in Utf8.
But sf::String is not. So you need to convert from UTF-8 to sf::String. I have no idea why what you do works, but if you look at the documentation and try to interpret it (instead of trying random things until it works), you'll see that you're using the constructor that takes a std::basic_string<Uint32>, and this one expects UTF-32 -- which UTF-8 is not.
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: tapule on January 25, 2015, 09:23:41 pm
Why dont you just install SFML 2.2 on your linux box?
I think that is possible that that doesn't will work because Glib::ustring seems that doesn't work with sf::Utf8::toUtf32.

But sf::String is not. So you need to convert from UTF-8 to sf::String. I have no idea why what you do works, but if you look at the documentation and try to interpret it (instead of trying random things until it works), you'll see that you're using the constructor that takes a std::basic_string<Uint32>, and this one expects UTF-32 -- which UTF-8 is not.
I heed you Laurent and I'm not trying random things.
In sf::String::fromUtf8 there is basically a call to sf::Utf8::toUtf32 so my first attempt was to get the data from the Glib::ustring, call directly toUtf32 with the data to convert and finally call the constructor of sf::String with the new Utf32 data, but this doesn't work. I have assumed that this problem was caused because the data in Glib::Ustring is already converted so I used the data directly and that work.

In the documentation of Glib::ustring it says "contains Unicode characters encoded as UTF-8" so I don't know exactly why it work in sf::String even if it is not in UTF-32.

My knowledge of encodings is not big, is it possible that UTF-8 is compatible with UTF-32?
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: Laurent on January 25, 2015, 09:45:27 pm
Quote
is it possible that UTF-8 is compatible with UTF-32?
Nop, it is not.

Your attempt to use sf::Utf8::toUtf32 should work. One thing that can explain the problem is the string literal: if your .cpp file is not saved in UTF-8, and/or if your compiler is not correctly configured then this doesn't work. Did you make sure that your Glib::ustring works as expected in the first place?

In the meantime I'll try to do it myself, as I'm really curious to understand why this doesn't work.
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: tapule on January 26, 2015, 12:00:32 pm
Your attempt to use sf::Utf8::toUtf32 should work. One thing that can explain the problem is the string literal: if your .cpp file is not saved in UTF-8, and/or if your compiler is not correctly configured then this doesn't work. Did you make sure that your Glib::ustring works as expected in the first place?
The file is in UTF-8 and no problem with my compiler, I have a Debian Testing updated so my compiler is up to date. I usually use Glib::ustring without problems, I think that it is a mature project but as every piece of software can have bugs.

I think that the problem with sf::Utf8::toUtf32 is in this iterator increment:

if (begin + trailingBytes < end)

in sf::Utf<8>::decode.

I will try with the last source code of SFML and see what happens.

Thank you for your help Laurent.
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: tapule on January 26, 2015, 02:15:55 pm
This time I do it in Windows with Mingw and the lastes SFML compided from the GitHub repo.
I tried sf::String::fromUtf8:

Glib::ustring text = "Text: ñáéíóúö";
sf::String string;

string = sf::String::fromUtf8(text.begin(), text.end());
 

The compiler trows the same error that I show yesterday:

c:\mingw\include\sfml\system\utf.inl:60:15: error: no match for 'operator+' (operand types are 'Glib::ustring_Iterator<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >' and 'int')
     if (begin + trailingBytes < end)
               ^

Seems that Glib::ustring iterator does not have + operator:

template <class T>
class ustring_Iterator
{
public:

...
  inline value_type operator*() const;
  inline ustring_Iterator<T> &     operator++();
  inline const ustring_Iterator<T> operator++(int);
  inline ustring_Iterator<T> &     operator--();
  inline const ustring_Iterator<T> operator--(int);
...

};
 
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: Laurent on January 26, 2015, 02:29:24 pm
Indeed. You can try to replace

if (begin + trailingBytes < end)

by

if (std::distance(begin, end) < trailingBytes)

(you'll have to recompile SFML, unless you directly use sf::Utf8::toUtf32 instead of sf::String::fromUtf8).
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: tapule on January 26, 2015, 04:59:20 pm
I did it Laurent, I modified Utf.inl with the change that you tell me, now it compile but the result is again incorrect:
(http://www.mediafire.com/convkey/6490/67qbh0bk6jbhqh6zg.jpg)

What is very strange is that if I use sf::String::fromUtf32 or sf::String::fromUtf16, it works again.
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: Laurent on January 26, 2015, 05:52:52 pm
Can you show your code again?
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: tapule on January 26, 2015, 06:03:08 pm
This doesn't work:
Glib::ustring text = "Text: ñáéíóúö";
sf::String string;

string = sf::String::fromUtf8(text.begin(), text.end());
 

This work
Glib::ustring text = "Text: ñáéíóúö";
sf::String string;

string = sf::String::fromUtf16(text.begin(), text.end());
 

and this
Glib::ustring text = "Text: ñáéíóúö";
sf::String string;

string = sf::String::fromUtf32(text.begin(), text.end());
 
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: Laurent on January 26, 2015, 07:06:24 pm
It seems that Glib::ustring::iterator provides gunichar, which is a codepoint (UTF-32).

So the following should both work:

sf::String string = sf::String::fromUtf32(text.begin(), text.end());

sf::String string = sf::String::fromUtf8(text.raw().begin(), text.raw().end());
Title: Re: How to convert from Glib::ustring to sf::String?
Post by: tapule on January 26, 2015, 07:39:35 pm
So, as sf::String::fromUtf32 basically does an assign to the internal std::basic_string<unsigned int> that sf::String has, this is the reason that make my code work, this is, is the same behaviour.

Thank you for your time Laurent.