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

@ -37,16 +37,16 @@
typedef struct d3d9x_font_desc
{
INT Height;
UINT Width;
UINT Weight;
UINT MipLevels;
BOOL Italic;
BYTE CharSet;
BYTE OutputPrecision;
BYTE Quality;
BYTE PitchAndFamily;
CHAR FaceName[32];
INT Height;
UINT Width;
UINT Weight;
UINT MipLevels;
BOOL Italic;
BYTE CharSet;
BYTE OutputPrecision;
BYTE Quality;
BYTE PitchAndFamily;
CHAR FaceName[32];
} d3d9x_font_desc_t;
typedef struct
@ -57,42 +57,28 @@ typedef struct
uint32_t ascent;
} 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,
const char *font_path, float font_size,
bool is_threaded)
{
TEXTMETRICA metrics;
d3d9x_font_desc_t desc;
d3dfonts_t *d3dfonts = (d3dfonts_t*)calloc(1, sizeof(*d3dfonts));
uint32_t new_font_size = 0;
ID3DXFont *font = NULL;
d3dfonts_t *d3dfonts = (d3dfonts_t*)calloc(1, sizeof(*d3dfonts));
if (!d3dfonts)
return NULL;
desc.Height = (int)font_size;
desc.Width = 0;
desc.Weight = 400;
desc.MipLevels = 0;
desc.Italic = FALSE;
desc.CharSet = DEFAULT_CHARSET;
desc.OutputPrecision = OUT_TT_PRECIS;
desc.Quality = CLIP_DEFAULT_PRECIS;
desc.PitchAndFamily = DEFAULT_PITCH;
desc.Height = (int)font_size;
desc.Width = 0;
desc.Weight = 400;
desc.MipLevels = 0;
desc.Italic = FALSE;
desc.CharSet = DEFAULT_CHARSET;
desc.OutputPrecision = OUT_TT_PRECIS;
desc.Quality = CLIP_DEFAULT_PRECIS;
desc.PitchAndFamily = DEFAULT_PITCH;
/* TODO/FIXME - don't hardcode this font */
#ifdef UNICODE
strlcpy(desc.FaceName, T(L"Verdana"), sizeof(desc.FaceName));
@ -100,18 +86,21 @@ static void *d3d9x_win32_font_init(void *video_data,
strlcpy(desc.FaceName, (const char*)_T("Verdana"), sizeof(desc.FaceName));
#endif
d3dfonts->font_size = font_size * 1.2; /* To match the other font drivers */
d3dfonts->d3d = (d3d9_video_t*)video_data;
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;
desc.Height = d3dfonts->font_size;
desc.Height = new_font_size;
if (!d3d9x_create_font_indirect(d3dfonts->d3d->dev,
&desc, (void**)&d3dfonts->font))
goto error;
d3d9x_font_get_text_metrics(d3dfonts->font, &metrics);
font = d3dfonts->font;
d3dfonts->ascent = metrics.tmAscent;
font->lpVtbl->GetTextMetrics(font, &metrics);
d3dfonts->ascent = metrics.tmAscent;
return d3dfonts;
@ -122,13 +111,16 @@ error:
static void d3d9x_win32_font_free(void *data, bool is_threaded)
{
ID3DXFont *font = NULL;
d3dfonts_t *d3dfonts = (d3dfonts_t*)data;
if (!d3dfonts)
return;
if (d3dfonts->font)
d3d9x_font_release((ID3DXFont*)d3dfonts->font);
font = d3dfonts->font;
if (font)
font->lpVtbl->Release(font);
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};
d3dfonts_t *d3dfonts = (d3dfonts_t*)data;
ID3DXFont *font = NULL;
if (!d3dfonts || !msg)
return 0;
d3d9x_font_draw_text(d3dfonts->font, NULL, (void*)msg,
msg_len ? msg_len : -1, &box, DT_CALCRECT, 0);
font = d3dfonts->font;
font->lpVtbl->DrawText(font, NULL,
(void*)msg, msg_len ? (INT)msg_len : -1, &box, DT_CALCRECT, 0);
return box.right - box.left;
}
@ -159,6 +154,7 @@ static void d3d9x_win32_font_render_msg(
RECT rect, rect_shifted;
RECT *p_rect_shifted = NULL;
RECT *p_rect = NULL;
ID3DXFont *font = NULL;
d3dfonts_t *d3dfonts = (d3dfonts_t*)data;
float drop_mod = 0.3f;
float drop_alpha = 1.0f;
@ -168,6 +164,8 @@ static void d3d9x_win32_font_render_msg(
if (!d3dfonts || !msg)
return;
font = d3dfonts->font;
width = d3dfonts->d3d->video_info.width;
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_b = b * drop_mod;
d3d9x_font_draw_text(d3dfonts->font, NULL,
font->lpVtbl->DrawText(font, NULL,
(void*)msg, -1, p_rect_shifted, format,
D3DCOLOR_ARGB(drop_a , drop_r, drop_g, drop_b));
}
d3d9x_font_draw_text(d3dfonts->font, NULL, (void*)msg, -1,
p_rect, format, D3DCOLOR_ARGB(a, r, g, b));
font->lpVtbl->DrawText(font, NULL,
(void*)msg, -1, p_rect, format,
D3DCOLOR_ARGB(a, r, g, b));
}
font_renderer_t d3d9x_win32_font = {

View File

@ -55,8 +55,7 @@ bitmapfont_lut_t *bitmapfont_get_lut(void)
size_t i, j;
/* Initialise font struct */
font = (bitmapfont_lut_t*)calloc(1, sizeof(bitmapfont_lut_t));
if (!font)
if (!(font = (bitmapfont_lut_t*)calloc(1, sizeof(bitmapfont_lut_t))))
goto error;
font->glyph_min = 0;
@ -109,8 +108,8 @@ void bitmapfont_free_lut(bitmapfont_lut_t *font)
if (font->lut)
{
size_t num_glyphs = (font->glyph_max - font->glyph_min) + 1;
size_t i;
size_t num_glyphs = (font->glyph_max - font->glyph_min) + 1;
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)
{
bm_renderer_t *handle = (bm_renderer_t*)data;
if (!handle)
return NULL;
return code < BMP_ATLAS_SIZE ? &handle->glyphs[code] : NULL;
if (handle && (code < BMP_ATLAS_SIZE))
return &handle->glyphs[code];
return NULL;
}
static void char_to_texture(bm_renderer_t *handle, uint8_t letter,
@ -174,26 +173,23 @@ static void char_to_texture(bm_renderer_t *handle, uint8_t letter,
static void *font_renderer_bmp_init(const char *font_path, float font_size)
{
unsigned i;
bm_renderer_t *handle = (bm_renderer_t*)calloc(1, sizeof(*handle));
bm_renderer_t *handle = (bm_renderer_t*)calloc(1, sizeof(*handle));
if (!handle)
return NULL;
(void)font_path;
handle->scale_factor = (unsigned)roundf(font_size / FONT_HEIGHT);
if (!handle->scale_factor)
if (!(handle->scale_factor = (unsigned)roundf(font_size / FONT_HEIGHT)))
handle->scale_factor = 1;
handle->atlas.width = (BMP_ATLAS_PADDING + (FONT_WIDTH * handle->scale_factor)) * BMP_ATLAS_COLS;
handle->atlas.height = (BMP_ATLAS_PADDING + (FONT_HEIGHT * handle->scale_factor)) * BMP_ATLAS_ROWS;
handle->atlas.buffer = (uint8_t*)calloc(handle->atlas.width * handle->atlas.height, 1);
handle->atlas.width = (BMP_ATLAS_PADDING + (FONT_WIDTH * handle->scale_factor)) * BMP_ATLAS_COLS;
handle->atlas.height = (BMP_ATLAS_PADDING + (FONT_HEIGHT * handle->scale_factor)) * BMP_ATLAS_ROWS;
handle->atlas.buffer = (uint8_t*)calloc(handle->atlas.width * handle->atlas.height, 1);
for (i = 0; i < BMP_ATLAS_SIZE; i++)
{
unsigned x = (i % BMP_ATLAS_COLS) *
unsigned x = (i % BMP_ATLAS_COLS) *
(BMP_ATLAS_PADDING + (handle->scale_factor * FONT_WIDTH));
unsigned y = (i / BMP_ATLAS_COLS) *
unsigned y = (i / BMP_ATLAS_COLS) *
(BMP_ATLAS_PADDING + (handle->scale_factor * FONT_HEIGHT));
char_to_texture(handle, i, x, y);

View File

@ -41,10 +41,10 @@
typedef struct coretext_atlas_slot
{
struct font_glyph glyph;
unsigned charcode;
unsigned last_used;
struct coretext_atlas_slot *next;
struct font_glyph glyph;
unsigned charcode;
unsigned last_used;
struct coretext_atlas_slot *next;
} coretext_atlas_slot_t;
typedef struct coretext_renderer
@ -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)
{
int max_width, max_height;
unsigned i;
size_t bytesPerRow;
CGGlyph glyphs[CT_ATLAS_SIZE];
@ -101,6 +100,8 @@ static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer
CFDictionaryRef attr;
CFTypeRef values[1];
CFStringRef keys[1];
int max_height = 0;
int max_width = 0;
void *bitmapData = NULL;
bool ret = true;
size_t bitsPerComponent = 8;
@ -130,39 +131,36 @@ static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer
#endif
glyphs, advances, CT_ATLAS_SIZE);
ascent = CTFontGetAscent(face);
ascent = CTFontGetAscent(face);
descent = CTFontGetDescent(face);
max_width = 0;
max_height = 0;
for (i = 0; i < CT_ATLAS_SIZE; i++)
{
int origin_x, origin_y;
struct font_glyph *glyph = &handle->atlas_slots[i].glyph;
struct font_glyph *glyph = &handle->atlas_slots[i].glyph;
if (!glyph)
continue;
origin_x = ceil(bounds[i].origin.x);
origin_y = ceil(bounds[i].origin.y);
origin_x = ceil(bounds[i].origin.x);
origin_y = ceil(bounds[i].origin.y);
glyph->draw_offset_x = 0;
glyph->draw_offset_y = -ascent;
glyph->width = ceil(bounds[i].size.width);
glyph->height = ceil(bounds[i].size.height);
glyph->advance_x = ceil(advances[i].width);
glyph->advance_y = ceil(advances[i].height);
glyph->draw_offset_x = 0;
glyph->draw_offset_y = -ascent;
glyph->width = ceil(bounds[i].size.width);
glyph->height = ceil(bounds[i].size.height);
glyph->advance_x = ceil(advances[i].width);
glyph->advance_y = ceil(advances[i].height);
max_width = MAX(max_width, (origin_x + glyph->width));
max_height = MAX(max_height, (origin_y + glyph->height));
max_width = MAX(max_width, (origin_x + glyph->width));
max_height = MAX(max_height, (origin_y + glyph->height));
}
max_height = MAX(max_height, ceil(ascent+descent));
handle->atlas.width = max_width * CT_ATLAS_COLS;
handle->atlas.height = max_height * CT_ATLAS_ROWS;
max_height = MAX(max_height, ceil(ascent+descent));
handle->atlas.width = max_width * CT_ATLAS_COLS;
handle->atlas.height = max_height * CT_ATLAS_ROWS;
handle->line_metrics.ascender = (float)CTFontGetAscent(face);
handle->line_metrics.descender = (float)CTFontGetDescent(face);
/* CTFontGetDescent() should return a positive value,
@ -176,15 +174,16 @@ static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer
handle->line_metrics.ascender + handle->line_metrics.descender +
(float)CTFontGetLeading(face);
handle->atlas.buffer = (uint8_t*)
calloc(handle->atlas.width * handle->atlas.height, 1);
handle->atlas.buffer = (uint8_t*)calloc(
handle->atlas.width * handle->atlas.height, 1);
if (!handle->atlas.buffer)
return false;
bytesPerRow = max_width;
bitmapData = calloc(max_height, bytesPerRow);
offscreen = CGBitmapContextCreate(bitmapData, max_width, max_height,
bytesPerRow = max_width;
bitmapData = calloc(max_height, bytesPerRow);
offscreen = CGBitmapContextCreate(
bitmapData, max_width, max_height,
bitsPerComponent, bytesPerRow, NULL, kCGImageAlphaOnly);
CGContextSetTextMatrix(offscreen, CGAffineTransformIdentity);
@ -195,60 +194,60 @@ static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer
for (i = 0; i < CT_ATLAS_SIZE; i++)
{
unsigned offset_x, offset_y, r, c;
char glyph_cstr[2];
const uint8_t *src;
uint8_t *dst;
unsigned offset_x, offset_y, r, c;
CTLineRef line;
CFStringRef glyph_cfstr;
CFAttributedStringRef attrString;
CTLineRef line;
struct font_glyph *glyph = &handle->atlas_slots[i].glyph;
if (!glyph)
continue;
glyph->width = max_width;
glyph->height = max_height;
glyph->width = max_width;
glyph->height = max_height;
offset_x = (i % CT_ATLAS_COLS) * max_width;
offset_y = (i / CT_ATLAS_COLS) * max_height;
offset_x = (i % CT_ATLAS_COLS) * max_width;
offset_y = (i / CT_ATLAS_COLS) * max_height;
glyph->atlas_offset_x = offset_x;
glyph->atlas_offset_y = offset_y;
glyph->atlas_offset_x = offset_x;
glyph->atlas_offset_y = offset_y;
glyph_cstr[0] = i;
glyph_cstr[1] = 0;
glyph_cfstr = CFStringCreateWithCString(
NULL, glyph_cstr, kCFStringEncodingASCII );
attrString =
CFAttributedStringCreate(NULL, glyph_cfstr, attr);
glyph_cstr[0] = i;
glyph_cstr[1] = 0;
glyph_cfstr = CFStringCreateWithCString(
NULL, glyph_cstr, kCFStringEncodingASCII);
attrString = CFAttributedStringCreate(
NULL, glyph_cfstr, attr);
CFRelease(glyph_cfstr);
glyph_cfstr = NULL;
line = CTLineCreateWithAttributedString(attrString);
glyph_cfstr = NULL;
line = CTLineCreateWithAttributedString(
attrString);
CFRelease(attrString);
attrString = NULL;
attrString = NULL;
memset( bitmapData, 0, max_height * bytesPerRow );
memset(bitmapData, 0, max_height * bytesPerRow);
CGContextSetTextPosition(offscreen, 0, descent);
CTLineDraw(line, offscreen);
CGContextFlush( offscreen );
CGContextFlush(offscreen);
CFRelease( line );
CFRelease(line);
line = NULL;
dst = (uint8_t*)handle->atlas.buffer;
src = (const uint8_t*)bitmapData;
dst = (uint8_t*)handle->atlas.buffer;
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++)
{
unsigned src_idx = (unsigned)(r * bytesPerRow + c);
unsigned src_idx = (unsigned)(r * bytesPerRow + c);
unsigned dest_idx =
(r + offset_y) * (CT_ATLAS_COLS * max_width) + (c + offset_x);
uint8_t v = src[src_idx];
dst[dest_idx] = v;
uint8_t v = src[src_idx];
dst[dest_idx] = v;
}
}
}
@ -256,7 +255,7 @@ static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer
CFRelease(attr);
CGContextRelease(offscreen);
attr = NULL;
attr = NULL;
offscreen = NULL;
free(bitmapData);
@ -271,7 +270,7 @@ static void *font_renderer_ct_init(const char *font_path, float font_size)
CFURLRef url = NULL;
CGDataProviderRef dataProvider = NULL;
CGFontRef theCGFont = NULL;
ct_font_renderer_t *handle = (ct_font_renderer_t*)
ct_font_renderer_t *handle = (ct_font_renderer_t*)
calloc(1, sizeof(*handle));
if (!handle || !path_is_valid(font_path))
@ -280,10 +279,8 @@ static void *font_renderer_ct_init(const char *font_path, float font_size)
goto error;
}
cf_font_path = CFStringCreateWithCString(
NULL, font_path, kCFStringEncodingASCII);
if (!cf_font_path)
if (!(cf_font_path = CFStringCreateWithCString(
NULL, font_path, kCFStringEncodingASCII)))
{
err = 1;
goto error;
@ -319,21 +316,25 @@ error:
CFRelease(cf_font_path);
cf_font_path = NULL;
}
if (face)
{
CFRelease(face);
face = NULL;
}
if (url)
{
CFRelease(url);
url = NULL;
}
if (dataProvider)
{
CFRelease(dataProvider);
dataProvider = NULL;
}
if (theCGFont)
{
CFRelease(theCGFont);
@ -343,14 +344,12 @@ error:
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)
{
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(

View File

@ -157,10 +157,10 @@ static const struct font_glyph *font_renderer_ft_get_glyph(
FT_Render_Glyph(handle->face->glyph, FT_RENDER_MODE_NORMAL);
slot = handle->face->glyph;
atlas_slot = font_renderer_get_slot(handle);
atlas_slot->charcode = charcode;
atlas_slot->next = handle->uc_map[map_id];
handle->uc_map[map_id] = atlas_slot;
atlas_slot = font_renderer_get_slot(handle);
atlas_slot->charcode = charcode;
atlas_slot->next = handle->uc_map[map_id];
handle->uc_map[map_id] = atlas_slot;
/* Some glyphs can be blank. */
atlas_slot->glyph.width = slot->bitmap.width;
@ -216,14 +216,15 @@ static bool font_renderer_create_atlas(ft_font_renderer_t *handle, float font_si
unsigned i, x, y;
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_height = round((handle->face->bbox.yMax - handle->face->bbox.yMin) * font_size / handle->face->units_per_EM);
unsigned max_width = round((handle->face->bbox.xMax - handle->face->bbox.xMin)
* 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_height = (max_height + FT_ATLAS_PADDING) * FT_ATLAS_ROWS;
uint8_t *atlas_buffer = (uint8_t*)
calloc(atlas_width * atlas_height, 1);
uint8_t *atlas_buffer = (uint8_t*)calloc(atlas_width * atlas_height, 1);
if (!atlas_buffer)
return false;

View File

@ -66,7 +66,7 @@ static bool font_renderer_stb_create_atlas(stb_font_renderer_t *self,
uint8_t *font_data, float font_size, unsigned width, unsigned height)
{
int i;
stbtt_packedchar chardata[256];
stbtt_packedchar chardata[256];
stbtt_pack_context pc = {NULL};
if (width > 2048 || height > 2048)
@ -128,11 +128,11 @@ static bool font_renderer_stb_create_atlas(stb_font_renderer_t *self,
return true;
error:
self->atlas.width = self->atlas.height = 0;
if (self->atlas.buffer)
free(self->atlas.buffer);
self->atlas.width = 0;
self->atlas.height = 0;
self->atlas.buffer = NULL;
return false;
@ -140,17 +140,17 @@ error:
static void *font_renderer_stb_init(const char *font_path, float font_size)
{
int ascent, descent, line_gap;
float scale_factor;
stbtt_fontinfo info;
uint8_t *font_data = NULL;
int ascent, descent, line_gap;
uint8_t *font_data = NULL;
stb_font_renderer_t *self = (stb_font_renderer_t*) calloc(1, sizeof(*self));
/* See https://github.com/nothings/stb/blob/master/stb_truetype.h#L539 */
font_size = STBTT_POINT_SIZE(font_size);
if (!self)
goto error;
return NULL;
if (!path_is_valid(font_path) || !filestream_read_file(font_path, (void**)&font_data, NULL))
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);
scale_factor = (font_size < 0) ?
stbtt_ScaleForMappingEmToPixels(&info, -font_size) :
stbtt_ScaleForPixelHeight(&info, font_size);
scale_factor = (font_size < 0)
? stbtt_ScaleForMappingEmToPixels(&info, -font_size)
: stbtt_ScaleForPixelHeight(&info, font_size);
/* Ascender, descender and line_gap values always
* 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 */
unsigned charcode;
unsigned last_used;
}stb_unicode_atlas_slot_t;
} stb_unicode_atlas_slot_t;
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;
stbtt_GetGlyphHMetrics(&self->info, glyph_index, &advance_width, &left_side_bearing);
if (stbtt_GetGlyphBox(&self->info, glyph_index, &x0, NULL, NULL, &y1))
{
stbtt_MakeGlyphBitmap(&self->info, dst, self->max_glyph_width, self->max_glyph_height,
self->atlas.width, self->scale_factor, self->scale_factor, glyph_index);
}
else
{
/* This means the glyph is empty. In this case, stbtt_MakeGlyphBitmap()
@ -168,24 +167,29 @@ static const struct font_glyph *font_renderer_stb_unicode_get_glyph(
atlas_slot->glyph.width = self->max_glyph_width;
atlas_slot->glyph.height = self->max_glyph_height;
/* advance_x must always be rounded to the
* *nearest* integer */
glyph_advance_x = (float)advance_width * self->scale_factor;
atlas_slot->glyph.advance_x = (int)((glyph_advance_x > 0.0f) ?
(glyph_advance_x + 0.5f) : (glyph_advance_x - 0.5f));
glyph_advance_x = (float)advance_width * self->scale_factor;
atlas_slot->glyph.advance_x = (int)((glyph_advance_x > 0.0f)
? (glyph_advance_x + 0.5f)
: (glyph_advance_x - 0.5f));
/* advance_y is always zero */
atlas_slot->glyph.advance_y = 0;
/* draw_offset_x must always be rounded *down*
* to the nearest integer */
atlas_slot->glyph.draw_offset_x = (int)((float)x0 * self->scale_factor);
/* draw_offset_y must always be rounded *up*
* to the nearest integer */
glyph_draw_offset_y = (float)(-y1) * self->scale_factor;
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));
glyph_draw_offset_y = (float)(-y1) * self->scale_factor;
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));
self->atlas.dirty = true;
atlas_slot->last_used = self->usage_counter++;
self->atlas.dirty = true;
atlas_slot->last_used = self->usage_counter++;
return &atlas_slot->glyph;
}
@ -194,15 +198,16 @@ static bool font_renderer_stb_unicode_create_atlas(
{
unsigned i, x, y;
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_height = font_size < 0 ? -font_size : font_size;
self->max_glyph_width = max_glyph_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.height = (self->max_glyph_height + STB_UNICODE_ATLAS_PADDING) * STB_UNICODE_ATLAS_ROWS;
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.buffer = (uint8_t*)
calloc(self->atlas.width * self->atlas.height, sizeof(uint8_t));
self->atlas.buffer = (uint8_t*)calloc(
self->atlas.width * self->atlas.height, sizeof(uint8_t));
if (!self->atlas.buffer)
return false;