ObjectivelyMVC
Object oriented MVC framework for SDL3 and GNU C
Loading...
Searching...
No Matches
Font.c File Reference
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <Objectively/Hash.h>
#include <Objectively/Array.h>
#include <Objectively/String.h>
#include "Font.h"
#include "Log.h"
#include "View.h"
#include "Window.h"
#include "../Assets/coda.ttf.h"

Go to the source code of this file.

Macros

#define _Class   _Font
 

Functions

Class * _Font (void)
 
static FontcachedFont (const char *family, int size, int style)
 
static void cacheFont (Data *data, const char *family)
 
static void clearCache (void)
 
static void dealloc (Object *self)
 
static FontdefaultFont (void)
 
static void destroy (Class *clazz)
 
static int hash (const Object *self)
 
static void initialize (Class *clazz)
 
static FontinitWithData (Font *self, Data *data, const char *family, int size, int style)
 
static bool isEqual (const Object *self, const Object *other)
 
static SDL_Surface * renderCharacters (const Font *self, const char *chars, SDL_Color color, int wrapWidth)
 
static void renderDeviceDidReset (Font *self)
 
static void sizeCharacters (const Font *self, const char *chars, int *w, int *h)
 

Variables

static Dictionary * _cache
 
static Array * _fonts
 
const EnumName FontStyleNames []
 

Macro Definition Documentation

◆ _Class

#define _Class   _Font

Definition at line 48 of file Font.c.

Function Documentation

◆ _Font()

Class * _Font ( void  )

Definition at line 355 of file Font.c.

355 {
356 static Class *clazz;
357 static Once once;
358
359 do_once(&once, {
360 clazz = _initialize(&(const ClassDef) {
361 .name = "Font",
362 .superclass = _Object(),
363 .instanceSize = sizeof(Font),
364 .interfaceOffset = offsetof(Font, interface),
365 .interfaceSize = sizeof(FontInterface),
367 .destroy = destroy,
368 });
369 });
370
371 return clazz;
372}
static void destroy(Class *clazz)
Definition Font.c:343
static void initialize(Class *clazz)
Definition Font.c:314
TrueType fonts.
Definition Font.h:63

◆ cachedFont()

static Font * cachedFont ( const char *  family,
int  size,
int  style 
)
static

Definition at line 126 of file Font.c.

126 {
127
128 if (family == NULL) {
129 family = DEFAULT_FONT_FAMILY;
130 }
131 if (size < 1) {
133 }
134 if (style < FontStyleRegular || style > FontStyleStrikeThrough) {
135 style = DEFAULT_FONT_STYLE;
136 }
137
138 const Array *fonts = (Array *) _fonts;
139 for (size_t i = 0; i < fonts->count; i++) {
140
141 Font *font = $(fonts, objectAtIndex, i);
142
143 if (!strcmp(font->family, family) &&
144 font->size == size &&
145 font->style == style) {
146 return font;
147 }
148 }
149
150 Data *data = $((Dictionary *) _cache, objectForKeyPath, family);
151 if (data) {
152 Font *font = $(alloc(Font), initWithData, data, family, size, style);
153 assert(font);
154
155 $(_fonts, addObject, font);
156 release(font);
157
158 return font;
159 }
160
161 MVC_LogWarn("%s-%d-%d not found\n", family, size, style);
162 return $$(Font, defaultFont);
163}
static Font * initWithData(Font *self, Data *data, const char *family, int size, int style)
Definition Font.c:196
static Dictionary * _cache
Definition Font.c:111
static Array * _fonts
Definition Font.c:112
static Font * defaultFont(void)
Definition Font.c:177
#define DEFAULT_FONT_STYLE
Definition Font.h:36
@ FontStyleStrikeThrough
Definition Font.h:51
#define DEFAULT_FONT_FAMILY
Definition Font.h:34
#define DEFAULT_FONT_SIZE
Definition Font.h:35
static SDL_Size size(const Image *self)
Definition Image.c:181
#define MVC_LogWarn(fmt,...)
Definition Log.h:54
char * family
The family name.
Definition Font.h:84
int size
The point size.
Definition Font.h:105
int style
The style.
Definition Font.h:110

◆ cacheFont()

static void cacheFont ( Data *  data,
const char *  family 
)
static

Definition at line 118 of file Font.c.

118 {
119 $(_cache, setObjectForKeyPath, data, family);
120}

◆ clearCache()

static void clearCache ( void  )
static

Definition at line 169 of file Font.c.

169 {
170 $(_cache, removeAllObjects);
171}

◆ dealloc()

static void dealloc ( Object *  self)
static
See also
Object::dealloc(Object *)

Definition at line 55 of file Font.c.

55 {
56
57 Font *this = (Font *) self;
58
59 free(this->family);
60
61 release(this->data);
62
63 TTF_CloseFont(this->font);
64
65 super(Object, self, dealloc);
66}
static void dealloc(Object *self)
Definition Font.c:55

◆ defaultFont()

static Font * defaultFont ( void  )
static

Definition at line 177 of file Font.c.

177 {
178 static Once once;
179
180 do_once(&once, {
181 Data *data = $(alloc(Data), initWithConstMemory, coda_ttf, coda_ttf_len - 1);
182 assert(data);
183
185
186 release(data);
187 });
188
190}
static Font * cachedFont(const char *family, int size, int style)
Definition Font.c:126
static void cacheFont(Data *data, const char *family)
Definition Font.c:118

◆ destroy()

static void destroy ( Class *  clazz)
static
See also
Class::destroy(Class *)

Definition at line 343 of file Font.c.

343 {
344
345 release(_cache);
346 release(_fonts);
347
348 TTF_Quit();
349}

◆ hash()

static int hash ( const Object *  self)
static
See also
Object::hash(const Object *)

Definition at line 71 of file Font.c.

71 {
72
73 Font *this = (Font *) self;
74
75 int hash = HASH_SEED;
76 hash = HashForCString(hash, this->family);
77 hash = HashForInteger(hash, this->size);
78 hash = HashForInteger(hash, this->style);
79 hash = HashForInteger(hash, this->renderSize);
80
81 return hash;
82}
static int hash(const Object *self)
Definition Font.c:71

◆ initialize()

static void initialize ( Class *  clazz)
static
See also
Class::initialize(Class *)

Definition at line 314 of file Font.c.

314 {
315
316 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
317 ((ObjectInterface *) clazz->interface)->hash = hash;
318 ((ObjectInterface *) clazz->interface)->isEqual = isEqual;
319
320 ((FontInterface *) clazz->interface)->cachedFont = cachedFont;
321 ((FontInterface *) clazz->interface)->cacheFont = cacheFont;
322 ((FontInterface *) clazz->interface)->clearCache = clearCache;
323 ((FontInterface *) clazz->interface)->defaultFont = defaultFont;
324 ((FontInterface *) clazz->interface)->initWithData = initWithData;
325 ((FontInterface *) clazz->interface)->renderCharacters = renderCharacters;
326 ((FontInterface *) clazz->interface)->renderDeviceDidReset = renderDeviceDidReset;
327 ((FontInterface *) clazz->interface)->sizeCharacters = sizeCharacters;
328
329 const bool init = TTF_Init();
330 assert(init);
331 (void) init;
332
333 _cache = $$(Dictionary, dictionary);
334 assert(_cache);
335
336 _fonts = $$(Array, array);
337 assert(_fonts);
338}
static View * init(View *self)
Definition Box.c:67
static void sizeCharacters(const Font *self, const char *chars, int *w, int *h)
Definition Font.c:273
static SDL_Surface * renderCharacters(const Font *self, const char *chars, SDL_Color color, int wrapWidth)
Definition Font.c:223
static void clearCache(void)
Definition Font.c:169
static bool isEqual(const Object *self, const Object *other)
Definition Font.c:87
static void renderDeviceDidReset(Font *self)
Definition Font.c:247
void(* cacheFont)(Data *data, const char *family)
Caches the specified font Data.
Definition Font.h:142
void renderCharacters(const Font *self, const char *chars, SDL_Color color, int wrapWidth)
Renders the given characters in this Font.
Definition Font.c:223
Font * initWithData(Font *self, Data *data, int size, int index)

◆ initWithData()

static Font * initWithData ( Font self,
Data *  data,
const char *  family,
int  size,
int  style 
)
static

Definition at line 196 of file Font.c.

196 {
197
198 self = (Font *) super(Object, self, init);
199 if (self) {
200
201 self->data = retain(data);
202 assert(self->data);
203
204 self->family = strdup(family);
205 assert(self->family);
206
207 self->size = size;
208 assert(self->size);
209
210 self->style = style;
211 self->scale = 1.0f;
212
213 $(self, renderDeviceDidReset);
214 }
215
216 return self;
217}
float scale
The display pixel density scale (e.g. 2.0 on Retina). Updated by callers via the scale field before i...
Definition Font.h:100
Data * data
The raw font data.
Definition Font.h:79

◆ isEqual()

static bool isEqual ( const Object *  self,
const Object *  other 
)
static
See also
Object::isEqual(const Object *, const Object *)

Definition at line 87 of file Font.c.

87 {
88
89 if (super(Object, self, isEqual, other)) {
90 return true;
91 }
92
93 if (other && $(other, isKindOfClass, _Font())) {
94
95 const Font *this = (Font *) self;
96 const Font *that = (Font *) other;
97
98 if (!strcmp(this->family, that->family) &&
99 this->size == that->size &&
100 this->style == that->style &&
101 this->renderSize == that->renderSize) {
102 return true;
103 }
104 }
105
106 return false;
107}
Class * _Font(void)
Definition Font.c:355
int renderSize
The render size, adjusted for display density.
Definition Font.h:94

◆ renderCharacters()

static SDL_Surface * renderCharacters ( const Font self,
const char *  chars,
SDL_Color  color,
int  wrapWidth 
)
static

Definition at line 223 of file Font.c.

223 {
224
225 SDL_Surface *surface;
226 if (wrapWidth) {
227 surface = TTF_RenderText_Blended_Wrapped(self->font, chars, 0, color, wrapWidth * self->scale);
228 } else {
229 surface = TTF_RenderText_Blended(self->font, chars, 0, color);
230 }
231
232 SDL_Surface *converted = NULL;
233 if (surface) {
234 converted = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_RGBA32);
235 SDL_DestroySurface(surface);
236 } else {
237 MVC_LogError("%s\n", SDL_GetError());
238 }
239
240 return converted;
241}
#define MVC_LogError(fmt,...)
Definition Log.h:57
TTF_Font * font
The backing font.
Definition Font.h:89

◆ renderDeviceDidReset()

static void renderDeviceDidReset ( Font self)
static

Definition at line 247 of file Font.c.

247 {
248
249 const int renderSize = self->size * self->scale;
250 if (renderSize != self->renderSize) {
251
252 self->renderSize = renderSize;
253
254 if (self->font) {
255 TTF_CloseFont(self->font);
256 }
257
258 SDL_IOStream *buffer = SDL_IOFromConstMem(self->data->bytes, (int) self->data->length);
259 assert(buffer);
260
261 self->font = TTF_OpenFontIO(buffer, 1, self->renderSize);
262 assert(self->font);
263
264 TTF_SetFontStyle(self->font, self->style);
265 TTF_SetFontHinting(self->font, TTF_HINTING_LIGHT_SUBPIXEL);
266 }
267}

◆ sizeCharacters()

static void sizeCharacters ( const Font self,
const char *  chars,
int *  w,
int *  h 
)
static

Definition at line 273 of file Font.c.

273 {
274
275 if (w) {
276 *w = 0;
277 }
278 if (h) {
279 *h = 0;
280 }
281
282 if (chars) {
283 char *lines = strdup(chars);
284
285 const int font_h = TTF_GetFontHeight(self->font);
286
287 for (char *line = strtok(lines, "\n\r"); line; line = strtok(NULL, "\n\r")) {
288
289 if (w) {
290 int line_w;
291 TTF_GetStringSize(self->font, line, 0, &line_w, NULL);
292 *w = max(*w, line_w);
293 }
294 if (h) {
295 *h += font_h;
296 }
297 }
298 free(lines);
299
300 if (w) {
301 *w = ceilf(*w / self->scale);
302 }
303 if (h) {
304 *h = ceilf(*h / self->scale);
305 }
306 }
307}

Variable Documentation

◆ _cache

Dictionary* _cache
static

Definition at line 111 of file Font.c.

◆ _fonts

Array* _fonts
static

Definition at line 112 of file Font.c.

◆ FontStyleNames

const EnumName FontStyleNames[]
Initial value:
= MakeEnumNames(
MakeEnumAlias(FontStyleRegular, regular),
MakeEnumAlias(FontStyleBold, bold),
MakeEnumAlias(FontStyleItalic, italic),
MakeEnumAlias(FontStyleUnderline, underline),
MakeEnumAlias(FontStyleStrikeThrough, strikethrough)
)
@ FontStyleUnderline
Definition Font.h:50
@ FontStyleBold
Definition Font.h:48
@ FontStyleRegular
Definition Font.h:47
@ FontStyleItalic
Definition Font.h:49

Definition at line 40 of file Font.c.