aboutsummaryrefslogtreecommitdiff
path: root/src/sdl/draw-text.c
blob: 0e58949d3d4e2921e51b707db46a361f7b2ad9ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "draw-text.h"
#include "util.h"

static SDL_Rect
text_get_rect(
  SDL_Renderer * const renderer,
  TTF_Font * const font,
  const text_style_t * const style,
  const char * const buf
) {
  // get renderer size
  int renderer_w, renderer_h;
  if (SDL_GetRendererOutputSize(renderer, &renderer_w, &renderer_h)) {
    die("SDL_GetRendererOutputSize(): %s", SDL_GetError());
  }

  // get text size
  int text_w, text_h;
  if (TTF_SizeText(font, buf, &text_w, &text_h)) {
    die("TTF_SizeText(): %s", TTF_GetError());
  }

  // build rect
  switch (style->align) {
  case TEXT_ALIGN_TOP_LEFT:
    return (SDL_Rect) { 
      .x = style->pad.x,
      .y = style->pad.y,
      .w = text_w,
      .h = text_h,
    };
  case TEXT_ALIGN_TOP_CENTER:
    return (SDL_Rect) {
      .x = (renderer_w - text_w) / 2 + style->pad.x,
      .y = style->pad.y,
      .w = text_w,
      .h = text_h,
    };
  case TEXT_ALIGN_TOP_RIGHT:
    return (SDL_Rect) {
      .x = renderer_w - text_w - style->pad.x,
      .y = style->pad.y,
      .w = text_w,
      .h = text_h,
    };
  case TEXT_ALIGN_CENTER_LEFT:
    return (SDL_Rect) {
      .x = style->pad.x,
      .y = (renderer_h - text_h) / 2 + style->pad.y,
      .w = text_w,
      .h = text_h,
    };
  case TEXT_ALIGN_CENTER_CENTER:
    return (SDL_Rect) {
      .x = (renderer_w - text_w) / 2 + style->pad.x,
      .y = (renderer_h - text_h) / 2 + style->pad.y,
      .w = text_w,
      .h = text_h,
    };
  case TEXT_ALIGN_CENTER_RIGHT:
    return (SDL_Rect) {
      .x = renderer_w - text_w - style->pad.x,
      .y = (renderer_h - text_h) / 2 + style->pad.y,
      .w = text_w,
      .h = text_h,
    };
  case TEXT_ALIGN_BOTTOM_LEFT:
    return (SDL_Rect) {
      .x = style->pad.x,
      .y = renderer_h - text_h - style->pad.y,
      .w = text_w,
      .h = text_h,
    };
  case TEXT_ALIGN_BOTTOM_CENTER:
    return (SDL_Rect) {
      .x = (renderer_w - text_w) / 2 + style->pad.x,
      .y = renderer_h - text_h - style->pad.y,
      .w = text_w,
      .h = text_h,
    };
  case TEXT_ALIGN_BOTTOM_RIGHT:
    return (SDL_Rect) {
      .x = renderer_w - text_w - style->pad.x,
      .y = renderer_h - text_h - style->pad.y,
      .w = text_w,
      .h = text_h,
    };
  default:
    return (SDL_Rect) {
      .x = style->pad.x,
      .y = style->pad.y,
      .w = text_w,
      .h = text_h,
    };
  }
}

void
draw_text(
  SDL_Renderer * const renderer,
  TTF_Font * const font,
  const text_style_t * const style,
  const char * const buf
) {
  // get rect
  const SDL_Rect rect = text_get_rect(renderer, font, style, buf);

  // create surface, check for error
  SDL_Surface *surface = TTF_RenderText_Shaded(font, buf, style->colors[0], style->colors[1]);
  if (!surface) {
    die("TTF_RenderText_Blended(): %s", TTF_GetError());
  }

  // create texture, check for error
  SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
  if (!texture) {
    die("SDL_CreateTextureFromSurface(): %s", SDL_GetError());
  }

  // free surface
  SDL_FreeSurface(surface);

  // render text
  if (SDL_RenderCopy(renderer, texture, NULL, &rect)) {
    die("SDL_RenderCopy(): %s", SDL_GetError());
  }

  // free texture
  SDL_DestroyTexture(texture);
}