Cleanups for font drivers

This commit is contained in:
libretroadmin 2023-06-15 12:36:44 +02:00
parent 1fc5c600a4
commit ae3ac72356
6 changed files with 167 additions and 167 deletions

View File

@ -57,29 +57,14 @@ typedef struct
uint32_t ascent; uint32_t ascent;
} d3dfonts_t; } d3dfonts_t;
static void d3d9x_font_release(ID3DXFont *font)
{
font->lpVtbl->Release(font);
}
static void d3d9x_font_get_text_metrics(ID3DXFont *font, TEXTMETRICA *metrics)
{
font->lpVtbl->GetTextMetrics(font, metrics);
}
static void d3d9x_font_draw_text(ID3DXFont *font, LPD3DXSPRITE sprite_data, LPCTSTR string_data,
unsigned count, LPRECT rect_data, DWORD format, D3DCOLOR color)
{
font->lpVtbl->DrawText(font, sprite_data,
string_data, count, rect_data, format, color);
}
static void *d3d9x_win32_font_init(void *video_data, static void *d3d9x_win32_font_init(void *video_data,
const char *font_path, float font_size, const char *font_path, float font_size,
bool is_threaded) bool is_threaded)
{ {
TEXTMETRICA metrics; TEXTMETRICA metrics;
d3d9x_font_desc_t desc; d3d9x_font_desc_t desc;
uint32_t new_font_size = 0;
ID3DXFont *font = NULL;
d3dfonts_t *d3dfonts = (d3dfonts_t*)calloc(1, sizeof(*d3dfonts)); d3dfonts_t *d3dfonts = (d3dfonts_t*)calloc(1, sizeof(*d3dfonts));
if (!d3dfonts) if (!d3dfonts)
return NULL; return NULL;
@ -93,6 +78,7 @@ static void *d3d9x_win32_font_init(void *video_data,
desc.OutputPrecision = OUT_TT_PRECIS; desc.OutputPrecision = OUT_TT_PRECIS;
desc.Quality = CLIP_DEFAULT_PRECIS; desc.Quality = CLIP_DEFAULT_PRECIS;
desc.PitchAndFamily = DEFAULT_PITCH; desc.PitchAndFamily = DEFAULT_PITCH;
/* TODO/FIXME - don't hardcode this font */ /* TODO/FIXME - don't hardcode this font */
#ifdef UNICODE #ifdef UNICODE
strlcpy(desc.FaceName, T(L"Verdana"), sizeof(desc.FaceName)); strlcpy(desc.FaceName, T(L"Verdana"), sizeof(desc.FaceName));
@ -100,16 +86,19 @@ static void *d3d9x_win32_font_init(void *video_data,
strlcpy(desc.FaceName, (const char*)_T("Verdana"), sizeof(desc.FaceName)); strlcpy(desc.FaceName, (const char*)_T("Verdana"), sizeof(desc.FaceName));
#endif #endif
d3dfonts->font_size = font_size * 1.2; /* To match the other font drivers */ new_font_size = font_size * 1.2; /* To match the other font drivers */
d3dfonts->font_size = new_font_size;
d3dfonts->d3d = (d3d9_video_t*)video_data; d3dfonts->d3d = (d3d9_video_t*)video_data;
desc.Height = d3dfonts->font_size; desc.Height = new_font_size;
if (!d3d9x_create_font_indirect(d3dfonts->d3d->dev, if (!d3d9x_create_font_indirect(d3dfonts->d3d->dev,
&desc, (void**)&d3dfonts->font)) &desc, (void**)&d3dfonts->font))
goto error; goto error;
d3d9x_font_get_text_metrics(d3dfonts->font, &metrics); font = d3dfonts->font;
font->lpVtbl->GetTextMetrics(font, &metrics);
d3dfonts->ascent = metrics.tmAscent; d3dfonts->ascent = metrics.tmAscent;
@ -122,13 +111,16 @@ error:
static void d3d9x_win32_font_free(void *data, bool is_threaded) static void d3d9x_win32_font_free(void *data, bool is_threaded)
{ {
ID3DXFont *font = NULL;
d3dfonts_t *d3dfonts = (d3dfonts_t*)data; d3dfonts_t *d3dfonts = (d3dfonts_t*)data;
if (!d3dfonts) if (!d3dfonts)
return; return;
if (d3dfonts->font) font = d3dfonts->font;
d3d9x_font_release((ID3DXFont*)d3dfonts->font);
if (font)
font->lpVtbl->Release(font);
free(d3dfonts); free(d3dfonts);
} }
@ -138,12 +130,15 @@ static int d3d9x_win32_font_get_message_width(void* data, const char* msg,
{ {
RECT box = {0,0,0,0}; RECT box = {0,0,0,0};
d3dfonts_t *d3dfonts = (d3dfonts_t*)data; d3dfonts_t *d3dfonts = (d3dfonts_t*)data;
ID3DXFont *font = NULL;
if (!d3dfonts || !msg) if (!d3dfonts || !msg)
return 0; return 0;
d3d9x_font_draw_text(d3dfonts->font, NULL, (void*)msg, font = d3dfonts->font;
msg_len ? msg_len : -1, &box, DT_CALCRECT, 0);
font->lpVtbl->DrawText(font, NULL,
(void*)msg, msg_len ? (INT)msg_len : -1, &box, DT_CALCRECT, 0);
return box.right - box.left; return box.right - box.left;
} }
@ -159,6 +154,7 @@ static void d3d9x_win32_font_render_msg(
RECT rect, rect_shifted; RECT rect, rect_shifted;
RECT *p_rect_shifted = NULL; RECT *p_rect_shifted = NULL;
RECT *p_rect = NULL; RECT *p_rect = NULL;
ID3DXFont *font = NULL;
d3dfonts_t *d3dfonts = (d3dfonts_t*)data; d3dfonts_t *d3dfonts = (d3dfonts_t*)data;
float drop_mod = 0.3f; float drop_mod = 0.3f;
float drop_alpha = 1.0f; float drop_alpha = 1.0f;
@ -168,6 +164,8 @@ static void d3d9x_win32_font_render_msg(
if (!d3dfonts || !msg) if (!d3dfonts || !msg)
return; return;
font = d3dfonts->font;
width = d3dfonts->d3d->video_info.width; width = d3dfonts->d3d->video_info.width;
height = d3dfonts->d3d->video_info.height; height = d3dfonts->d3d->video_info.height;
@ -242,13 +240,14 @@ static void d3d9x_win32_font_render_msg(
unsigned drop_g = g * drop_mod; unsigned drop_g = g * drop_mod;
unsigned drop_b = b * drop_mod; unsigned drop_b = b * drop_mod;
d3d9x_font_draw_text(d3dfonts->font, NULL, font->lpVtbl->DrawText(font, NULL,
(void*)msg, -1, p_rect_shifted, format, (void*)msg, -1, p_rect_shifted, format,
D3DCOLOR_ARGB(drop_a , drop_r, drop_g, drop_b)); D3DCOLOR_ARGB(drop_a , drop_r, drop_g, drop_b));
} }
d3d9x_font_draw_text(d3dfonts->font, NULL, (void*)msg, -1, font->lpVtbl->DrawText(font, NULL,
p_rect, format, D3DCOLOR_ARGB(a, r, g, b)); (void*)msg, -1, p_rect, format,
D3DCOLOR_ARGB(a, r, g, b));
} }
font_renderer_t d3d9x_win32_font = { font_renderer_t d3d9x_win32_font = {

View File

@ -55,8 +55,7 @@ bitmapfont_lut_t *bitmapfont_get_lut(void)
size_t i, j; size_t i, j;
/* Initialise font struct */ /* Initialise font struct */
font = (bitmapfont_lut_t*)calloc(1, sizeof(bitmapfont_lut_t)); if (!(font = (bitmapfont_lut_t*)calloc(1, sizeof(bitmapfont_lut_t))))
if (!font)
goto error; goto error;
font->glyph_min = 0; font->glyph_min = 0;
@ -109,8 +108,8 @@ void bitmapfont_free_lut(bitmapfont_lut_t *font)
if (font->lut) if (font->lut)
{ {
size_t num_glyphs = (font->glyph_max - font->glyph_min) + 1;
size_t i; size_t i;
size_t num_glyphs = (font->glyph_max - font->glyph_min) + 1;
for (i = 0; i < num_glyphs; i++) for (i = 0; i < num_glyphs; i++)
{ {
@ -137,9 +136,9 @@ static const struct font_glyph *font_renderer_bmp_get_glyph(
void *data, uint32_t code) void *data, uint32_t code)
{ {
bm_renderer_t *handle = (bm_renderer_t*)data; bm_renderer_t *handle = (bm_renderer_t*)data;
if (!handle) if (handle && (code < BMP_ATLAS_SIZE))
return &handle->glyphs[code];
return NULL; return NULL;
return code < BMP_ATLAS_SIZE ? &handle->glyphs[code] : NULL;
} }
static void char_to_texture(bm_renderer_t *handle, uint8_t letter, static void char_to_texture(bm_renderer_t *handle, uint8_t letter,
@ -179,10 +178,7 @@ static void *font_renderer_bmp_init(const char *font_path, float font_size)
if (!handle) if (!handle)
return NULL; return NULL;
(void)font_path; if (!(handle->scale_factor = (unsigned)roundf(font_size / FONT_HEIGHT)))
handle->scale_factor = (unsigned)roundf(font_size / FONT_HEIGHT);
if (!handle->scale_factor)
handle->scale_factor = 1; handle->scale_factor = 1;
handle->atlas.width = (BMP_ATLAS_PADDING + (FONT_WIDTH * handle->scale_factor)) * BMP_ATLAS_COLS; handle->atlas.width = (BMP_ATLAS_PADDING + (FONT_WIDTH * handle->scale_factor)) * BMP_ATLAS_COLS;

View File

@ -90,7 +90,6 @@ static void font_renderer_ct_free(void *data)
static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer_t *handle) static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer_t *handle)
{ {
int max_width, max_height;
unsigned i; unsigned i;
size_t bytesPerRow; size_t bytesPerRow;
CGGlyph glyphs[CT_ATLAS_SIZE]; CGGlyph glyphs[CT_ATLAS_SIZE];
@ -101,6 +100,8 @@ static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer
CFDictionaryRef attr; CFDictionaryRef attr;
CFTypeRef values[1]; CFTypeRef values[1];
CFStringRef keys[1]; CFStringRef keys[1];
int max_height = 0;
int max_width = 0;
void *bitmapData = NULL; void *bitmapData = NULL;
bool ret = true; bool ret = true;
size_t bitsPerComponent = 8; size_t bitsPerComponent = 8;
@ -133,9 +134,6 @@ static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer
ascent = CTFontGetAscent(face); ascent = CTFontGetAscent(face);
descent = CTFontGetDescent(face); descent = CTFontGetDescent(face);
max_width = 0;
max_height = 0;
for (i = 0; i < CT_ATLAS_SIZE; i++) for (i = 0; i < CT_ATLAS_SIZE; i++)
{ {
int origin_x, origin_y; int origin_x, origin_y;
@ -176,15 +174,16 @@ static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer
handle->line_metrics.ascender + handle->line_metrics.descender + handle->line_metrics.ascender + handle->line_metrics.descender +
(float)CTFontGetLeading(face); (float)CTFontGetLeading(face);
handle->atlas.buffer = (uint8_t*) handle->atlas.buffer = (uint8_t*)calloc(
calloc(handle->atlas.width * handle->atlas.height, 1); handle->atlas.width * handle->atlas.height, 1);
if (!handle->atlas.buffer) if (!handle->atlas.buffer)
return false; return false;
bytesPerRow = max_width; bytesPerRow = max_width;
bitmapData = calloc(max_height, bytesPerRow); bitmapData = calloc(max_height, bytesPerRow);
offscreen = CGBitmapContextCreate(bitmapData, max_width, max_height, offscreen = CGBitmapContextCreate(
bitmapData, max_width, max_height,
bitsPerComponent, bytesPerRow, NULL, kCGImageAlphaOnly); bitsPerComponent, bytesPerRow, NULL, kCGImageAlphaOnly);
CGContextSetTextMatrix(offscreen, CGAffineTransformIdentity); CGContextSetTextMatrix(offscreen, CGAffineTransformIdentity);
@ -195,13 +194,13 @@ static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer
for (i = 0; i < CT_ATLAS_SIZE; i++) for (i = 0; i < CT_ATLAS_SIZE; i++)
{ {
unsigned offset_x, offset_y, r, c;
char glyph_cstr[2]; char glyph_cstr[2];
const uint8_t *src; const uint8_t *src;
uint8_t *dst; uint8_t *dst;
unsigned offset_x, offset_y, r, c; CTLineRef line;
CFStringRef glyph_cfstr; CFStringRef glyph_cfstr;
CFAttributedStringRef attrString; CFAttributedStringRef attrString;
CTLineRef line;
struct font_glyph *glyph = &handle->atlas_slots[i].glyph; struct font_glyph *glyph = &handle->atlas_slots[i].glyph;
if (!glyph) if (!glyph)
@ -219,27 +218,28 @@ static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer
glyph_cstr[0] = i; glyph_cstr[0] = i;
glyph_cstr[1] = 0; glyph_cstr[1] = 0;
glyph_cfstr = CFStringCreateWithCString( glyph_cfstr = CFStringCreateWithCString(
NULL, glyph_cstr, kCFStringEncodingASCII ); NULL, glyph_cstr, kCFStringEncodingASCII);
attrString = attrString = CFAttributedStringCreate(
CFAttributedStringCreate(NULL, glyph_cfstr, attr); NULL, glyph_cfstr, attr);
CFRelease(glyph_cfstr); CFRelease(glyph_cfstr);
glyph_cfstr = NULL; glyph_cfstr = NULL;
line = CTLineCreateWithAttributedString(attrString); line = CTLineCreateWithAttributedString(
attrString);
CFRelease(attrString); CFRelease(attrString);
attrString = NULL; attrString = NULL;
memset( bitmapData, 0, max_height * bytesPerRow ); memset(bitmapData, 0, max_height * bytesPerRow);
CGContextSetTextPosition(offscreen, 0, descent); CGContextSetTextPosition(offscreen, 0, descent);
CTLineDraw(line, offscreen); CTLineDraw(line, offscreen);
CGContextFlush( offscreen ); CGContextFlush(offscreen);
CFRelease( line ); CFRelease(line);
line = NULL; line = NULL;
dst = (uint8_t*)handle->atlas.buffer; dst = (uint8_t*)handle->atlas.buffer;
src = (const uint8_t*)bitmapData; src = (const uint8_t*)bitmapData;
for (r = 0; r < max_height; r++ ) for (r = 0; r < max_height; r++)
{ {
for (c = 0; c < max_width; c++) for (c = 0; c < max_width; c++)
{ {
@ -247,7 +247,6 @@ static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer
unsigned dest_idx = unsigned dest_idx =
(r + offset_y) * (CT_ATLAS_COLS * max_width) + (c + offset_x); (r + offset_y) * (CT_ATLAS_COLS * max_width) + (c + offset_x);
uint8_t v = src[src_idx]; uint8_t v = src[src_idx];
dst[dest_idx] = v; dst[dest_idx] = v;
} }
} }
@ -280,10 +279,8 @@ static void *font_renderer_ct_init(const char *font_path, float font_size)
goto error; goto error;
} }
cf_font_path = CFStringCreateWithCString( if (!(cf_font_path = CFStringCreateWithCString(
NULL, font_path, kCFStringEncodingASCII); NULL, font_path, kCFStringEncodingASCII)))
if (!cf_font_path)
{ {
err = 1; err = 1;
goto error; goto error;
@ -319,21 +316,25 @@ error:
CFRelease(cf_font_path); CFRelease(cf_font_path);
cf_font_path = NULL; cf_font_path = NULL;
} }
if (face) if (face)
{ {
CFRelease(face); CFRelease(face);
face = NULL; face = NULL;
} }
if (url) if (url)
{ {
CFRelease(url); CFRelease(url);
url = NULL; url = NULL;
} }
if (dataProvider) if (dataProvider)
{ {
CFRelease(dataProvider); CFRelease(dataProvider);
dataProvider = NULL; dataProvider = NULL;
} }
if (theCGFont) if (theCGFont)
{ {
CFRelease(theCGFont); CFRelease(theCGFont);
@ -343,14 +344,12 @@ error:
return handle; return handle;
} }
/* We can't tell if a font is going to be there until we actually
initialize CoreText and the best way to get fonts is by name, not
by path. */
static const char *default_font = "Verdana";
static const char *font_renderer_ct_get_default_font(void) static const char *font_renderer_ct_get_default_font(void)
{ {
return default_font; /* We can't tell if a font is going to be there until we actually
initialize CoreText and the best way to get fonts is by name, not
by path. */
return "Verdana";
} }
static void font_renderer_ct_get_line_metrics( static void font_renderer_ct_get_line_metrics(

View File

@ -216,14 +216,15 @@ static bool font_renderer_create_atlas(ft_font_renderer_t *handle, float font_si
unsigned i, x, y; unsigned i, x, y;
freetype_atlas_slot_t* slot = NULL; freetype_atlas_slot_t* slot = NULL;
unsigned max_width = round((handle->face->bbox.xMax - handle->face->bbox.xMin) * font_size / handle->face->units_per_EM); unsigned max_width = round((handle->face->bbox.xMax - handle->face->bbox.xMin)
unsigned max_height = round((handle->face->bbox.yMax - handle->face->bbox.yMin) * font_size / handle->face->units_per_EM); * font_size / handle->face->units_per_EM);
unsigned max_height = round((handle->face->bbox.yMax - handle->face->bbox.yMin)
* font_size / handle->face->units_per_EM);
unsigned atlas_width = (max_width + FT_ATLAS_PADDING) * FT_ATLAS_COLS; unsigned atlas_width = (max_width + FT_ATLAS_PADDING) * FT_ATLAS_COLS;
unsigned atlas_height = (max_height + FT_ATLAS_PADDING) * FT_ATLAS_ROWS; unsigned atlas_height = (max_height + FT_ATLAS_PADDING) * FT_ATLAS_ROWS;
uint8_t *atlas_buffer = (uint8_t*) uint8_t *atlas_buffer = (uint8_t*)calloc(atlas_width * atlas_height, 1);
calloc(atlas_width * atlas_height, 1);
if (!atlas_buffer) if (!atlas_buffer)
return false; return false;

View File

@ -128,11 +128,11 @@ static bool font_renderer_stb_create_atlas(stb_font_renderer_t *self,
return true; return true;
error: error:
self->atlas.width = self->atlas.height = 0;
if (self->atlas.buffer) if (self->atlas.buffer)
free(self->atlas.buffer); free(self->atlas.buffer);
self->atlas.width = 0;
self->atlas.height = 0;
self->atlas.buffer = NULL; self->atlas.buffer = NULL;
return false; return false;
@ -140,9 +140,9 @@ error:
static void *font_renderer_stb_init(const char *font_path, float font_size) static void *font_renderer_stb_init(const char *font_path, float font_size)
{ {
int ascent, descent, line_gap;
float scale_factor; float scale_factor;
stbtt_fontinfo info; stbtt_fontinfo info;
int ascent, descent, line_gap;
uint8_t *font_data = NULL; uint8_t *font_data = NULL;
stb_font_renderer_t *self = (stb_font_renderer_t*) calloc(1, sizeof(*self)); stb_font_renderer_t *self = (stb_font_renderer_t*) calloc(1, sizeof(*self));
@ -150,7 +150,7 @@ static void *font_renderer_stb_init(const char *font_path, float font_size)
font_size = STBTT_POINT_SIZE(font_size); font_size = STBTT_POINT_SIZE(font_size);
if (!self) if (!self)
goto error; return NULL;
if (!path_is_valid(font_path) || !filestream_read_file(font_path, (void**)&font_data, NULL)) if (!path_is_valid(font_path) || !filestream_read_file(font_path, (void**)&font_data, NULL))
goto error; goto error;
@ -163,9 +163,9 @@ static void *font_renderer_stb_init(const char *font_path, float font_size)
stbtt_GetFontVMetrics(&info, &ascent, &descent, &line_gap); stbtt_GetFontVMetrics(&info, &ascent, &descent, &line_gap);
scale_factor = (font_size < 0) ? scale_factor = (font_size < 0)
stbtt_ScaleForMappingEmToPixels(&info, -font_size) : ? stbtt_ScaleForMappingEmToPixels(&info, -font_size)
stbtt_ScaleForPixelHeight(&info, font_size); : stbtt_ScaleForPixelHeight(&info, font_size);
/* Ascender, descender and line_gap values always /* Ascender, descender and line_gap values always
* end up ~0.5 pixels too small when scaled... * end up ~0.5 pixels too small when scaled...

View File

@ -52,7 +52,7 @@ typedef struct stb_unicode_atlas_slot
struct font_glyph glyph; /* unsigned alignment */ struct font_glyph glyph; /* unsigned alignment */
unsigned charcode; unsigned charcode;
unsigned last_used; unsigned last_used;
}stb_unicode_atlas_slot_t; } stb_unicode_atlas_slot_t;
typedef struct typedef struct
{ {
@ -150,11 +150,10 @@ static const struct font_glyph *font_renderer_stb_unicode_get_glyph(
+ atlas_slot->glyph.atlas_offset_y * self->atlas.width; + atlas_slot->glyph.atlas_offset_y * self->atlas.width;
stbtt_GetGlyphHMetrics(&self->info, glyph_index, &advance_width, &left_side_bearing); stbtt_GetGlyphHMetrics(&self->info, glyph_index, &advance_width, &left_side_bearing);
if (stbtt_GetGlyphBox(&self->info, glyph_index, &x0, NULL, NULL, &y1)) if (stbtt_GetGlyphBox(&self->info, glyph_index, &x0, NULL, NULL, &y1))
{
stbtt_MakeGlyphBitmap(&self->info, dst, self->max_glyph_width, self->max_glyph_height, stbtt_MakeGlyphBitmap(&self->info, dst, self->max_glyph_width, self->max_glyph_height,
self->atlas.width, self->scale_factor, self->scale_factor, glyph_index); self->atlas.width, self->scale_factor, self->scale_factor, glyph_index);
}
else else
{ {
/* This means the glyph is empty. In this case, stbtt_MakeGlyphBitmap() /* This means the glyph is empty. In this case, stbtt_MakeGlyphBitmap()
@ -168,21 +167,26 @@ static const struct font_glyph *font_renderer_stb_unicode_get_glyph(
atlas_slot->glyph.width = self->max_glyph_width; atlas_slot->glyph.width = self->max_glyph_width;
atlas_slot->glyph.height = self->max_glyph_height; atlas_slot->glyph.height = self->max_glyph_height;
/* advance_x must always be rounded to the /* advance_x must always be rounded to the
* *nearest* integer */ * *nearest* integer */
glyph_advance_x = (float)advance_width * self->scale_factor; glyph_advance_x = (float)advance_width * self->scale_factor;
atlas_slot->glyph.advance_x = (int)((glyph_advance_x > 0.0f) ? atlas_slot->glyph.advance_x = (int)((glyph_advance_x > 0.0f)
(glyph_advance_x + 0.5f) : (glyph_advance_x - 0.5f)); ? (glyph_advance_x + 0.5f)
: (glyph_advance_x - 0.5f));
/* advance_y is always zero */ /* advance_y is always zero */
atlas_slot->glyph.advance_y = 0; atlas_slot->glyph.advance_y = 0;
/* draw_offset_x must always be rounded *down* /* draw_offset_x must always be rounded *down*
* to the nearest integer */ * to the nearest integer */
atlas_slot->glyph.draw_offset_x = (int)((float)x0 * self->scale_factor); atlas_slot->glyph.draw_offset_x = (int)((float)x0 * self->scale_factor);
/* draw_offset_y must always be rounded *up* /* draw_offset_y must always be rounded *up*
* to the nearest integer */ * to the nearest integer */
glyph_draw_offset_y = (float)(-y1) * self->scale_factor; glyph_draw_offset_y = (float)(-y1) * self->scale_factor;
atlas_slot->glyph.draw_offset_y = (int)((glyph_draw_offset_y < 0.0f) ? atlas_slot->glyph.draw_offset_y = (int)((glyph_draw_offset_y < 0.0f)
floor((double)glyph_draw_offset_y) : ceil((double)glyph_draw_offset_y)); ? floor((double)glyph_draw_offset_y)
: ceil((double)glyph_draw_offset_y));
self->atlas.dirty = true; self->atlas.dirty = true;
atlas_slot->last_used = self->usage_counter++; atlas_slot->last_used = self->usage_counter++;
@ -194,15 +198,16 @@ static bool font_renderer_stb_unicode_create_atlas(
{ {
unsigned i, x, y; unsigned i, x, y;
stb_unicode_atlas_slot_t* slot = NULL; stb_unicode_atlas_slot_t* slot = NULL;
int max_glyph_size = (font_size < 0) ? -font_size : font_size;
self->max_glyph_width = font_size < 0 ? -font_size : font_size; self->max_glyph_width = max_glyph_size;
self->max_glyph_height = font_size < 0 ? -font_size : font_size; self->max_glyph_height = max_glyph_size;
self->atlas.width = (self->max_glyph_width + STB_UNICODE_ATLAS_PADDING) * STB_UNICODE_ATLAS_COLS; self->atlas.width = (self->max_glyph_width + STB_UNICODE_ATLAS_PADDING) * STB_UNICODE_ATLAS_COLS;
self->atlas.height = (self->max_glyph_height + STB_UNICODE_ATLAS_PADDING) * STB_UNICODE_ATLAS_ROWS; self->atlas.height = (self->max_glyph_height + STB_UNICODE_ATLAS_PADDING) * STB_UNICODE_ATLAS_ROWS;
self->atlas.buffer = (uint8_t*) self->atlas.buffer = (uint8_t*)calloc(
calloc(self->atlas.width * self->atlas.height, sizeof(uint8_t)); self->atlas.width * self->atlas.height, sizeof(uint8_t));
if (!self->atlas.buffer) if (!self->atlas.buffer)
return false; return false;