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

Author Topic: uft-8 characters  (Read 3006 times)

0 Members and 1 Guest are viewing this topic.

Yours3lf

  • Newbie
  • *
  • Posts: 43
    • View Profile
uft-8 characters
« on: May 02, 2011, 05:50:18 pm »
Hi all,

I've been trying to develop a text-editor in sfml based on the built-in text renderer, and I ran into this issue: I can't display uft-8 characters like őúűá etc. here's my code:

Code: [Select]
#include "keyboard.h"

void keyboard::process_keypress(sf::Key::Code keycode) //if a key is pressed then let's handle it
{
    keys[keycode] = true;

    if (keys[sf::Key::Back] == true)
    {
        //backslash pressed
        if (the_string.length() > 0)
        {
            if (!save_state)
            {
                if (the_pos > 0)
                {
                    the_string = the_string.replace(the_pos - 1, 1, "");
                    the_pos--;
                }
            }
            else
            {
                if (the_pos > save_pos)
                {
                    the_string = the_string.replace(the_pos - 1, 1, "");
                    the_pos--;
                }
            }
        }
    }

    if (keys[sf::Key::Delete] == true)
    {
        //delete pressed
        if (the_pos < the_string.length())
        {
            the_string = the_string.replace(the_pos, 1, "");
        }
    }

    if (keys[sf::Key::Return] == true)
    {
        //enter pressed
        the_string.insert(the_pos, 1, '\n');
        the_pos += 1;

        if (save_state)
        {
            std::string tmp_str = the_string.substr(the_string.substr(0, the_string.length() - 1).rfind("\n") + 1);
            tmp_str = tmp_str.substr(0, tmp_str.length() - 1);
            std::fstream f;
            f.open(tmp_str.c_str(), std::fstream::out);
            if (f.is_open())
            {
                f << write_out;
                f.close();
                the_string = write_out + "\nText successfully saved!\n";
                the_pos = the_string.length();
            }
            else
            {
                the_string = write_out + "\nCouldn't save the text!\n";
                the_pos = the_string.length();
            }
            save_state = false;

        }
    }

    if (keys[sf::Key::Escape] == true)
    {
        //escape pressed
        the_context.Close();
    }

    if (keys[sf::Key::Left] == true)
    {
        if (!save_state)
        {
            if (the_pos > 0)
            {
                the_pos--;
            }
        }
        else
        {
            if (the_pos > save_pos)
            {
                the_pos--;
            }
        }
    }

    if (keys[sf::Key::Right] == true)
    {
        if (the_pos < the_string.length())
        {
            the_pos++;
        }
    }

    if (keys[sf::Key::RControl] == true || keys[sf::Key::LControl] == true)
    {
        if (keys[sf::Key::S] == true)
        {
            write_out = the_string;
            the_string += "\nPlease enter the filename to save the text to: \n";
            the_pos = the_string.length();
            save_pos = the_pos;
            save_state = true;
            is_not_text = true;
        }
    }
}

void keyboard::process_keyrelease(sf::Key::Code keycode)
{
    keys[keycode] = false;
}

void keyboard::process_text_input(const unsigned int& char_code)
{
    for (int c = 0; c < not_text.size(); c++)
    {
        if (keys[not_text[c]] == true)
        {
            is_not_text = true;
        }
    }

    if (!is_not_text) //if it is text
    {
        the_string.insert(the_pos, 1, (wchar_t)char_code); //I think the problem lies here: I convert the incoming unsigned integer to a wchar_t which is supposed to be utf-8 right?
        the_pos++;
    }

    is_not_text = false;
}


I basically pass the character code to the process_text_input(...), in which I convert it to a wchar_t and insert it at the current position into the string I display.

So how can I render the unicode characters, what did I do wrong?

Best regards,
Yours3!f

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
uft-8 characters
« Reply #1 on: May 02, 2011, 06:32:37 pm »
First: where does the character come from? If it's a sf::Uint32 that comes from an event.Text.Unicode, it's UTF-32 and it *should* be safe to cast it to a wchar_t, which is by the way platform-specific (and rather UCS-32 or 16 than UTF-8 ).

Then what's the type of the_string?

And finally: how do you display it?
Laurent Gomila - SFML developer

Yours3lf

  • Newbie
  • *
  • Posts: 43
    • View Profile
uft-8 characters
« Reply #2 on: May 02, 2011, 08:58:14 pm »
thanks for the reply Laurent,

I pass the character like this:
Code: [Select]
process_text_input(the_events.Text.Unicode);

the type of the string is std::string

and I display it like this:

Code: [Select]
void loop::display_text()
{
    the_context.Clear(sf::Color(255, 255, 255)); //the the_context is a sf::RenderWindow object

    if (the_clock.GetElapsedTime() < 0.400f) //this whole time checking is for the blinking | sign
    {
        the_text.SetString(the_string.substr(0, the_string.length()).insert(the_pos, 1, '|'));
    }
    else
    {
        the_text.SetString(the_string.substr(0, the_string.length()).insert(the_pos, 1, ' '));
        if (the_clock.GetElapsedTime() > 0.800f)
        {
            the_clock.Reset();
        }
    }

    the_context.Draw(the_text); //the the_text is a sf::text object

    the_context.Display();
}

void loop::start()
{
    the_context.Create(sf::VideoMode(1280, 720, 32), "This is an SFML based text editor.", sf::Style::Resize | sf::Style::Close);
the_context.Show(true);
    the_context.SetFramerateLimit(30);

    if (!the_font.LoadFromFile("verdana.ttf")) //this font does contain utf-8 characters
    {
        std::cerr << "Couldn't load font.\n";
        exit(1);
    }

    the_text.SetFont(the_font);
    the_text.SetColor(sf::Color(0, 0, 0));
    the_text.SetCharacterSize(20);

    while (the_context.IsOpened())
    {
        // Process events
        process_events();

        display_text();
    }
}


Best regards,
Yours3!f

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
uft-8 characters
« Reply #3 on: May 02, 2011, 09:18:36 pm »
You should use std::wstring instead of std::string.
Laurent Gomila - SFML developer

Yours3lf

  • Newbie
  • *
  • Posts: 43
    • View Profile
uft-8 characters
« Reply #4 on: May 03, 2011, 09:57:39 pm »
thanks now it works!!!
...after doing some research about how wstring works and conversions etc, etc...