30#include <Objectively/Hash.h>
31#include <Objectively/Array.h>
32#include <Objectively/String.h>
39#include "../Assets/coda.ttf.h"
40#include "../Assets/shareTechMono.ttf.h"
63 TTF_CloseFont(this->
font);
76static int hash(
const Object *self) {
81 hash = HashForCString(
hash, this->family);
83 hash = HashForInteger(
hash, this->style);
84 hash = HashForInteger(
hash, this->renderSize);
92static bool isEqual(
const Object *self,
const Object *other) {
94 if (super(Object, self,
isEqual, other)) {
98 if (other && $(other, isKindOfClass,
_Font())) {
103 if (!strcmp(this->family, that->
family) &&
105 this->style == that->
style &&
123 $(
_cache, setObjectForKeyPath, data, family);
132 if (attributes->
family == NULL) {
136 if (attributes->
size < 1) {
150 $(
_cache, removeAllObjects);
204 if (pixelDensity < 1.f) {
208 Data *data = $((Dictionary *)
_cache, objectForKeyPath, normalized.
family);
228 char *chars = strdup(
name);
233 char *styleToken = strrchr(chars,
'-');
235 *styleToken++ =
'\0';
237 char *sizeToken = strrchr(chars,
'-');
242 chars, (int) strtol(sizeToken, NULL, 10), valueof(
FontStyleNames, styleToken)
265 self = (
Font *) super(Object, self,
init);
268 self->
data = retain(data);
282 SDL_IOStream *buffer = SDL_IOFromConstMem(self->
data->bytes, (
int) self->
data->length);
288 TTF_SetFontStyle(self->
font, self->
style);
289 TTF_SetFontHinting(self->
font, TTF_HINTING_LIGHT_SUBPIXEL);
291 if (TTF_FontIsFixedWidth(self->
font)) {
318 if (en->value == normalized.
style) {
319 return str(
"%s-%d-%s", normalized.
family, normalized.
size, en->alias ?: en->name);
323 return str(
"%s-%d-%d", normalized.
family, normalized.
size, normalized.
style);
335 SDL_Surface *surface = TTF_RenderText_Blended_Wrapped(self->
font, chars, 0, color, wrapWidth * self->
pixelDensity);
337 SDL_Surface *converted = NULL;
339 converted = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_RGBA32);
340 SDL_DestroySurface(surface);
362 char *lines = strdup(chars);
364 const int font_h = TTF_GetFontHeight(self->
font);
366 for (
char *line = strtok(lines,
"\n\r"); line; line = strtok(NULL,
"\n\r")) {
371 TTF_GetStringSize(self->
font, line, 0, &lineWidth, NULL);
376 const char *end = line + strlen(line);
377 const Uint32 ch = SDL_StepBackUTF8(line, &end);
380 if (TTF_GetGlyphMetrics(self->
font, ch, NULL, &maxX, NULL, NULL, &advance)) {
381 if (maxX > advance) {
382 lineWidth += maxX - advance;
387 *w = max(*w, lineWidth);
404#pragma mark - Class lifecycle
411 ((ObjectInterface *) clazz->interface)->dealloc =
dealloc;
412 ((ObjectInterface *) clazz->interface)->hash =
hash;
413 ((ObjectInterface *) clazz->interface)->isEqual =
isEqual;
415 ((FontInterface *) clazz->interface)->cacheFont =
cacheFont;
416 ((FontInterface *) clazz->interface)->clearCache =
clearCache;
417 ((FontInterface *) clazz->interface)->defaultFont =
defaultFont;
422 ((FontInterface *) clazz->interface)->
name =
name;
428 ((FontInterface *) clazz->interface)->sizeCharacters =
sizeCharacters;
430 const bool init = TTF_Init();
434 _cache = $$(Dictionary, dictionary);
437 Data *coda = $(alloc(Data), initWithConstMemory, coda_ttf, coda_ttf_len - 1);
442 Data *shareTechMono = $(alloc(Data), initWithConstMemory, shareTechMono_ttf, shareTechMono_ttf_len - 1);
443 assert(shareTechMono);
445 release(shareTechMono);
469 clazz = _initialize(&(
const ClassDef) {
471 .superclass = _Object(),
472 .instanceSize =
sizeof(
Font),
473 .interfaceSize =
sizeof(FontInterface),
static View * init(View *self)
void renderCharactersBitmap(Font *self, const Renderer *renderer, const char *chars, SDL_Color color, int wrapWidth, const SDL_Point *origin, const ImageAtlas *icons)
Implements Font::renderBitmapCharacters.
void deallocBitmap(FontBitmap *bitmap)
Releases the resources held by bitmap. Safe to call on a zeroed FontBitmap.
void renderDeviceWillResetBitmap(Font *self)
Implements Font::renderDeviceWillReset.
void sizeCharactersBitmap(const Font *self, const char *chars, int wrapWidth, const ImageAtlas *icons, int *w, int *h)
Implements Font::sizeBitmapCharacters.
bool initBitmap(FontBitmap *bitmap, Font *font)
Bakes FONT_BITMAP_COUNT codepoints of font, from FONT_BITMAP_FIRST, into a glyph sheet,...
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 * _defaultMonospaceFont
static String * nameWithAttributes(const FontAttributes *attributes)
static Font * fontWithName(const char *name, float pixelDensity)
static Font * defaultMonospaceFont(void)
static bool isEqual(const Object *self, const Object *other)
static void normalizeAttributes(FontAttributes *attributes)
Normalizes Font attributes to their defaults, in one place, so that Font::nameWithAttributes and Font...
static void dealloc(Object *self)
static Font * fontWithAttributes(const FontAttributes *attributes, float pixelDensity)
static Dictionary * _cache
const EnumName FontStyleNames[]
static void initialize(Class *clazz)
static void cacheFont(Data *data, const char *family)
static Font * initWithData(Font *self, Data *data, const FontAttributes *attributes, float pixelDensity)
static String * name(const Font *self)
static Font * _defaultFont
static int hash(const Object *self)
static Font * defaultFont(void)
#define DEFAULT_MONOSPACE_FONT_FAMILY
#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,...)
static const char * iconPlaceholder(const Font *font)
The placeholder an icon occupies in font's layout: a codepoint that is not a line-break opportunity,...
static Font * font(Theme *self, const FontAttributes *attributes, float pixelDensity)
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
The family, size and style attributes that identify a Font, independent of the pixel density at which...
const char * family
The family, or NULL for the default.
int style
The FontStyle, or -1 for the default.
int size
The point size, or 0 for the default.
float pixelDensity
The display pixel density scale, greater than 1.0 on high-density displays.
Font * defaultMonospaceFont(void)
int renderSize
The render size, adjusted for pixel density.
char * family
The family name.
Font * initWithData(Font *self, Data *data, const FontAttributes *attributes, float pixelDensity)
Initializes this Font with the given TTF Data and attributes.
FontBitmap bitmap
The glyphs of a fixed-width Font, baked into one sheet; bitmap.surface is NULL for a proportional Fon...
Font * fontWithName(const char *name, float pixelDensity)
Resolves a Font from a name in the format produced by Font::name.
Font * fontWithAttributes(const FontAttributes *attributes, float pixelDensity)
Resolves a new Font with the given attributes from the cached font Data.
TTF_Font * font
The backing font.
String * name(const Font *self)
Data * data
The raw font data.