grimfang4 / SDL_FontCache

A generic font caching C library with loading and rendering support for SDL.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Non-ascii characters do not display when using DrawBox functions

opened this issue · comments

It seems that when you use any of the DrawBox functions only ascii characters will be drawn.

Example:

// this will correctly display as "abcåäöabc"
FC_Draw(m_font, renderer, 10, 10, "abcåäöabc");

// this will display as "abc abc", and the swedish letters have been replaced with spaces
FC_DrawBox(m_font, renderer, m_rect, "abcåäöabc");

Do you have any idea why this is happening?

I would guess that there's something going wrong in FC_GetBufferFitToColumn(). FC_DrawBox() uses FC_GetBufferFitToColumn() to manipulate the string into separate strings for each line. I'll look further.

Hmm... I'm not able to reproduce this yet. I've set my file's encoding to UTF-8 so I can use raw UTF-8 literals and tried your string in FC_Draw() and FC_DrawBox() with and without the format string "%s". If you're comfortable with a debugger, could you try to track down where the UTF-8 values are being broken?

I am sorry, I still pretty new to C++ and I am afraid I would not be of much help trying to "track something down".

Last time this happened I think I just gave up and used FC_Draw instead and did the positioning manually, maybe I could do that this time too.

Ah, okay. Positioning the text yourself sounds like a good workaround until this is figured out. If you're interested and motivated, I can email with you about how to use the debugger. Otherwise, I'll keep looking.

Update:

When I use the function FC_GetWidth(font, "abcåäöabc") first there is no error and all letters are shown like they should.

// Works
FC_GetWidth(font, "abcåäöabc");
FC_DrawBox(font,renderer,FC_MakeRect(10,10,100,100),"abcåäöabc");

goodtext

// Does not work
FC_DrawBox(font,renderer,FC_MakeRect(10,10,100,100),"abcåäöabc");

badtext

What does the FC_GetWidth function do to make the text display as it should?

You should be able to use FC_DrawBox without calling FC_GetWidth first should't you?

Thanks for the further info! This behavior is a hallmark of a memory bug, so I think you're right. Would you mind passing your program through valgrind to see if it pinpoints the accesses that are causing the problem? I probably won't be able to do so myself today.

I still wasn't able to reproduce in Kubuntu 14. valgrind didn't come up with anything in my demo either. Please let me know if you can figure anything further out about this problem. Could you send me a program (source and binary) that exhibits the problem?

#include "SDL.h"
#include "SDL_ttf.h"
#include "SDL_FontCache.h"

int main (int argc, char* argv[])
{
    SDL_Init(SDL_INIT_EVERYTHING);
    TTF_Init();

    SDL_Window* window = SDL_CreateWindow("SDL_FontCache Test",
                                          SDL_WINDOWPOS_CENTERED,
                                          SDL_WINDOWPOS_CENTERED,
                                          800,600,0);

    SDL_Renderer* renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED);

    FC_Font* font = FC_CreateFont();
    FC_LoadFont(font,renderer,"DejaVuSans.ttf",16,FC_MakeColor(0,0,0,255),TTF_STYLE_NORMAL);

    SDL_Rect textrect = {10,10,100,100};
    const char* text = "abcåäöabc";

    SDL_Event event;

    while (1)
    {
        if (SDL_PollEvent(&event))
        {
            if (event.type == SDL_QUIT)
            {
                break;
            }
        }

        SDL_RenderClear(renderer);
        SDL_SetRenderDrawColor(renderer,255,255,255,255);

        // Draw text
        FC_DrawBox(font,renderer,textrect,text);

        SDL_SetRenderDrawColor(renderer,0,0,0,255);

        // Draw rect border
        SDL_RenderDrawRect(renderer,&textrect);

        SDL_SetRenderDrawColor(renderer,255,255,255,255);

        SDL_RenderPresent(renderer);

    }

    FC_FreeFont(font);
    TTF_Quit();

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

Compiled with:
g++ -Wall -g -I/usr/include/SDL2 -c test.cpp -o ./test.o
gcc -Wall -g -I/usr/include/SDL2 -c SDL_FontCache.c -o ./SDL_FontCache.o
g++ -o ./test ./test.o ./SDL_FontCache.o -lSDL2 -lSDL2_ttf

Running the above test program on my computer gives this result:

test2

The DejaVu font being used can be downloaded from here if don't have it already:
http://sourceforge.net/projects/dejavu/files/dejavu/2.35/dejavu-fonts-ttf-2.35.zip

Hmm, when I use FC_SetLoadingString(font,"abcåäö") before loading the font all text is displaying correctly. So doing either FC_GetWidth or FC_SetLoadingString will make the text appear as it should.

Is that where the problem is? The swedish letters "åäö" are not "cached" by default?

I read what you wrote here #11:

There are two ways to tell SDL_FontCache which glyphs to cache. If you have render target support, the glyphs will be cached the first time you use a string with new codepoints in it. Alternatively, you can cache all of your glyphs up front with FC_SetLoadingString().

I should be able to do FC_DrawBox without using FC_SetLoadingString first shouldn't I?

Great! I've been able to reproduce the problem by switching to that font. From first glance, there is nothing wrong with the encoding in the font file, and it seems like the logic diverges on the choice of codepoint.

Okay, this should be fixed in 2b69818!

SDL's new clipping system applies to everything until unset. I did not unset the clipping when loading new glyphs to the cache, so they were getting clipped and not stored properly. This would only occur if a clip rect was set (e.g. by DrawBox()) before a given glyph was loaded for the first time.

Can you confirm the fix?

Yes, it is working now. Thank you and good job finding the problem!

Excellent! Thanks for reporting it and helping improve this library. :)