Scaling Text in SDL

How can I make text scale properly with different DPI settings?

Text scaling requires additional considerations beyond simply multiplying dimensions by a scale factor. Here's how to handle text scaling properly in SDL:

Using SDL_ttf

First, we need to use SDL's text rendering library, SDL_ttf. Here's a complete example that shows how to render scaled text:

#include <SDL.h>
#include <SDL_ttf.h>
#include <iostream>

float GetDPIScale(SDL_Window* Window) {
  int w1, w2;
  SDL_GetWindowSize(Window, &w1, nullptr);
  SDL_GetWindowSizeInPixels(
    Window, &w2, nullptr);
  return float(w2) / w1;
}

int main(int argc, char* argv[]) {
  SDL_SetHint(
    SDL_HINT_WINDOWS_DPI_SCALING, "1");
  SDL_Init(SDL_INIT_VIDEO);
  TTF_Init();

  SDL_Window* Window{
    SDL_CreateWindow(
      "Text Scaling Demo",
      SDL_WINDOWPOS_UNDEFINED,
      SDL_WINDOWPOS_UNDEFINED,
      800, 200, 0)};

  float Scale{GetDPIScale(Window)};

  // Load font and scale the size based on DPI
  TTF_Font* Font{
    TTF_OpenFont(
      "arial.ttf",
      int(24 * Scale))}; 

  SDL_Surface* Surface{
    SDL_GetWindowSurface(Window)};
  SDL_FillRect(
    Surface, nullptr,
    SDL_MapRGB(Surface->format, 255, 255, 255));

  // Render text
  SDL_Color TextColor{0, 0, 0};
  SDL_Surface* TextSurface{
    TTF_RenderText_Blended(
      Font,
      "Hello, DPI-aware world!",
      TextColor)};

  // Calculate position to center the text
  SDL_Rect Position{
    (Surface->w - TextSurface->w) / 2,
    (Surface->h - TextSurface->h) / 2,
    TextSurface->w,
    TextSurface->h
  };

  SDL_BlitSurface(
    TextSurface, nullptr, Surface, &Position
  );
  SDL_UpdateWindowSurface(Window);

  SDL_Event E;
  bool Running{true};
  while (Running) {
    while (SDL_PollEvent(&E)) {
      if (E.type == SDL_QUIT) Running = false;
    }
  }

  TTF_CloseFont(Font);
  SDL_FreeSurface(TextSurface);
  SDL_DestroyWindow(Window);
  TTF_Quit();
  SDL_Quit();
  return 0;
}

The key to proper text scaling is scaling the font size itself rather than trying to scale the rendered text surface. Notice how we multiply the desired font size by our DPI scale when opening the font.

You might be tempted to render the text at a base size and then scale the surface, but this leads to blurry text. By scaling the font size directly, we get crisp text at any DPI.

Additional Considerations

When working with text in a DPI-aware application, keep these points in mind:

  • Cache your fonts at commonly used sizes to improve performance
  • Consider using different font weights at different scales
  • Test your text rendering at various DPI scales to ensure readability

Pixel Density and High-DPI Displays

Learn how to create SDL applications that look great on modern displays across different platforms

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Why Handle DPI Scaling
Why do we need to handle DPI scaling at all? Can't we just let the operating system handle it?
Image Scaling and DPI
If I'm loading images for my game, do I need different versions for different DPI settings?
DPI Scale Calculation
In GetDPIScale(), why do we only use the width to calculate the scale? What about height?
DPI with SDL_Renderer
The example uses SDL_Surface. Does DPI scaling work differently with SDL_Renderer or SDL_Texture?
UI Elements and DPI
How do I handle DPI scaling for UI elements like buttons that need to stay a specific physical size?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant