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 - underww

Pages: [1] 2 3
1
General discussions / Better font rendering
« on: March 29, 2019, 03:08:18 am »
I'm always dissatisfied with SFML font rendering quality. I know it has been improved for the last several years, but it is still hard to say good enough. So I've been trying to improve it myself last few days and I found FT_LOAD_FORCE_AUTOHINT flag in sf::Font makes more bad result mostly.



Check this. The first one is default SFML text and the second one is SFML text without FT_LOAD_FORCE_AUTOHINT flag, the last one is my implementation of SFML + freetype + harfbuzz. Interestingly they all have different letter spacing even though they all have the same character size. I don't know which one is correct, but the result of my implementation is exactly the same as the original code (https://github.com/lxnt/ex-sdl-freetype-harfbuzz)

You easily find ugly rendered Korean text(the red box, only few characters here but generally I could found a lot). Maybe you can't find significant differences between English texts here, but I'm sure it's not just a problem of non-English text. Usually in small texts, SFML font rendering is not so nice.

Any ideas?

I also attach my short example code.
Sorry for my bad English :P

#include <SFML/Graphics.hpp>

#include <ft2build.h>
#include FT_FREETYPE_H

#include <harfbuzz/hb.h>
#include <harfbuzz/hb-ft.h>

int main()
{
        const std::string filename = "fonts/KoPub Dotum Bold.ttf";
        const sf::String string = L"The quick brown fox jumps over the lazy dog. 다람쥐 헌 쳇바퀴에 타고파. 글굴귤";
        constexpr int font_size = 20;

        constexpr int width = 800;
        constexpr int height = 600;

        sf::RenderWindow window(sf::VideoMode(width, height), "SFML Text");

        sf::Font font;
        font.loadFromFile(filename);

        sf::Text text(string, font, font_size);
        text.setPosition(50.f, 50.f);

        FT_Library ft_library;
        FT_Face ft_face;

        if (FT_Init_FreeType(&ft_library) ||
                FT_New_Face(ft_library, filename.c_str(), 0, &ft_face) ||
                FT_Set_Char_Size(ft_face, font_size * 64, font_size * 64, 0, 0))
                return 1;

        hb_font_t* hb_font = hb_ft_font_create(ft_face, NULL);

        hb_buffer_t* hb_buffer = hb_buffer_create();
        hb_buffer_add_utf32(hb_buffer, string.getData(), -1, 0, -1);
        hb_buffer_guess_segment_properties(hb_buffer);

        hb_shape(hb_font, hb_buffer, NULL, 0);

        unsigned int glyph_count = hb_buffer_get_length(hb_buffer);
        hb_glyph_info_t* glyph_info = hb_buffer_get_glyph_infos(hb_buffer, NULL);
        hb_glyph_position_t* glyph_pos = hb_buffer_get_glyph_positions(hb_buffer, NULL);

        std::vector<sf::Uint8> pixelbuffer;
        pixelbuffer.resize(width * height * 4, 0);

        {
                sf::Uint8* current = pixelbuffer.data();
                sf::Uint8* end = current + width * height * 4;

                while (current != end)
                {
                        (*current++) = 255;
                        (*current++) = 255;
                        (*current++) = 255;
                        (*current++) = 0;
                }
        }

        int current_x = 50;
        int current_y = 100;

        // render
        for (unsigned int i = 0; i < glyph_count; ++i)
        {
                if (FT_Load_Glyph(ft_face, glyph_info[i].codepoint, 0))
                        return 1;

                current_x += glyph_pos[i].x_offset / 64;
                current_y += glyph_pos[i].y_offset / 64;

                FT_GlyphSlot ft_slot = ft_face->glyph;
                FT_Render_Glyph(ft_slot, FT_RENDER_MODE_NORMAL);
                FT_Bitmap ft_bitmap = ft_slot->bitmap;

                int w = ft_bitmap.width;
                int h = ft_bitmap.rows;
                int left = ft_slot->bitmap_left;
                int top = ft_slot->bitmap_top;

                const sf::Uint8* buffer = ft_bitmap.buffer;

                if (ft_bitmap.pixel_mode == FT_PIXEL_MODE_MONO)
                        return 1;

                constexpr int padding = 1;

                w += 2 * padding;
                h += 2 * padding;

                for (int y = padding; y < h - padding; ++y)
                {
                        for (int x = padding; x < w - padding; ++x)
                        {
                                if (buffer[x - padding] > 0)
                                {
                                        std::size_t index = (current_x + x + left) + (current_y + y - top) * width - padding;
                                        pixelbuffer[index * 4 + 3] = buffer[x - padding];
                                }
                        }

                        buffer += ft_bitmap.pitch;
                }

                current_x += glyph_pos[i].x_advance / 64;
                current_y += glyph_pos[i].y_advance / 64;
        }
        //

        hb_buffer_clear_contents(hb_buffer);

        sf::Image image;
        image.create(width, height, pixelbuffer.data());

        sf::Texture texture;
        texture.loadFromImage(image);

        sf::Sprite sprite(texture);

        while (window.isOpen())
        {
                sf::Event event;

                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                                window.close();
                }

                window.clear();
                window.draw(text);
                window.draw(sprite);
                window.display();
        }

        hb_buffer_destroy(hb_buffer);
        hb_font_destroy(hb_font);

        FT_Done_Face(ft_face);
        FT_Done_FreeType(ft_library);

        return 0;
}
 

Edit: fixed typo

2
Graphics / Re: Is it possible to make full white sprite?
« on: January 30, 2018, 02:55:06 pm »
Thanks for the answers. I'll try some.

3
Graphics / Is it possible to make full white sprite?
« on: January 29, 2018, 03:31:53 pm »
I'm trying to make the sprites white shortly when characters take damage.
Some solutions I found are making white images by hand then swap the sprites or using shaders.

I don't like both solutions for a couple of reasons.
(There're a lot of images and I change the images often. and also I don't want to use shader for now.)

I was trying to make the white sprite using sf::BlendMode, but I could make only white sprite with black background.
(It seems because of the transparent area of the images.)

So I want to know if it is possible to make full white sprite without making white image or shader.
Thanks in advance. :)

4
SFML projects / Re: Simplex Noise generator
« on: January 07, 2018, 05:07:53 pm »
It looks nice. I was toying with Perlin Noise and Poisson Disk Sampling to make a procedural infinite galaxy a few days ago.
But I've not tested Simplex Noise yet, so I'll probably try your code later.

5
Window / Re: Strange behavior with borderless windowed fullscreen
« on: April 12, 2017, 03:26:54 pm »
I have only two PCs, one desktop, and one laptop.
So, I can't find the exact reason yet.

I usually use SFML with a default windows console for debugging (without sfml-main.lib or sfml-main-d.lib file)
While I was trying this and that, I added those main lib files and switched SUBSYSTEM from CONSOLE to WINDOWS.
then flicking and other problems disappeared on my laptop.

After that, I tried the same thing on my desktop, but it still happens there.
I also built the program on my laptop and moved it to the desktop and tested it. (the opposite too)

The problem doesn't happen at all only on my laptop when I don't use a console.
So it's still mysterious... :P

6
Window / Re: Strange behavior with borderless windowed fullscreen
« on: April 12, 2017, 02:44:06 pm »
I found few more things about this.

The problem doesn't happen if I don't use console window on my laptop. (/SUBSYSTEM:CONSOLE -> WINDOWS)
However, this still happens on my desktop computer.

I thought it's kind of video card problems at first but both machines have GeForce. (Models are different of course)
So, I tried it with Intel HD graphics and GeForce on my laptop. but there's no difference.

Another reason I'm guessing is only my desktop computer has dual monitors.

7
Window / Strange behavior with borderless windowed fullscreen
« on: April 12, 2017, 12:42:14 pm »
Recently I realized there's a strange difference between these codes.
I tested the codes on Windows 10, Visual Studio 2015/2017, with SFML 2.4.2
(also in my desktop and laptop)

// I assume 1920x1080 is your desktop resolution.
1. window.create(sf::VideoMode(1920, 1080), "title", sf::Style::None);
2. window.create(sf::VideoMode(1920, 1079), "title", sf::Style::None);
3. window.setPosition(1, 1); // after code #1

First, #1 is flickered a little when the window is created while #2 is not flickered.
It also flickers when you try alt+tab or the window gains/loses focus.
(it's also delayed when you gain the window focus in some case)

Windows default screen capture doesn't work after you gain focus the SFML window in #1.
(I could capture the screen after alt+tab twice)

Second, #2 is drawn behind the taskbar while #1 is drawn in front of the taskbar.
(You can also check the same behavior if you change position after you create #1 window) - #3

#3 is the same as #2

So, what's the reason of these strange behaviors?
Thanks in advance.

Edit: In my opinion, this seems to be handled the same as real fullscreen when the window size is the desktop resolution.

8
Graphics / Re: How can I draw pretty box with .ttf font?
« on: March 01, 2016, 01:46:28 am »
Yeah, but box-drawing characters in many fonts don't have the gaps between themselves unlike other symbols.
the fonts I tested also don't have gaps naturally.

I don't scale the text but, the gaps is variable when I change font size.
sometimes it looks perfect with some size, but it doesn't generally.
so I thought it's because of some rendering problem in SFML.

9
Graphics / Re: How can I draw pretty box with .ttf font?
« on: February 29, 2016, 10:14:37 pm »
Yes, I'm trying to draw ASCII art with virtual console using SFML
This is what I want to do (the same font and size in notepad)

10
Graphics / How can I draw pretty box with .ttf font?
« on: February 29, 2016, 08:10:31 pm »
I'm trying to draw a box with sf::text with .ttf font and unicode.
but the result is a bit ugly, here's a screenshot and it's just one text object.
some fonts look better but most fonts don't look good.

I know I can draw a box with sf::Rectangle, but I want to draw it with font for some reason.
and I've tried to turn on/off the font smoothing, but it didn't help.

11
Graphics / Re: Monospace fonts is not rendered correctly
« on: October 19, 2015, 07:13:43 am »
Yes, actually some fonts work fine. but also some fonts don't work as monospace.

Edit: Oh, It looks because of the bugs of fonts themselves.
but I still don't know why they're normal in other environments.

12
Graphics / Re: Monospace fonts is not rendered correctly
« on: October 19, 2015, 01:28:59 am »
This is the screenshot of FantasqueSansMono-Regular font.
It's one sf::Text object.
(I use Windows 10, VS2015, and the latest version of SFML which I built myself)

13
Graphics / Monospace fonts is not rendered correctly
« on: October 18, 2015, 03:12:32 pm »
I'm making a pseudo-console using SFML with a monospace font.
but I found that the monospace fonts is not rendered correctly in SFML.

the width(the 'advance' of the glyph) values are not equal.
and the 'bounds'  values of the glyph are also a bit strange.

here's some glyph data from my test.
(I tested a few monospace fonts, and they're normal in other environments)

any help would be appreciated. Thanks :)

 // OfficeCodePro, 20px
 // bounds = (left, top, width, height)
 'I' : bounds =  2, -14,  8, 14, advance = 12
 'J' : bounds =  1, -14,  9, 14, advance = 12
 'K' : bounds =  2, -14, 10, 14, advance = 12
 'L' : bounds =  3, -14,  8, 14, advance = 12
 'M' : bounds =  2, -14, 10, 14, advance = 13
 'N' : bounds =  2, -14,  9, 14, advance = 12
 'O' : bounds =  1, -14, 10, 14, advance = 12
 'P' : bounds =  2, -14,  9, 14, advance = 12
 'Q' : bounds =  1, -14, 11, 18, advance = 12
 'R' : bounds =  2, -14, 10, 14, advance = 12

 // FantasqueSansMono, 20px
 'I' : bounds =  1, -13,  7, 13, advance = 10
 'J' : bounds =  1, -13,  9, 13, advance = 10
 'K' : bounds =  1, -13,  9, 14, advance = 10
 'L' : bounds =  1, -13,  8, 13, advance = 10
 'M' : bounds =  1, -13,  8, 13, advance = 11
 'N' : bounds =  1, -13,  8, 13, advance = 10
 'O' : bounds =  1, -13,  9, 13, advance = 11
 'P' : bounds =  1, -13,  8, 13, advance = 10
 'Q' : bounds =  1, -13,  9, 15, advance = 10
 'R' : bounds =  1, -13,  9, 14, advance = 10
 

14
Graphics / is it ok to load texture object multiple times?
« on: July 20, 2015, 12:21:02 pm »
Hello there,

I use only one sf::Texture object as a tileset at the same time.
but sometimes I need to change a tileset in game. (runtime)
in this case, can I call loadFromFile function again?
is there any drawback like waste memory? or should I delete and create the object?

Thanks.

15
General / Re: Strange behavior with isKeyPressed() function
« on: July 11, 2015, 05:01:30 pm »
I'm sure it's not the problem of keyboard limitation.
and I tested it on my laptop (windows 10) and the result was the same.

Holding numpad + shift (with numlock) for a while often make the program holds that numpad key forever.

Pages: [1] 2 3
anything