mirror of
https://github.com/libretro/RetroArch
synced 2025-01-29 18:32:44 +00:00
Cleanups for font drivers
This commit is contained in:
parent
1fc5c600a4
commit
ae3ac72356
@ -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 = {
|
||||
|
@ -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);
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
|
@ -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...
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user