Pixel Density and High-DPI Displays

Scaling Text in SDL

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

Abstract art representing computer programming

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

Answers to questions are automatically generated and may not have been reviewed.

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 71 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved