Page 2 of 2 FirstFirst 12
Results 21 to 27 of 27

Thread: First impressions about ClanLib 3.0 (and a bunch of questions)

  1. #21

    Default

    Confirmed; it is optional now.

    Now I have some doubts about the InputCode enum. I can't find keycodes for some keys, specifically the minus and equal keys (the ones left to backspace on a querty keyboard, not the NumPad ones,) as well as the PageUp and PageDown keys. I expected something like keycode_equal, keycode_dash, keycode_page_up, and keycode_page_down, but nothing in the enum list seems similar. What am I doing wrong here?

    Also, I noticed that, although Canvas has methods fill_rect() and draw_box() to fill a rectangle (or just draw its perimeter) with a specified color, the functionality for circles is not equivalent, as one would expect: There are fill_circle() methods but not draw_circle(). So you can fill a circle but can't draw its circumference. Of course, one can easily write a function to do that, something like
    Code:
    void draw_circle(clan::Canvas &canvas,const clan::Pointf center,const float radius,const clan::Colorf color) {
      // A workaround for the lack of canvas.draw_circle() method.
      clan::Shape2D shape;
      std::vector<clan::Vec2f> circle;
      shape.add_circle(center,radius,false);shape.add_circle(center,radius-1.f,true);
      shape.get_triangles(circle);
      canvas.fill_triangles(circle,color);
    }
    (or using Shape2D.get_outline(), but the above implementation seems still easier and faster to me.) I wonder why it's not worth prototyping though, given that draw_box() is there.
    Using ClanLib 3.0.0, compiled from source on Debian 8.0 ("jessie") GNU/Linux (64-bit)

  2. #22
    ClanLib Developer
    Join Date
    May 2007
    Posts
    1,824

    Default

    Quote Originally Posted by Pap View Post
    Now I have some doubts about the InputCode enum. I can't find keycodes for some keys, specifically the minus and equal keys (the ones left to backspace on a querty keyboard, not the NumPad ones,) as well as the PageUp and PageDown keys. I expected something like keycode_equal, keycode_dash, keycode_page_up, and keycode_page_down, but nothing in the enum list seems similar. What am I doing wrong here?
    PageUp == keycode_prior
    PageDown == keycode_next

    There isn't one for '=' on Microsoft Windows (See Virtual-Key Codes ). So, it cannot be made portable (as far as I know)

    In my opinion, there shouldn't be. Else every single glyph on every possible keyboard would require a keycode.
    It's better to use the string equivalent for keystrokes that return strings, especially for keyboards that take advantage of modifier keys.

    Quote Originally Posted by Pap View Post
    ... There are fill_circle() methods but not draw_circle()...
    I thought about that myself. But decided against it. Although draw_circle() is a nice convenience function, it is relatively slow. Also, I am not sure it's useful.
    I also thought of adding Shape2D::draw_circle() static. But the code to do it is so trivial, it would just add to ClanLib API bloat.

    Other developers may have other ideas and thoughts...

  3. #23

    Default

    I was not sure I should start a new topic, so I post my question here.
    I need to draw text on the canvas, but the problem is, the text size can vary. The only way I could find to do that is to set up a FontDescription, then set up a Font, something like
    Code:
    labelDescription=clan::FontDescription("font name");
    labelDescription.set_height(12);
    labelFont=clan::Font(canvas,labelDescription);
    Now, each time I need to change the text size, it is not enough to just call labelDescription.set_height(), as the font itself will still have the previous description. So I am forced to do the following each time I need to change font height:
    Code:
    labelDescription.set_height(newHeight);
    labelFont=clan::Font(canvas,labelDescription);
    labelFont.draw_text(canvas,x,y,"blah blah",color);
    The problem is that this is very slow, as each time the height is changed, font is essentially recreated. Having something like that in a loop is really not convenient, as it slows down execution a lot. I could easily solve the speed issue if Font had a method to change description, say Font::set_description(). Unfortunately, Font class doesn't have such a method (in fact, Font doesn't provide any "set" method,) so if I understand well, once.a font is set it cannot be changed, unless you do something like the above, which is very slow in runtime. Maybe I am missing something here?
    Using ClanLib 3.0.0, compiled from source on Debian 8.0 ("jessie") GNU/Linux (64-bit)

  4. #24
    ClanLib Developer
    Join Date
    May 2007
    Posts
    1,824

    Default

    It's what I personally know as the font size trap

    Recreating the font every time you use it will be slow.
    Each time you create it, it has to extract the system glyphs into a pixelbuffer, and upload it to the GPU. Once it's created, it is cached.

    There are 2 ways to solve the problem.
    1) Create an array of fonts on initialisation with various sizes.
    2) Create a large font (say 100pixels). Use canvas.set_scale() to scale it when drawing

    Option 1 is preferable when you have a known limited set of font sizes. Too many, wastes GPU memory, and performance (if using more than 16 fonts.)

    If using Option 2, you must turn off sub-pixel rendering in the font description, else the font will look dreadful when scaled. Keep anti-alias option on though.
    Also Option 2 looks bad on small font sizes (less than 24 size)

    If using very large fonts (>100 pixels), use VectorFont (the Input example uses this) and use canvas.set_scale()

  5. #25

    Default

    Quote Originally Posted by rombust View Post
    There are 2 ways to solve the problem.
    1) Create an array of fonts on initialisation with various sizes.
    2) Create a large font (say 100pixels). Use canvas.set_scale() to scale it when drawing
    Actually, I was already implementing first option when I saw this - implementing it very reluctantly I must add, as I think it's too much computational work for just changing font size. Same for second option (plus font sizes are rarely that big to use it.) Best solution would be a Font::set_description() method, so that you could have one Font object, but also the ability to dynamically change its size using FontDescription::set_height() then update the font using Font::set_description()... neat, more convenient, and without wasting resources or doing scaling tricks (with all their disadvantages.) How difficult is to add such a method? Or it makes no sense because it would still be slow?
    Using ClanLib 3.0.0, compiled from source on Debian 8.0 ("jessie") GNU/Linux (64-bit)

  6. #26
    ClanLib Developer
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    554

    Default

    Adding a Font::set_height() function is not realistic, at least not the way the Font class is currently coded. On a related note, functions such as the Win32 CreateFont function also does not allow you change the font size after it has been created.

    The key issue here is how a font works internally. To maintain a high rendering speed, font glyphs are first converted from vector form to an image. This process involves the font height as it needs to know what size you intend to render the glyph. The process is further complicated by the fact the individual glyph images then needs to be stored in a shared texture image (one texture per glyph would be way too slow).

    The Font implementation cheats slightly by assuming that you intend to render the font at the exact pixel size given in the FontDescription. By doing this, it can render the glyphs at this one size once and thereby solving the problem. The catch is that this doesn't work very well with canvas scaling. I think the GDI font renderer internally uses a somewhat more dynamic glyph bitmap cache to support scaling, but its exact behavior is unknown to me (I don't have the source). Personally I virtually never use canvas scaling, so for me an improved glyph bitmap cache is a nice to have feature.

    Adding Font::set_height() is not realistic because with the current glyph cache design it would be forced to recreate the entire cache, which effectively will run at exactly the same speed as creating a new Font from scratch.

    Therefore the current assumption in ClanLib has always been that you create individual Font objects for the sizes you need, which in most applications actually map to surprisingly few variations (assuming no canvas scaling). For example, rendering a website usually only involves 1-3 fonts with 3-5 different sizes. The only catch here is that you need to share those Font objects created along where you draw the text.

    If you're using the resource system, then the caching of Font objects should be automatic - call Font::resource(canvas, desc) with a few different font sizes, and it will only create the font objects once for each of those sizes.

    Otherwise you'd have to create your own cache, something like:

    Code:
    class MyFontCache
    {
    public:
      clan::Font get(clan::Canvas &canvas, int size)
      {
        auto it = cache.find(size);
        if (it != cache.end())
          return it->second;
    
        clan::Font font(canvas, "Times Ugly Roman", size);
        cache[size] = font;
        return font;
      }
    private:
      std::map<int, clan::Font> cache;
    };
    Only catch is for canvas scaling fonts won't look too good. Fixing this would require a lot of work, and so far none have had the need badly enough to try.

  7. #27

    Default

    I ended up with a vector of Fonts with different sizes, defined in class construction, and indeed it is fast enough in practice. Maybe not the best way to change font sizes in run time, but it works. Maybe another font class that doesn't store glyphs to the GPU, so it's not that fast but it's also more flexible and configurable in run time is a good idea.
    For more wide font size range, I will use a vector font (or a sprite) and rescaling. Thank you both for your support.
    Using ClanLib 3.0.0, compiled from source on Debian 8.0 ("jessie") GNU/Linux (64-bit)

Similar Threads

  1. ClanLib 2.3.4 questions
    By Veitikka in forum Official ClanLib SDK Forums
    Replies: 10
    Last Post: 03-14-2012, 02:11 PM
  2. 2 questions when start using Clanlib GUI moudule
    By westpointer in forum Official ClanLib SDK Forums
    Replies: 2
    Last Post: 05-26-2010, 12:44 PM
  3. First Impressions...
    By Fr3DBr in forum Official ClanLib SDK Forums
    Replies: 0
    Last Post: 08-26-2009, 02:46 AM
  4. ClanLib 0.9 GUI Questions
    By rombust in forum Official ClanLib SDK Forums
    Replies: 2
    Last Post: 02-10-2009, 01:17 PM
  5. First impressions...
    By whisperstorm in forum Novashell Game Creation System
    Replies: 1
    Last Post: 11-22-2006, 11:21 PM

Bookmarks

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •