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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Ryder

Pages: [1]
1
Window / Mixing TextEntered and KeyPressed events
« on: April 17, 2017, 06:37:28 pm »
Hi!
I'm implementing a small interface for a game, with multiple focus handing. Keyboard can be used by several players playing at the same time, each player having its own mapping to navigate in menus. When a player activates a text entry control, he gains full access to the keyboard until he finished typing.

Since keys pressed when typing text in entry must not be handled for menu navigation, there are two input modes: a "key mode" in which KeyPressed are handled for menu navigation and TextEntered are ignored, and a "text mode" in which TextEntered and non-text KeyPressed are handled for typing and editing (backspacing, etc.).

I'm having issues handling the transition from one mode to another.
After entering text mode, I wait for the next KeyPressed until actually handling TextEntered to avoid handling pending the TextEntered triggered by the previous KeyPressed. But this trick is not sufficient for characters typed using multiple keys (typically dead keys). For instance, on a French keyboard, ê is typed with ^ + e.

Here is text code implementing this:
#include <string>
#include <iostream>
#include <SFML/Window.hpp>

int main()
{
  sf::Window window(sf::VideoMode(100, 100), "");
  window.setFramerateLimit(60);
  bool text_mode_enabled = false;
  bool text_mode_active = false;
  while(window.isOpen()) {
    sf::Event event;
    while(window.pollEvent(event)) {
      if(event.type == sf::Event::Closed) {
        window.close();

      } else if(event.type == sf::Event::MouseButtonPressed) {
        // toggle text mode on click
        text_mode_enabled = !text_mode_enabled;
        text_mode_active = false;
        std::cout << "text mode: " << (text_mode_enabled ? "enabled" : "disabled") << std::endl;

      } else if(event.type == sf::Event::KeyPressed) {
        if(text_mode_enabled) {
          // actually active text mode once a key has been pressed
          text_mode_active = true;
        } else {
          // key mode: handle KeyPressed normally
          std::cout << "press: " << event.key.code << std::endl;
        }

      } else if(event.type == sf::Event::TextEntered) {
        if(text_mode_active) {
          // handle TextEntered only if text mode is active
          auto s = sf::String{event.text.unicode}.toWideString();
          std::wcout << "text: " << event.text.unicode << " (" << s << ")" << std::endl;
        }
      }
    }
    window.setActive();
    window.display();
  }
}
 

With the following sequence:
- ^ : navigate in menus
- click : enable text mode
- e : first input text

The result is:
Code: [Select]
press: 47
text mode: enabled
text: 234 (ê)

The user typed e, but input text is ê because of the previous ^ used to navigate (before text mode is enabled).

Is there a workaround to this problem?
A clean solution would be to be able to flush pending input and partially input text in SFML, but I doubt it is actually possible on all supported platforms. :(

2
Graphics / Re: sf::Font size not accurate
« on: September 22, 2014, 11:25:03 pm »
If an accent was placed on top of the upper case E, it probably wouldn't be visible (off-screen)
That's exactly what happened to me on Windows. For instance when displaying a Ê, the accent is not visible (or only bottom pixels).
Also, the line spacing (returned by sf::Font::getLineSpacing) doesn't include the extra space for accents (this is probably the root cause). It can be seen with multiline text, when drawing a letter with a loop (eg. g) above an accentuated capital (eg. Â): both characters overlap.

According to the FreeType tutorial, the ascender value (used to compute the line height) may have a different meaning depending on the font format. I guess it may also depend on the font itself (some fonts may set invalid values). Still according to this documentation, it should include the space for accents (so the correct rendering would be the Linux version).

You may consider updating your font file for a consistent result. I had the issue with an old version of FreeSans; with a freshly downloaded version, the line spacing includes accent spacing, as expected.

3
Feature requests / Re: Stroke text using FreeType capabilities
« on: May 04, 2014, 01:45:20 pm »
I agree for the need of configurable stroking attributes. I didn't had it because it was simpler, but it's definitely needed. There is another parameter: the miter limit, used for FT_STROKER_LINEJOIN_MITER_FIXED and FT_STROKER_LINEJOIN_MITER_VARIABLE. We could decide to enforce it to 0 though; in this case all FT_STROKER_LINEJOIN_MITER_* styles are equivalent.

If we keep the same logic for fonts and glyphs, then we would have to introduce a new parameter to Font::getGlyph() for each new attribute: border width, line join style, line cap style and (possibly) miter limit. A probably better solution would be to create a struct/class to gather all stroking attributes, hence avoiding functions with too much parameters and logical grouping of stroking attributes. This would also allow easier passing of stroke configuration troughout the code (notably for accessors). This structure needs to be comparable to be used as index in Font::PageTable. Since all stroke attributes are integers or enums, this is easy to implement.

What do you think of this?

4
Feature requests / Stroke text using FreeType capabilities
« on: May 04, 2014, 12:07:40 am »
Hi!

I wanted to use stroke fonts with SFML. FreeType supports stroked glyphs but this is not made available in SFML.
I know it is posible to obtain a similar result by drawing the text several times with small position offsets, but they are several drawbacks to this method:
 - for larger borders and font sizes you have to draw more occurences of the text or artefacts will appear
 - space between characters does not take account of the border (or you have to draw each character independently, without relying on SFML)
 - sharpness of edges is not preserved
 - the result is more a "glow effect" than a stroke.

I made a small patch to SFML to add stroked support (feel free to ask if your are interested). Basically it adds:
 - m_borderWidth, m_borderColor and m_borderVertices members to Text (with associated constructors)
 - a borderWidth parameter (defaulting to 0) to glyph-related methods (ex. Font::loadGlyph()), along the characterSize parameter
API is preserved (new methods for Text, new optional parameter for glyph-related method), but not ABI (especially, glyph pages are now indexed by character size and border width).

Here is a picture showing the difference between FT-based stroke font and the multiple drawing method for 4 configurations (regular and bold font style, border width 3 and 6). For each configuration there are:
 - FreeType stroking (using FT_STROKER_LINECAP_BUTT and FT_STROKER_LINEJOIN_MITER_FIXED stroke style)
 - stroke by drawing the text 9 times with offsets from (-width,-width) to (width,width) to produce sharp corners
 - stroke by drawing the text 8 times around the initial position (at multiples of pi/4 angles)
 - stroke by drawing the text 16 times around the initial position (at multiples pi/8 angles)

As you can see, when the border is thick, drawing 8 times is not enough. And even with a small border, artefacts are visible where the FT-based stroking is always clean. FT-based version is larger because character spacing respects the border width.


This is just a proposal. I know that Laurent is very cautious with API changes (and he's right!) and maybe this solution would not fit its requirements, but I think stroke text would be a nice addition to SFML and I'm ready to help. :)

5
Graphics / sf::RenderImage::Create extremely slow
« on: July 24, 2011, 01:47:04 pm »
Having a similar issue, I added some traces in RenderImage::Create().
The slow operation is the call to XGetWindowAttributes() in GlxContext::CreateContext() which tooks 170ms.

I'm using the last git version (99b33e8) with Intel HD Graphics 3000.
Also, RenderImage does not seem work at all (which is not uncommon with Intel graphics, according to other topics).
For instance, the following code produces a black PNG image instead of a blue one:
Code: [Select]
sf::RenderImage img;
img.Create(32, 32);
img.SetActive(true);
img.Clear(sf::Color::Blue);
img.Display();
img.GetImage().SaveToFile("a.png");


On Windows 7, everything works fine, RenderImage is not slow and images are rendered as expected.

Pages: [1]