30#include <Objectively/Hash.h>
31#include <Objectively/Array.h>
32#include <Objectively/String.h>
39#include "../Assets/coda.ttf.h"
64 TTF_CloseFont(this->font);
72static int hash(
const Object *self) {
77 hash = HashForCString(
hash, this->family);
79 hash = HashForInteger(
hash, this->style);
80 hash = HashForInteger(
hash, this->renderSize);
88static bool isEqual(
const Object *self,
const Object *other) {
90 if (super(Object, self,
isEqual, other)) {
94 if (other && $(other, isKindOfClass,
_Font())) {
99 if (!strcmp(this->family, that->
family) &&
101 this->style == that->
style &&
120 $(
_cache, setObjectForKeyPath, data, family);
129 if (family == NULL) {
139 const Array *fonts = (Array *)
_fonts;
140 for (
size_t i = 0; i < fonts->count; i++) {
142 Font *font = $(fonts, objectAtIndex, i);
144 if (!strcmp(font->
family, family) &&
146 font->
style == style) {
151 Data *data = $((Dictionary *)
_cache, objectForKeyPath, family);
156 $(
_fonts, addObject, font);
171 $(
_cache, removeAllObjects);
182 Data *data = $(alloc(Data), initWithConstMemory, coda_ttf, coda_ttf_len - 1);
199 self = (
Font *) super(Object, self,
init);
202 self->
data = retain(data);
205 self->
family = strdup(family);
226 SDL_Surface *surface;
228 surface = TTF_RenderText_Blended_Wrapped(self->
font, chars, 0, color, wrapWidth * self->
scale);
230 surface = TTF_RenderText_Blended(self->
font, chars, 0, color);
233 SDL_Surface *converted = NULL;
235 converted = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_RGBA32);
236 SDL_DestroySurface(surface);
250 const int renderSize = self->
size * self->
scale;
256 TTF_CloseFont(self->
font);
259 SDL_IOStream *buffer = SDL_IOFromConstMem(self->
data->bytes, (
int) self->
data->length);
265 TTF_SetFontStyle(self->
font, self->
style);
266 TTF_SetFontHinting(self->
font, TTF_HINTING_LIGHT_SUBPIXEL);
284 char *lines = strdup(chars);
286 const int font_h = TTF_GetFontHeight(self->
font);
288 for (
char *line = strtok(lines,
"\n\r"); line; line = strtok(NULL,
"\n\r")) {
294 const size_t len = strlen(line) + 2;
297 snprintf(buf, len,
"%s ", line);
301 TTF_GetStringSize(self->
font, buf, 0, &line_w, NULL);
302 *w = max(*w, line_w);
311 *w = ceilf(*w / self->
scale);
314 *h = ceilf(*h / self->
scale);
319#pragma mark - Class lifecycle
326 ((ObjectInterface *) clazz->interface)->dealloc =
dealloc;
327 ((ObjectInterface *) clazz->interface)->hash =
hash;
328 ((ObjectInterface *) clazz->interface)->isEqual =
isEqual;
330 ((FontInterface *) clazz->interface)->cachedFont =
cachedFont;
332 ((FontInterface *) clazz->interface)->clearCache =
clearCache;
333 ((FontInterface *) clazz->interface)->defaultFont =
defaultFont;
337 ((FontInterface *) clazz->interface)->sizeCharacters =
sizeCharacters;
339 const bool init = TTF_Init();
343 _cache = $$(Dictionary, dictionary);
346 _fonts = $$(Array, array);
370 clazz = _initialize(&(
const ClassDef) {
372 .superclass = _Object(),
373 .instanceSize =
sizeof(
Font),
374 .interfaceOffset = offsetof(
Font, interface),
375 .interfaceSize =
sizeof(FontInterface),
static View * init(View *self)
static void destroy(Class *clazz)
static void sizeCharacters(const Font *self, const char *chars, int *w, int *h)
static SDL_Surface * renderCharacters(const Font *self, const char *chars, SDL_Color color, int wrapWidth)
static void clearCache(void)
static Font * cachedFont(const char *family, int size, int style)
static bool isEqual(const Object *self, const Object *other)
static void renderDeviceDidReset(Font *self)
static Font * initWithData(Font *self, Data *data, const char *family, int size, int style)
static void dealloc(Object *self)
static Dictionary * _cache
const EnumName FontStyleNames[]
static void initialize(Class *clazz)
static void cacheFont(Data *data, const char *family)
static int hash(const Object *self)
static Font * defaultFont(void)
#define DEFAULT_FONT_STYLE
#define DEFAULT_FONT_FAMILY
#define DEFAULT_FONT_SIZE
static SDL_Size size(const Image *self)
View logging facilities via SDL_Log.
#define MVC_LogWarn(fmt,...)
#define MVC_LogError(fmt,...)
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
void(* cacheFont)(Data *data, const char *family)
Caches the specified font Data.
float scale
The display pixel density scale (e.g. 2.0 on Retina). Updated by callers via the scale field before i...
int renderSize
The render size, adjusted for display density.
char * family
The family name.
void renderCharacters(const Font *self, const char *chars, SDL_Color color, int wrapWidth)
Renders the given characters in this Font.
Font * initWithData(Font *self, Data *data, int size, int index)
TTF_Font * font
The backing font.
Data * data
The raw font data.