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

Author Topic: [Solved] Wrap & justify sf::Text  (Read 4811 times)

0 Members and 1 Guest are viewing this topic.

Law

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
[Solved] Wrap & justify sf::Text
« on: July 17, 2015, 04:24:20 pm »
Hello,

I'm trying to draw an sf::Text inside a rectangle, and I've looked up how to wrap my sf::Text so that it doesn't go out of the rectangle. I found Laurent's post:

Calculating a character position is trickier than just accumulating the glyphs' widths. For this reason, there's a sf::Text::getCharacterPos function which gives you what you want. Call it for every position (from 0 to text size), and when result.x becomes greater than your limit, insert a \n. And start again after the line break.

and my question is: how can I make the sf::Text "justified" inside the rectangle? My first thought was to center it and then scale it horizontally so that it reaches both sides of the rectangle, but it gets more complicated when I'm dealing with a 10-line sf::Text, because every line would need a different scale factor. I would have to split the sf::Text in 10 one-line sf::Texts, but that looks awfully complicated. Not to mention that a scaled sf::Text might not even look aesthetic.

I'm at a loss here. Thank you for your help.
« Last Edit: July 20, 2015, 08:19:04 pm by Law »

Hapax

  • Hero Member
  • *****
  • Posts: 3353
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Wrap & justify sf::Text
« Reply #1 on: July 17, 2015, 04:58:56 pm »
getCharacterPos could probably do wrapping by testing each character (in order) and seeing if it has past the right side of the container and then inserting a new line before it if it does. Then, continue through the rest of the letters.

Justification is much more complicated. You need to adjust spacing between characters and this is only available at the font level. Worse still is that each line will require its own spacing so you could need a separate font per line. (I just reread the Font documentation and it seems that you can't actually change character spacing there either so that option is out.)
If your text lines are separate text objects, this complicates wrapping too as, instead of just inserting a newline to wrap, you'd need to either transfer the letter and the rest of the text to the next object or transfer the text so far to the next completed line (if the object you're processing is a buffer).

It could be worth rewriting the Text class for your own needs but it would not be an easy task and you'd have to consider if that's worth it just for justification. You find it interesting to see this Wiki post on curved text.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Law

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
Re: Wrap & justify sf::Text
« Reply #2 on: July 17, 2015, 06:30:25 pm »
Well I'd rather wait for Laurent's opinion about this, but if there is nothing remotely simple to solve my problem, I think my next question will be "What library do you think I should use?" ^^,

I'm already extensively using SFML for my project, but if there's a library that would solve this fairly easily, I'd rather make another small program and use it along with the rest :)

Edit: or maybe I could cut the n-word sf::Text in n one-word sf::Texts and draw each word where it should be...
« Last Edit: July 17, 2015, 08:01:09 pm by Law »

Hapax

  • Hero Member
  • *****
  • Posts: 3353
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Wrap & justify sf::Text
« Reply #3 on: July 17, 2015, 11:04:19 pm »
I'd rather wait for Laurent's opinion about this
There's a whole team working on SFML now, you know...  :P

maybe I could cut the n-word sf::Text in n one-word sf::Texts and draw each word where it should be...
There's nothing stopping you drawing each word as a separate text object (or indeed, each letter as a separate text object) if you absolutely definitely cannot live without text justification. You could, in fact, re-use text objects and reposition and draw them multiple times before displaying the window. You may want to draw this to a render texture and only redraw it when necessary as that's a lot of draw calls!  ;D

As a personal curiosity, I'm interested to know for what you intend to use this.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Law

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
Re: Wrap & justify sf::Text
« Reply #4 on: July 19, 2015, 12:18:09 pm »
Well there's a card game whose cards I'm trying to make replicas. Each card has a description inside a box, and my program is supposed to copy/paste the text (found on the Internet) inside the box of a blank card that will hopefully be its exact copy eventually!

But anyways, I've managed to justify the text by splitting it into n one-word sf::Texts! I have another problem though. When a card has a long text, the font size is reduced so that everything can be stored inside the box. My problem is that my sf::Texts with small sizes (the following example is size=9) aren't very good-looking:



The text is:

std::wstring Text = L"●This text is hard to read.\n●This text is hard to read.\n●This text is hard to read.\n●This text is hard to read.";

And the character that neither the picture nor the code shows is a bullet (which is another problem). Is there a way to smooth texts or something? Thank you for your help so far.

Hapax

  • Hero Member
  • *****
  • Posts: 3353
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Wrap & justify sf::Text
« Reply #5 on: July 19, 2015, 05:27:46 pm »
my program is supposed to copy/paste the text (found on the Internet)
This sounds quite dangerous as you never really know what will be on that site in the future.

My problem is that my sf::Texts with small sizes (the following example is size=9) aren't very good-looking:
[...]
Is there a way to smooth texts or something?
The first thing to do is make sure that it's drawing at an integer position. That is, (position - origin) must be at an integer position.

Thank you for your help so far.
You're welcome.

there's a card game whose cards I'm trying to make replicas.
I think it would weird if i didn't mention this here: SpinningCard
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Law

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
Re: Wrap & justify sf::Text
« Reply #6 on: July 20, 2015, 08:17:21 pm »
Well luckily I was drawing sf::Texts at a size that was much shorter than what it should have been, so this means I don't have that problem anymore.

The bullet problem remains though, I've tried '\x9679', '\x2022' and other things, but each time I tried, SFML drew a square or a bullet that was too small instead. So I'm open to ideas. I would like to print a big, black bullet like this: ●

Well anyway, this is completely irrelevant to the initial topic, so I'm going to start another thread about it. Thanks for your help.
« Last Edit: July 20, 2015, 08:18:52 pm by Law »

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: [Solved] Wrap & justify sf::Text
« Reply #7 on: July 20, 2015, 10:06:17 pm »
Try a different font maybe. Or find out what character in your current font contains a bullet.

 

anything