ObjectivelyMVC 0.1.0
Object oriented MVC framework for OpenGL, SDL2 and GNU C
Macros | Functions | Variables
Font.c File Reference
#include <assert.h>
#include <string.h>
#include <Objectively/Hash.h>
#include <Objectively/MutableArray.h>
#include <Objectively/String.h>
#include "Font.h"
#include "Log.h"
#include "View.h"
#include "Window.h"
#include "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 MutableDictionary * _cache
 
static MutableArray * _fonts
 
const EnumName FontStyleNames []
 

Macro Definition Documentation

◆ _Class

#define _Class   _Font

Definition at line 46 of file Font.c.

Function Documentation

◆ _Font()

Class * _Font ( void  )

Definition at line 353 of file Font.c.

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

◆ cachedFont()

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

Definition at line 124 of file Font.c.

124 {
125
126 if (family == NULL) {
127 family = DEFAULT_FONT_FAMILY;
128 }
129 if (size < 1) {
131 }
132 if (style < FontStyleRegular || style > FontStyleStrikeThrough) {
133 style = DEFAULT_FONT_STYLE;
134 }
135
136 const int renderSize = size * MVC_WindowScale(NULL, NULL, NULL);
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 font->renderSize == renderSize) {
147 return font;
148 }
149 }
150
151 Data *data = $((Dictionary *) _cache, objectForKeyPath, family);
152 if (data) {
153 Font *font = $(alloc(Font), initWithData, data, family, size, style);
154 assert(font);
155
156 $(_fonts, addObject, font);
157 release(font);
158
159 return font;
160 }
161
162 MVC_LogWarn("%s-%d-%d not found\n", family, size, style);
163 return $$(Font, defaultFont);
164}
static MutableDictionary * _cache
Definition: Font.c:109
static MutableArray * _fonts
Definition: Font.c:110
#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
#define MVC_LogWarn(fmt,...)
Definition: Log.h:52
double MVC_WindowScale(SDL_Window *window, int *height, int *drawableHeight)
Resolves the scale factor of the specified window for High-DPI support.
Definition: Window.c:47
int renderSize
The render size, adjusted for display density.
Definition: Font.h:94
char * family
The family name.
Definition: Font.h:84
Font * defaultFont(void)
Definition: Font.c:178
Font * initWithData(Font *self, Data *data, int size, int index)
int size
The point size.
Definition: Font.h:99
int style
The style.
Definition: Font.h:104
SDL_Size size(const Image *self)
Definition: Image.c:181

◆ cacheFont()

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

Definition at line 116 of file Font.c.

116 {
117 $(_cache, setObjectForKeyPath, data, family);
118}

◆ clearCache()

static void clearCache ( void  )
static

Definition at line 170 of file Font.c.

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

◆ dealloc()

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

Definition at line 53 of file Font.c.

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

◆ defaultFont()

static Font * defaultFont ( void  )
static

Definition at line 178 of file Font.c.

178 {
179 static Once once;
180
181 do_once(&once, {
182 Data *data = $(alloc(Data), initWithConstMemory, coda_ttf, coda_ttf_len);
183 assert(data);
184
186
187 release(data);
188 });
189
191}
void(* cacheFont)(Data *data, const char *family)
Caches the specified font Data.
Definition: Font.h:136
Font * cachedFont(const char *family, int size, int style)
Resolves the cached Font with the given attributes.
Definition: Font.c:124

◆ destroy()

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

Definition at line 341 of file Font.c.

341 {
342
343 release(_cache);
344 release(_fonts);
345
346 TTF_Quit();
347}

◆ hash()

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

Definition at line 69 of file Font.c.

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

◆ initialize()

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

Definition at line 313 of file Font.c.

313 {
314
315 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
316 ((ObjectInterface *) clazz->interface)->hash = hash;
317 ((ObjectInterface *) clazz->interface)->isEqual = isEqual;
318
319 ((FontInterface *) clazz->interface)->cachedFont = cachedFont;
320 ((FontInterface *) clazz->interface)->cacheFont = cacheFont;
321 ((FontInterface *) clazz->interface)->clearCache = clearCache;
322 ((FontInterface *) clazz->interface)->defaultFont = defaultFont;
323 ((FontInterface *) clazz->interface)->initWithData = initWithData;
324 ((FontInterface *) clazz->interface)->renderCharacters = renderCharacters;
325 ((FontInterface *) clazz->interface)->renderDeviceDidReset = renderDeviceDidReset;
326 ((FontInterface *) clazz->interface)->sizeCharacters = sizeCharacters;
327
328 const int err = TTF_Init();
329 assert(err == 0);
330
331 _cache = $$(MutableDictionary, dictionary);
332 assert(_cache);
333
334 _fonts = $$(MutableArray, array);
335 assert(_fonts);
336}
static _Bool isEqual(const Object *self, const Object *other)
Definition: Font.c:85
void renderCharacters(const Font *self, const char *chars, SDL_Color color, int wrapWidth)
Renders the given characters in this Font.
Definition: Font.c:223
void renderDeviceDidReset(Font *self)
This method should be invoked when the render context is invalidated.
Definition: Font.c:247
void clearCache(void)
Clears the Font cache.
Definition: Font.c:170
void sizeCharacters(const Font *self, const char *chars, int *w, int *h)
Definition: Font.c:272

◆ initWithData()

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

Definition at line 197 of file Font.c.

197 {
198
199 self = (Font *) super(Object, self, init);
200 if (self) {
201
202 self->data = retain(data);
203 assert(self->data);
204
205 self->family = strdup(family);
206 assert(self->family);
207
208 self->size = size;
209 assert(self->size);
210
211 self->style = style;
212
213 $(self, renderDeviceDidReset);
214 }
215
216 return self;
217}
CollectionView * init(CollectionView *self, const SDL_Rect *frame)
Initializes this CollectionView with the specified frame and style.
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 85 of file Font.c.

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

◆ 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_RenderUTF8_Blended_Wrapped(self->font, chars, color, wrapWidth * MVC_WindowScale(NULL, NULL, NULL));
228 } else {
229 surface = TTF_RenderUTF8_Blended(self->font, chars, color);
230 }
231
232 SDL_Surface *converted = NULL;
233 if (surface) {
234 converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA32, 0);
235 SDL_FreeSurface(surface);
236 } else {
237 MVC_LogError("%s\n", TTF_GetError());
238 }
239
240 return converted;
241}
#define MVC_LogError(fmt,...)
Definition: Log.h:55
ident 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 * MVC_WindowScale(NULL, NULL, NULL);
250 if (renderSize != self->renderSize) {
251
252 self->renderSize = renderSize;
253
254 if (self->font) {
255 TTF_CloseFont(self->font);
256 }
257
258 SDL_RWops *buffer = SDL_RWFromConstMem(self->data->bytes, (int) self->data->length);
259 assert(buffer);
260
261 self->font = TTF_OpenFontRW(buffer, 1, self->renderSize);
262 assert(self->font);
263
264 TTF_SetFontStyle(self->font, self->style);
265 }
266}

◆ sizeCharacters()

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

Definition at line 272 of file Font.c.

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

Variable Documentation

◆ _cache

MutableDictionary* _cache
static

Definition at line 109 of file Font.c.

◆ _fonts

MutableArray* _fonts
static

Definition at line 110 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 38 of file Font.c.