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

Author Topic: Tabs in sf::Text and another suggestion  (Read 4261 times)

0 Members and 2 Guests are viewing this topic.

TomasRiker

  • Newbie
  • *
  • Posts: 5
    • View Profile
Tabs in sf::Text and another suggestion
« on: December 17, 2009, 10:45:33 am »
In the current implementation, the tab size in sf::Text is always 4 times the width of a space. But the space added doesn't depend on the current cursor position as it is in "real" tabs.
I'd like to be able to set the tab size using SetTabWidth or something (default tab size can still be 4 * width of space). And the actual space should take the current cursor location into account.
I can provide a sample implementation for that.

I tried it like this and it works:

Code: [Select]
// Initialize the rendering coordinates
(...)
float tabSpace    = space * myTabSize;
(...)

        // Handle special characters
        switch (curChar)
        {
                (...)
                case L'\t' : x = tabSpace * static_cast<int>((x + space + tabSpace) / tabSpace); continue;
                (...)
        }


myTabSize is a new member variable that stores the tab size, in number of spaces.

Also, when looking at the source, I saw that essentially the same logic is there three times: once in GetCharacterPos, then in Render and finally in RecomputeRect. It would be easier to maintain the code if sf::Text used a std::vector of character positions. Then GetCharacterPos would need only O(1) time and Render could just use the vector to draw the characters at the appropriate position.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Tabs in sf::Text and another suggestion
« Reply #1 on: December 17, 2009, 11:40:00 am »
That's not a bad idea ;)

However the tab width shouldn't be expressed as a multiple of the space character width. This expression is only relevant for text editors that automatically convert tabs to spaces. But for a general purpose usage, the tab width should just be an arbitrary number (not even linked to the character size). Remember the tab definition: it advances the cursor to the next text "column".

Quote
I saw that essentially the same logic is there three times: once in GetCharacterPos, then in Render and finally in RecomputeRect. It would be easier to maintain the code if sf::Text used a std::vector of character positions. Then GetCharacterPos would need only O(1) time and Render could just use the vector to draw the characters at the appropriate position.

I know, I'm currently working on this.
However your idea doesn't work: if the font changes, the text doesn't know about it and cannot update its positions. So it cannot be cached. I guess that all I can do is refactoring the code.
Laurent Gomila - SFML developer

TomasRiker

  • Newbie
  • *
  • Posts: 5
    • View Profile
Tabs in sf::Text and another suggestion
« Reply #2 on: December 18, 2009, 07:04:31 am »
Quote from: "Laurent"
However your idea doesn't work: if the font changes, the text doesn't know about it and cannot update its positions. So it cannot be cached. I guess that all I can do is refactoring the code.

That's a problem indeed. The only way a font can change is when you call LoadFromFile, LoadFromMemory or operator= on it, right? Maybe it would be better if the Load methods were static or implemented as constructors or even provided my some resource manager. Resources would be "immutable" then, once created they would never be replaced by another one. Then you wouldn't have this problem.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Tabs in sf::Text and another suggestion
« Reply #3 on: December 18, 2009, 09:38:45 am »
That wouldn't solve the problem:
Code: [Select]
font = Font("font.ttf");
font = Font::LoadFromFile("font.ttf");
font = manager.LoadFromFile("font.ttf");

They all still use operator=. We can't make immutable classes in C++. It works great in managed languages like C# (and that's what SFML.Net uses), but in C++ that would mean restricting the usage of resources to pointers only, which is not a good idea ;)
Laurent Gomila - SFML developer

TomasRiker

  • Newbie
  • *
  • Posts: 5
    • View Profile
Tabs in sf::Text and another suggestion
« Reply #4 on: December 18, 2009, 09:29:05 pm »
Quote from: "Laurent"
They all still use operator=. We can't make immutable classes in C++. It works great in managed languages like C# (and that's what SFML.Net uses), but in C++ that would mean restricting the usage of resources to pointers only, which is not a good idea ;)

Why not make operator= private?
Most other libraries give access to a resource only via pointers, preferrably smart pointers. I think there's nothing wrong with that, as resources are usually "big" datatypes which you don't want to pass around anyway.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Tabs in sf::Text and another suggestion
« Reply #5 on: December 18, 2009, 11:49:34 pm »
And what? Just for solving the above issue? ...
Laurent Gomila - SFML developer

TomasRiker

  • Newbie
  • *
  • Posts: 5
    • View Profile
Tabs in sf::Text and another suggestion
« Reply #6 on: December 19, 2009, 12:30:32 am »
For now there may only be this issue, but I guess there will be more. Basically this way of handling resources can often prevent you from caching things and thereby improving performance because some resources might change during their lifetime.