ObjectivelyMVC
Object oriented MVC framework for SDL3 and GNU C
Loading...
Searching...
No Matches
Font+Bitmap.h File Reference

Fixed-width Fonts baked into a glyph sheet, drawn as one quad per glyph. More...

Go to the source code of this file.

Data Structures

struct  FontBitmap
 A fixed-width Font's glyphs, baked into one sheet, drawn as one quad per glyph. More...
 

Macros

#define FONT_BITMAP_COLUMNS   32
 The number of cells per row of the glyph sheet: FONT_BITMAP_COUNT cells make a square grid of this many columns and rows.
 
#define FONT_BITMAP_COUNT   1024
 The codepoint count Font bakes into its bitmap.
 
#define FONT_BITMAP_FIRST   ' '
 The first codepoint Font bakes into its bitmap.
 
#define FONT_BITMAP_LAST   (FONT_BITMAP_FIRST + FONT_BITMAP_COUNT)
 One past the last baked codepoint in a Font bitmap (exclusive upper bound).
 
#define FONT_BITMAP_REPLACEMENT   '?'
 The codepoint drawn in place of one outside the baked range.
 

Functions

OBJECTIVELYMVC_EXPORT void deallocBitmap (FontBitmap *bitmap)
 Releases the resources held by bitmap. Safe to call on a zeroed FontBitmap.
 
OBJECTIVELYMVC_EXPORT bool initBitmap (FontBitmap *bitmap, Font *font)
 Bakes FONT_BITMAP_COUNT codepoints of font, from FONT_BITMAP_FIRST, into a glyph sheet, initializing bitmap.
 
OBJECTIVELYMVC_EXPORT 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.
 
OBJECTIVELYMVC_EXPORT void renderDeviceWillResetBitmap (Font *self)
 Implements Font::renderDeviceWillReset.
 
OBJECTIVELYMVC_EXPORT void sizeCharactersBitmap (const Font *self, const char *chars, int wrapWidth, const ImageAtlas *icons, int *w, int *h)
 Implements Font::sizeBitmapCharacters.
 

Detailed Description

Fixed-width Fonts baked into a glyph sheet, drawn as one quad per glyph.

Definition in file Font+Bitmap.h.

Macro Definition Documentation

◆ FONT_BITMAP_COLUMNS

#define FONT_BITMAP_COLUMNS   32

The number of cells per row of the glyph sheet: FONT_BITMAP_COUNT cells make a square grid of this many columns and rows.

Definition at line 50 of file Font+Bitmap.h.

◆ FONT_BITMAP_COUNT

#define FONT_BITMAP_COUNT   1024

The codepoint count Font bakes into its bitmap.

Covers Basic Latin, Latin-1 Supplement, Latin Extended-A/B, and Greek and Coptic (U+0020-U+041F) – generous enough for any Latin- or Greek-script text without configuration. Individual codepoints a Font lacks a glyph for are simply skipped, not rejected, so this is safe to bake against any fixed-width face regardless of its actual coverage.

Definition at line 40 of file Font+Bitmap.h.

◆ FONT_BITMAP_FIRST

#define FONT_BITMAP_FIRST   ' '

The first codepoint Font bakes into its bitmap.

Definition at line 31 of file Font+Bitmap.h.

◆ FONT_BITMAP_LAST

#define FONT_BITMAP_LAST   (FONT_BITMAP_FIRST + FONT_BITMAP_COUNT)

One past the last baked codepoint in a Font bitmap (exclusive upper bound).

Definition at line 45 of file Font+Bitmap.h.

◆ FONT_BITMAP_REPLACEMENT

#define FONT_BITMAP_REPLACEMENT   '?'

The codepoint drawn in place of one outside the baked range.

Definition at line 55 of file Font+Bitmap.h.

Function Documentation

◆ deallocBitmap()

OBJECTIVELYMVC_EXPORT void deallocBitmap ( FontBitmap *  bitmap)

Releases the resources held by bitmap. Safe to call on a zeroed FontBitmap.

Parameters
bitmapThe FontBitmap.

Definition at line 375 of file Font+Bitmap.c.

375 {
376
377 assert(bitmap);
378
379 release(bitmap->texture);
380
381 if (bitmap->surface) {
382 SDL_DestroySurface(bitmap->surface);
383 }
384}
SDL_Surface * surface
The glyph sheet: a grid of FONT_BITMAP_COLUMNS by FONT_BITMAP_COLUMNS cells of cellSize,...

◆ initBitmap()

OBJECTIVELYMVC_EXPORT bool initBitmap ( FontBitmap *  bitmap,
Font *  font 
)

Bakes FONT_BITMAP_COUNT codepoints of font, from FONT_BITMAP_FIRST, into a glyph sheet, initializing bitmap.

A codepoint outside the range draws FONT_BITMAP_REPLACEMENT instead.

Parameters
bitmapThe FontBitmap, zero-initialized.
fontThe Font, which MUST be fixed-width.
Returns
True if the bitmap was baked, false if font is not fixed-width or has no glyphs in the range, in which case bitmap is left zeroed.

Definition at line 322 of file Font+Bitmap.c.

322 {
323
324 assert(bitmap);
325 assert(font);
326
327 if (!TTF_FontIsFixedWidth(font->font)) {
328 String *name = $(font, name);
329 MVC_LogWarn("%s is not fixed-width\n", name->chars);
330 release(name);
331 return false;
332 }
333
334 int minX = INT_MAX, maxX = INT_MIN, advance = 0;
335
336 for (Uint32 codepoint = FONT_BITMAP_FIRST; codepoint < FONT_BITMAP_LAST; codepoint++) {
337
338 if (TTF_FontHasGlyph(font->font, codepoint)) {
339 int glyphMinX = 0, glyphMaxX = 0, glyphAdvance = 0;
340 if (!TTF_GetGlyphMetrics(font->font, codepoint, &glyphMinX, &glyphMaxX, NULL, NULL, &glyphAdvance)) {
341 continue;
342 }
343
344 minX = min(minX, glyphMinX);
345 maxX = max(maxX, max(glyphMaxX, glyphAdvance));
346 advance = max(advance, glyphAdvance);
347 }
348 }
349
350 if (maxX <= minX || advance == 0) {
351 String *name = $(font, name);
352 MVC_LogWarn("%s has no glyphs in U+%04X-U+%04X\n", name->chars, FONT_BITMAP_FIRST, FONT_BITMAP_LAST - 1);
353 release(name);
354 return false;
355 }
356
357 bitmap->advance = advance;
358 bitmap->bearing = minX;
359 bitmap->cellSize = MakeSize(maxX - minX, TTF_GetFontHeight(font->font));
360
361 const int rows = FONT_BITMAP_COUNT / FONT_BITMAP_COLUMNS;
362
363 bitmap->surface = SDL_CreateSurface(FONT_BITMAP_COLUMNS * bitmap->cellSize.w, rows * bitmap->cellSize.h, SDL_PIXELFORMAT_RGBA32);
364 assert(bitmap->surface);
365
366 SDL_FillSurfaceRect(bitmap->surface, NULL, 0);
367
368 for (Uint32 i = 0; i < FONT_BITMAP_COUNT; i++) {
369 initGlyph(bitmap, font->font, FONT_BITMAP_FIRST + i, i);
370 }
371
372 return true;
373}
static void initGlyph(const FontBitmap *bitmap, TTF_Font *font, Uint32 codepoint, Uint32 cell)
Rasterizes codepoint into the given cell, with its bearing baked in.
Definition Font+Bitmap.c:64
#define FONT_BITMAP_COUNT
The codepoint count Font bakes into its bitmap.
Definition Font+Bitmap.h:40
#define FONT_BITMAP_FIRST
The first codepoint Font bakes into its bitmap.
Definition Font+Bitmap.h:31
#define FONT_BITMAP_LAST
One past the last baked codepoint in a Font bitmap (exclusive upper bound).
Definition Font+Bitmap.h:45
#define FONT_BITMAP_COLUMNS
The number of cells per row of the glyph sheet: FONT_BITMAP_COUNT cells make a square grid of this ma...
Definition Font+Bitmap.h:50
static String * name(const Font *self)
Definition Font.c:303
#define MVC_LogWarn(fmt,...)
Definition Log.h:54
static Font * font(Theme *self, const FontAttributes *attributes, float pixelDensity)
Definition Theme.c:108
int bearing
The horizontal offset from the pen to a cell's left edge, in texels.
Definition Font+Bitmap.h:92
SDL_Size cellSize
The size of one cell, in texels.
Definition Font+Bitmap.h:97
int advance
The pen advance per glyph, in texels.
Definition Font+Bitmap.h:86
TTF_Font * font
The backing font.
Definition Font.h:122

◆ renderCharactersBitmap()

OBJECTIVELYMVC_EXPORT 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.

Definition at line 452 of file Font+Bitmap.c.

452 {
453
454 assert(self);
455 assert(renderer);
456 assert(origin);
457
458 FontBitmap *bitmap = &self->bitmap;
459 assert(bitmap->surface);
460
461 if (chars == NULL) {
462 return;
463 }
464
465 if (bitmap->texture == NULL) {
466 bitmap->texture = $(renderer->device, createTextureFromSurface, bitmap->surface, SDL_GPU_TEXTUREUSAGE_SAMPLER, false);
467 assert(bitmap->texture);
468 }
469
470 RenderContext context = {
471 .renderer = renderer,
472 .device = renderer->device,
473 .texture = bitmap->texture,
474 .origin = { roundf(origin->x * self->pixelDensity), roundf(origin->y * self->pixelDensity) },
475 .scale = self->pixelDensity,
476 };
477
478 walk(bitmap, chars, (int) (wrapWidth * context.scale), color, icons, renderToken, &context, NULL, NULL);
479}
static void renderToken(const FontBitmap *bitmap, const Token *token, int x, int y, ident data)
TokenVisitor for Font::renderBitmapCharacters.
static void walk(const FontBitmap *bitmap, const char *chars, int wrapWidth, SDL_Color color, const ImageAtlas *icons, TokenVisitor visitor, ident data, int *w, int *h)
Walks chars, wrapping at word boundaries when wrapWidth (in texels) is non-zero, and reports the exte...
static ImageAtlas * icons(Theme *self)
Definition Theme.c:144
A fixed-width Font's glyphs, baked into one sheet, drawn as one quad per glyph.
Definition Font+Bitmap.h:82
float pixelDensity
The display pixel density scale, greater than 1.0 on high-density displays.
Definition Font.h:134
FontBitmap bitmap
The glyphs of a fixed-width Font, baked into one sheet; bitmap.surface is NULL for a proportional Fon...
Definition Font.h:107
const Renderer * renderer
RenderDevice * device
The backing RenderDevice.
Definition Renderer.h:97

◆ renderDeviceWillResetBitmap()

OBJECTIVELYMVC_EXPORT void renderDeviceWillResetBitmap ( Font *  self)

Implements Font::renderDeviceWillReset.

Definition at line 390 of file Font+Bitmap.c.

390 {
391
392 assert(self);
393
394 self->bitmap.texture = release(self->bitmap.texture);
395}

◆ sizeCharactersBitmap()

OBJECTIVELYMVC_EXPORT void sizeCharactersBitmap ( const Font *  self,
const char *  chars,
int  wrapWidth,
const ImageAtlas *  icons,
int *  w,
int *  h 
)

Implements Font::sizeBitmapCharacters.

Definition at line 485 of file Font+Bitmap.c.

485 {
486
487 assert(self);
488
489 const FontBitmap *bitmap = &self->bitmap;
490 assert(bitmap->surface);
491
492 int texelsW = 0, texelsH = 0;
493
494 if (chars) {
495 walk(bitmap, chars, (int) (wrapWidth * self->pixelDensity), Colors.White, icons, NULL, NULL, &texelsW, &texelsH);
496 }
497
498 if (w) {
499 *w = (int) ceilf(texelsW / self->pixelDensity);
500 }
501 if (h) {
502 *h = (int) ceilf(texelsH / self->pixelDensity);
503 }
504}
W3C Color constants.
Definition Colors.h:37
SDL_Color White
Definition Colors.h:185