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.


Topics - kawe

Pages: [1]
1
C / Unicode limited to Plane 0 (U+0000 to U+FFFF) in (C)SFML?
« on: July 12, 2022, 12:25:37 pm »
Hi,

I started with CSFML a couple of weeks ago.
I am *not* using SFML but only the C binding, so questions and reports here may or may not also apply to SFML itself.
I just don't know, :-).

When I came to unicode strings I first had to manage some hurdles as my programs(s) should run in a Windows an a Linux enviroment, and handling the locales and wide characters is not alway funny then.
Especially, I miss the UTF_X_toUTF_Y conversion functions in the C binding.
You may consider to add them in a future release ...
But of course, this can also manually be done.

But when I wanted to set a unicode string to an sfText ('sfText_setUnicodeString()') I had to realize that CSFML doesn't accept unicode characters on higher planes beyond U+FFFF.

So I decided to get the character by the font itself (see example below) - same result.

Good for testing is the unicode font 'unifont' from  https://www.unifoundry.com/unifont/index.html that virtually contains an image for (nearly) every single code point.

My 'test character' is U+1D11E ('Musical Symbol G Clef') but you'll find that no unicode character at all will work in (C)SFML beyond 'U+FFFF'.

Is this a bug or by design? But if it's by design - why use 4 byte long sfUint32 integers to handle them ...?

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <SFML/Graphics.h>


sfRenderWindow* window;

void selectGlyph(void *data)
{
        sfUint32 *codePoint = data;
        char buffer[8];

        while(sfRenderWindow_isOpen(window))
        {
                printf("Enter hexadecimal code point: ");
                do
                {
                        fgets(buffer, 8, stdin);
                } while (strcspn(buffer, "\n") == 7);
                *codePoint = strtoul(buffer, NULL, 16);
        }
}

int main(void)
        {
        sfVideoMode mode = {160, 160, 32};
        sfTexture* texture;
        sfSprite* sprite;
        sfEvent event;
        sfColor bColor;
       
        sfUint32 codePoint = 0x0000;
        sfUint32 oldCodePt = 0xFFFF;
        sfThread *thread = sfThread_create(selectGlyph, &codePoint);
       
        /* Create the main window */
        window = sfRenderWindow_create(mode, "CSFML Unicode Test", (sfDefaultStyle), NULL);
        if (!window)
                return EXIT_FAILURE;
        sfRenderWindow_setVerticalSyncEnabled(window, sfTrue);
        sfRenderWindow_setPosition(window, (sfVector2i){50, 50});
        /* Create a graphical text to display */
        sfFont *font = sfFont_createFromFile("unifont-14.0.04.ttf");
        if (!font)
                return EXIT_FAILURE;
        unsigned int size = 160;
       
        sfThread_launch(thread);
       
        /* Start the game loop */
        while (sfRenderWindow_isOpen(window))
        {
                /* Process events */
                while (sfRenderWindow_pollEvent(window, &event))
                {
                        /* Close window : exit */
                        if (event.type == sfEvtClosed)
                                sfRenderWindow_close(window);
                }
               
                if(codePoint != oldCodePt)
                {
                        sfGlyph glyph = sfFont_getGlyph(font, codePoint, size, sfFalse, 0);
                        const sfTexture *bitmap = sfFont_getTexture(font, size);
                        if (!bitmap)
                                return EXIT_FAILURE;
                        sfImage *chr = sfTexture_copyToImage(bitmap);
                        if(glyph.bounds.width > 0 && glyph.bounds.height > 0)
                        {
                                sfImage *image = sfImage_create(glyph.bounds.width, glyph.bounds.height);
                                sfImage_copyImage(image, chr, 0, 0, glyph.textureRect, sfFalse);
                                texture = sfTexture_createFromImage(image, NULL);
                                if (!texture)
                                return EXIT_FAILURE;
                                sprite = sfSprite_create();
                                if (!sprite)
                                        return EXIT_FAILURE;
                                sfSprite_setColor(sprite, sfBlue);
                                sfSprite_setTexture(sprite, texture, sfFalse);
                                oldCodePt = codePoint;
                                bColor = codePoint ? sfYellow : sfRed;
                        }
                        else
                                codePoint = 0;
                }
                sfRenderWindow_clear(window, bColor);
                /* Draw the sprite */
                sfRenderWindow_drawSprite(window, sprite, NULL);
                /* Update the window */
                sfRenderWindow_display(window);
        }
        /* Cleanup resources */
        sfThread_destroy(thread);
        sfSprite_destroy(sprite);
        sfTexture_destroy(texture);
        sfFont_destroy(font);
        sfRenderWindow_destroy(window);
        return EXIT_SUCCESS;
}

Pages: [1]