SDL_ttf: Cannot load font in two different sizes

53 Views Asked by At

Here is how I load the font file:

HRSRC resourceInfo = FindResourceW(instance, MAKEINTRESOURCEW(ID_FONT), RT_RCDATA);
if (!resourceInfo)
    return false;

HGLOBAL resourceData = LoadResource(instance, resourceInfo);
if (!resourceData)
    return false;

LPVOID resource = LockResource(resourceData);
if (!resource)
    return false;
        
DWORD resourceSize = SizeofResource(instance, resourceInfo);

SDL_RWops* data = SDL_RWFromConstMem(resource, resourceSize);
if (!data)
    return false;
        
font10pt = TTF_OpenFontRW(data, SDL_FALSE, 10 * scale);
if (!font10pt)
    return false;
        
font20pt = TTF_OpenFontRW(data, SDL_FALSE, 20 * scale);
if (!font20pt)
    return false;

So with this I am able to render using the 10 pt font, but not the 20. If I reverse the order that I create the fonts in, then I can render the 20 but not the 10.

What confuses me is that both fonts, which are set to nullptr before hitting this part the code, have memory addresses like they were allocated with no issues. Calls to TTF_CloseFont have no problems. Same when I call TTF_Quit, no issues. When I create a texture using the font, it doesn't cause an error. The texture has a memory address as well.

Here is how I create textures for rendering text:

TTF_Font* font = nullptr;
switch (size) {
    case 10:
        font = font10pt;
        break;
    case 20:
        font = font20pt;
        break;
}

if (!font)
    return nullptr;
        
SDL_Color color = { 255, 255, 255 };
SDL_Surface* surface = TTF_RenderUTF8_Blended_Wrapped(font, text.c_str(), color, 0);
if (!surface)
    return nullptr;

SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);
if (!texture)
    return nullptr;

Here is where I render the textures:

SDL_Texture* texture = getCachedText(text, size);
if (!texture)
    return;

SDL_Rect dst = {};
dst.x = x * scale;
dst.y = y * scale;
SDL_QueryTexture(texture, nullptr, nullptr, &dst.w, &dst.h);

SDL_SetTextureColorMod(texture, r, g, b);
SDL_RenderCopy(renderer, texture, nullptr, &dst);

The code does not error anywhere. Both fonts and all textures still have memory addresses by the time they reach the function used for rendering (above). I am not sure what happens inside the SDL_RenderCopy but it only renders the 10 pt font.

If I rerun SDL_RWFromConstMem after loading the 10 pt font but before creating the 20 pt, then I can use both. This doesn't make sense to me because I am specifying to not close the SDL_RWops when I call TTF_OpenFontRW.

Here is what it looks like when I can render both:

SDL_RWops* data = SDL_RWFromConstMem(resource, resourceSize);
if (!data)
    return false;
        
font10pt = TTF_OpenFontRW(data, SDL_FALSE, 10 * scale);
if (!font10pt)
    return false;

data = SDL_RWFromConstMem(resource, resourceSize);
if (!data)
    return false;
        
font20pt = TTF_OpenFontRW(data, SDL_FALSE, 20 * scale);
if (!font20pt)
    return false;

Please help me understand why this is happening. I'd like to reuse the SDL_RWops to create fonts on the fly.

0

There are 0 best solutions below