mirror of
https://github.com/libretro/RetroArch
synced 2025-03-28 08:37:41 +00:00
(Fonts) Cleanups; declare variables at top of functions
This commit is contained in:
parent
5f26bbcfb9
commit
0ac6fee02a
@ -35,6 +35,8 @@ typedef struct bm_renderer
|
||||
static const struct font_atlas *font_renderer_bmp_get_atlas(void *data)
|
||||
{
|
||||
bm_renderer_t *handle = (bm_renderer_t*)data;
|
||||
if (!handle)
|
||||
return NULL;
|
||||
return &handle->atlas;
|
||||
}
|
||||
|
||||
@ -42,6 +44,8 @@ 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 < ATLAS_SIZE ? &handle->glyphs[code] : NULL;
|
||||
}
|
||||
|
||||
@ -57,11 +61,11 @@ static void char_to_texture(bm_renderer_t *handle, uint8_t letter,
|
||||
for (x = 0; x < FONT_WIDTH; x++)
|
||||
{
|
||||
unsigned font_pixel = x + y * FONT_WIDTH;
|
||||
uint8_t rem = 1 << (font_pixel & 7);
|
||||
unsigned offset = font_pixel >> 3;
|
||||
uint8_t col = (bitmap_bin[FONT_OFFSET(letter) + offset] & rem) ? 0xff : 0;
|
||||
uint8_t rem = 1 << (font_pixel & 7);
|
||||
unsigned offset = font_pixel >> 3;
|
||||
uint8_t col = (bitmap_bin[FONT_OFFSET(letter) + offset] & rem) ? 0xff : 0;
|
||||
uint8_t *dst = target;
|
||||
|
||||
uint8_t *dst = target;
|
||||
dst += x * handle->scale_factor;
|
||||
dst += y * handle->scale_factor * handle->atlas.width;
|
||||
|
||||
@ -74,13 +78,14 @@ 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)
|
||||
{
|
||||
(void)font_path;
|
||||
unsigned i;
|
||||
|
||||
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)
|
||||
handle->scale_factor = 1;
|
||||
@ -93,6 +98,7 @@ static void *font_renderer_bmp_init(const char *font_path, float font_size)
|
||||
{
|
||||
unsigned x = (i % ATLAS_COLS) * handle->scale_factor * FONT_WIDTH;
|
||||
unsigned y = (i / ATLAS_COLS) * handle->scale_factor * FONT_HEIGHT;
|
||||
|
||||
char_to_texture(handle, i, x, y);
|
||||
|
||||
handle->glyphs[i].width = FONT_WIDTH * handle->scale_factor;
|
||||
|
@ -40,19 +40,27 @@ typedef struct coretext_renderer
|
||||
static const struct font_atlas *font_renderer_ct_get_atlas(void *data)
|
||||
{
|
||||
font_renderer_t *handle = (font_renderer_t*)data;
|
||||
if (!handle)
|
||||
return NULL;
|
||||
return &handle->atlas;
|
||||
}
|
||||
|
||||
static const struct font_glyph *font_renderer_ct_get_glyph(void *data, uint32_t code)
|
||||
{
|
||||
font_renderer_t *handle = (font_renderer_t*)data;
|
||||
struct font_glyph *result = code < CT_ATLAS_SIZE ? &handle->glyphs[code] : NULL;
|
||||
return result;
|
||||
struct font_glyph *result = NULL;
|
||||
font_renderer_t *handle = (font_renderer_t*)data;
|
||||
|
||||
if (!handle)
|
||||
return NULL;
|
||||
if (code >= CT_ATLAS_SIZE)
|
||||
return NULL;
|
||||
return &handle->glyphs[code];
|
||||
}
|
||||
|
||||
static void font_renderer_ct_free(void *data)
|
||||
{
|
||||
font_renderer_t *handle = (font_renderer_t*)data;
|
||||
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
@ -62,170 +70,218 @@ static void font_renderer_ct_free(void *data)
|
||||
|
||||
static bool font_renderer_create_atlas(CTFontRef face, font_renderer_t *handle)
|
||||
{
|
||||
unsigned i;
|
||||
bool ret = true;
|
||||
int max_width, max_height;
|
||||
unsigned i;
|
||||
size_t bytesPerRow;
|
||||
CGGlyph glyphs[CT_ATLAS_SIZE];
|
||||
CGRect bounds[CT_ATLAS_SIZE];
|
||||
CGSize advances[CT_ATLAS_SIZE];
|
||||
CGFloat ascent, descent;
|
||||
CGContextRef offscreen;
|
||||
CFStringRef keys[] = { kCTFontAttributeName };
|
||||
CFDictionaryRef attr;
|
||||
void *bitmapData = NULL;
|
||||
bool ret = true;
|
||||
size_t bitsPerComponent = 8;
|
||||
UniChar characters[CT_ATLAS_SIZE] = {0};
|
||||
CFTypeRef values[] = { face };
|
||||
|
||||
UniChar characters[CT_ATLAS_SIZE] = {0};
|
||||
for (i = 0; i < CT_ATLAS_SIZE; i++) {
|
||||
characters[i] = (UniChar)i;
|
||||
}
|
||||
for (i = 0; i < CT_ATLAS_SIZE; i++)
|
||||
characters[i] = (UniChar)i;
|
||||
|
||||
CGGlyph glyphs[CT_ATLAS_SIZE];
|
||||
CTFontGetGlyphsForCharacters(face, characters, glyphs, CT_ATLAS_SIZE);
|
||||
CTFontGetGlyphsForCharacters(face, characters, glyphs, CT_ATLAS_SIZE);
|
||||
|
||||
CGRect bounds[CT_ATLAS_SIZE];
|
||||
CTFontGetBoundingRectsForGlyphs(face, kCTFontDefaultOrientation,
|
||||
glyphs, bounds, CT_ATLAS_SIZE);
|
||||
CTFontGetBoundingRectsForGlyphs(face, kCTFontDefaultOrientation,
|
||||
glyphs, bounds, CT_ATLAS_SIZE);
|
||||
|
||||
CGSize advances[CT_ATLAS_SIZE];
|
||||
CTFontGetAdvancesForGlyphs(face, kCTFontDefaultOrientation,
|
||||
glyphs, advances, CT_ATLAS_SIZE);
|
||||
CTFontGetAdvancesForGlyphs(face, kCTFontDefaultOrientation,
|
||||
glyphs, advances, CT_ATLAS_SIZE);
|
||||
|
||||
CGFloat ascent = CTFontGetAscent( face );
|
||||
CGFloat descent = CTFontGetDescent( face );
|
||||
ascent = CTFontGetAscent(face);
|
||||
descent = CTFontGetDescent(face);
|
||||
|
||||
int max_width = 0;
|
||||
int max_height = 0;
|
||||
for (i = 0; i < CT_ATLAS_SIZE; i++) {
|
||||
struct font_glyph *glyph = &handle->glyphs[i];
|
||||
int origin_x = ceil(bounds[i].origin.x);
|
||||
int origin_y = ceil(bounds[i].origin.y);
|
||||
max_width = 0;
|
||||
max_height = 0;
|
||||
|
||||
glyph->draw_offset_x = 0;
|
||||
glyph->draw_offset_y = -1 * (ascent - descent);
|
||||
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);
|
||||
for (i = 0; i < CT_ATLAS_SIZE; i++)
|
||||
{
|
||||
int origin_x, origin_y;
|
||||
struct font_glyph *glyph = &handle->glyphs[i];
|
||||
|
||||
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));
|
||||
if (!glyph)
|
||||
continue;
|
||||
|
||||
handle->atlas.width = max_width * CT_ATLAS_COLS;
|
||||
handle->atlas.height = max_height * CT_ATLAS_ROWS;
|
||||
origin_x = ceil(bounds[i].origin.x);
|
||||
origin_y = ceil(bounds[i].origin.y);
|
||||
|
||||
handle->atlas.buffer = (uint8_t*)
|
||||
calloc(handle->atlas.width * handle->atlas.height, 1);
|
||||
glyph->draw_offset_x = 0;
|
||||
glyph->draw_offset_y = -1 * (ascent - descent);
|
||||
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);
|
||||
|
||||
if (!handle->atlas.buffer) {
|
||||
ret = false;
|
||||
goto end;
|
||||
}
|
||||
max_width = max(max_width, (origin_x + glyph->width));
|
||||
max_height = max(max_height, (origin_y + glyph->height));
|
||||
}
|
||||
|
||||
size_t bitsPerComponent = 8;
|
||||
size_t bytesPerRow = max_width;
|
||||
void *bitmapData = calloc(max_height, bytesPerRow);
|
||||
CGContextRef offscreen =
|
||||
CGBitmapContextCreate(bitmapData, max_width, max_height,
|
||||
bitsPerComponent, bytesPerRow, NULL, kCGImageAlphaOnly);
|
||||
CGContextSetTextMatrix(offscreen, CGAffineTransformIdentity);
|
||||
max_height = max(max_height, ceil(ascent+descent));
|
||||
|
||||
CFStringRef keys[] = { kCTFontAttributeName };
|
||||
CFTypeRef values[] = { face };
|
||||
CFDictionaryRef attr =
|
||||
CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values,
|
||||
sizeof(keys) / sizeof(keys[0]),
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
|
||||
for (i = 0; i < CT_ATLAS_SIZE; i++) {
|
||||
struct font_glyph *glyph = &handle->glyphs[i];
|
||||
handle->atlas.width = max_width * CT_ATLAS_COLS;
|
||||
handle->atlas.height = max_height * CT_ATLAS_ROWS;
|
||||
|
||||
glyph->width = max_width;
|
||||
glyph->height = max_height;
|
||||
handle->atlas.buffer = (uint8_t*)
|
||||
calloc(handle->atlas.width * handle->atlas.height, 1);
|
||||
|
||||
unsigned offset_x = (i % CT_ATLAS_COLS) * max_width;
|
||||
unsigned offset_y = (i / CT_ATLAS_COLS) * max_height;
|
||||
if (!handle->atlas.buffer)
|
||||
{
|
||||
ret = false;
|
||||
goto end;
|
||||
}
|
||||
|
||||
glyph->atlas_offset_x = offset_x;
|
||||
glyph->atlas_offset_y = offset_y;
|
||||
bytesPerRow = max_width;
|
||||
bitmapData = calloc(max_height, bytesPerRow);
|
||||
offscreen = CGBitmapContextCreate(bitmapData, max_width, max_height,
|
||||
bitsPerComponent, bytesPerRow, NULL, kCGImageAlphaOnly);
|
||||
|
||||
char glyph_cstr[2];
|
||||
glyph_cstr[0] = i;
|
||||
glyph_cstr[1] = 0;
|
||||
CFStringRef glyph_cfstr =
|
||||
CFStringCreateWithCString( NULL, glyph_cstr, kCFStringEncodingASCII );
|
||||
CFAttributedStringRef attrString =
|
||||
CFAttributedStringCreate(NULL, glyph_cfstr, attr);
|
||||
CFRelease(glyph_cfstr), glyph_cfstr = NULL;
|
||||
CTLineRef line = CTLineCreateWithAttributedString(attrString);
|
||||
CFRelease(attrString), attrString = NULL;
|
||||
CGContextSetTextMatrix(offscreen, CGAffineTransformIdentity);
|
||||
|
||||
memset( bitmapData, 0, max_height * bytesPerRow );
|
||||
CGContextSetTextPosition(offscreen, 0, descent);
|
||||
CTLineDraw(line, offscreen);
|
||||
CGContextFlush( offscreen );
|
||||
attr = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values,
|
||||
sizeof(keys) / sizeof(keys[0]), &kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
|
||||
CFRelease( line ), line = NULL;
|
||||
for (i = 0; i < CT_ATLAS_SIZE; i++)
|
||||
{
|
||||
char glyph_cstr[2];
|
||||
const uint8_t *src;
|
||||
uint8_t *dst;
|
||||
unsigned offset_x, offset_y, r, c;
|
||||
CFStringRef glyph_cfstr;
|
||||
CFAttributedStringRef attrString;
|
||||
CTLineRef line;
|
||||
struct font_glyph *glyph = &handle->glyphs[i];
|
||||
|
||||
if (!glyph)
|
||||
continue;
|
||||
|
||||
uint8_t *dst = (uint8_t*)handle->atlas.buffer;
|
||||
glyph->width = max_width;
|
||||
glyph->height = max_height;
|
||||
|
||||
const uint8_t *src = (const uint8_t*)bitmapData;
|
||||
for (unsigned r = 0; r < max_height; r++ ) {
|
||||
for (unsigned c = 0; c < max_width; c++) {
|
||||
unsigned src_idx = 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;
|
||||
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_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);
|
||||
CFRelease(attrString);
|
||||
attrString = NULL;
|
||||
|
||||
memset( bitmapData, 0, max_height * bytesPerRow );
|
||||
CGContextSetTextPosition(offscreen, 0, descent);
|
||||
CTLineDraw(line, offscreen);
|
||||
CGContextFlush( offscreen );
|
||||
|
||||
CFRelease( line );
|
||||
line = NULL;
|
||||
|
||||
dst = (uint8_t*)handle->atlas.buffer;
|
||||
src = (const uint8_t*)bitmapData;
|
||||
|
||||
for (r = 0; r < max_height; r++ )
|
||||
{
|
||||
for (c = 0; c < max_width; c++)
|
||||
{
|
||||
unsigned src_idx = 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(attr), attr = NULL;
|
||||
CGContextRelease(offscreen), offscreen = NULL;
|
||||
free(bitmapData);
|
||||
CFRelease(attr);
|
||||
CGContextRelease(offscreen);
|
||||
|
||||
end:
|
||||
return ret;
|
||||
attr = NULL;
|
||||
offscreen = NULL;
|
||||
free(bitmapData);
|
||||
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *font_renderer_ct_init(const char *font_path, float font_size)
|
||||
{
|
||||
char err = 0;
|
||||
CFStringRef cf_font_path = NULL;
|
||||
CTFontRef face = NULL;
|
||||
char err = 0;
|
||||
CFStringRef cf_font_path = NULL;
|
||||
CTFontRef face = NULL;
|
||||
font_renderer_t *handle = (font_renderer_t*)
|
||||
calloc(1, sizeof(*handle));
|
||||
|
||||
font_renderer_t *handle = (font_renderer_t*)
|
||||
calloc(1, sizeof(*handle));
|
||||
if (!handle)
|
||||
{
|
||||
err = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!handle) {
|
||||
err = 1; goto error;
|
||||
}
|
||||
cf_font_path = CFStringCreateWithCString(NULL, font_path, kCFStringEncodingASCII);
|
||||
if (!cf_font_path)
|
||||
{
|
||||
err = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
face = CTFontCreateWithName(cf_font_path, font_size, NULL);
|
||||
|
||||
cf_font_path = CFStringCreateWithCString( NULL, font_path, kCFStringEncodingASCII );
|
||||
if ( ! cf_font_path ) {
|
||||
err = 1; goto error;
|
||||
}
|
||||
face = CTFontCreateWithName( cf_font_path, font_size, NULL );
|
||||
if ( ! face ) {
|
||||
err = 1; goto error;
|
||||
}
|
||||
if (! font_renderer_create_atlas(face, handle)) {
|
||||
err = 1; goto error;
|
||||
}
|
||||
if (!face)
|
||||
{
|
||||
err = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
error:
|
||||
if ( err ) {
|
||||
font_renderer_ct_free(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
if (!font_renderer_create_atlas(face, handle))
|
||||
{
|
||||
err = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ( cf_font_path ) {
|
||||
CFRelease( cf_font_path ), cf_font_path = NULL ; }
|
||||
if ( face ) {
|
||||
CFRelease(face), face = NULL; }
|
||||
error:
|
||||
if (err)
|
||||
{
|
||||
font_renderer_ct_free(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
|
||||
return handle;
|
||||
if (cf_font_path)
|
||||
{
|
||||
CFRelease(cf_font_path);
|
||||
cf_font_path = NULL;
|
||||
}
|
||||
if (face)
|
||||
{
|
||||
CFRelease(face);
|
||||
face = NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -31,6 +31,7 @@ const d3d_font_renderer_t *d3d_font_init_first(void *data,
|
||||
const char *font_path, unsigned font_size)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(d3d_font_backends); i++)
|
||||
{
|
||||
if (d3d_font_backends[i]->init(data, font_path, font_size))
|
||||
|
@ -24,8 +24,7 @@ static LPD3DXFONT d3d_font;
|
||||
static bool d3dfonts_w32_init_font(void *data,
|
||||
const char *font_path, unsigned font_size)
|
||||
{
|
||||
(void)font_path;
|
||||
|
||||
uint32_t r, g, b;
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
D3DXFONT_DESC desc = {
|
||||
static_cast<int>(font_size), 0, 400, 0,
|
||||
@ -36,9 +35,12 @@ static bool d3dfonts_w32_init_font(void *data,
|
||||
"Verdana" // Hardcode ftl :(
|
||||
};
|
||||
|
||||
uint32_t r = static_cast<uint32_t>(g_settings.video.msg_color_r * 255) & 0xff;
|
||||
uint32_t g = static_cast<uint32_t>(g_settings.video.msg_color_g * 255) & 0xff;
|
||||
uint32_t b = static_cast<uint32_t>(g_settings.video.msg_color_b * 255) & 0xff;
|
||||
(void)font_path;
|
||||
|
||||
r = static_cast<uint32_t>(g_settings.video.msg_color_r * 255) & 0xff;
|
||||
g = static_cast<uint32_t>(g_settings.video.msg_color_g * 255) & 0xff;
|
||||
b = static_cast<uint32_t>(g_settings.video.msg_color_b * 255) & 0xff;
|
||||
|
||||
d3d->font_color = D3DCOLOR_XRGB(r, g, b);
|
||||
|
||||
return SUCCEEDED(D3DXCreateFontIndirect(d3d->dev, &desc, &d3d_font));
|
||||
@ -47,6 +49,7 @@ static bool d3dfonts_w32_init_font(void *data,
|
||||
static void d3dfonts_w32_deinit_font(void *data)
|
||||
{
|
||||
(void)data;
|
||||
|
||||
if (d3d_font)
|
||||
d3d_font->Release();
|
||||
d3d_font = NULL;
|
||||
@ -57,24 +60,28 @@ static void d3dfonts_w32_render_msg(void *data, const char *msg,
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
if (msg && SUCCEEDED(d3d->dev->BeginScene()))
|
||||
{
|
||||
d3d_font->DrawTextA(NULL,
|
||||
msg,
|
||||
-1,
|
||||
&d3d->font_rect_shifted,
|
||||
DT_LEFT,
|
||||
((d3d->font_color >> 2) & 0x3f3f3f) | 0xff000000);
|
||||
if (!d3d)
|
||||
return;
|
||||
if (!msg)
|
||||
return;
|
||||
if (!(SUCCEEDED(d3d->dev->BeginScene())))
|
||||
return;
|
||||
|
||||
d3d_font->DrawTextA(NULL,
|
||||
msg,
|
||||
-1,
|
||||
&d3d->font_rect,
|
||||
DT_LEFT,
|
||||
d3d->font_color | 0xff000000);
|
||||
d3d_font->DrawTextA(NULL,
|
||||
msg,
|
||||
-1,
|
||||
&d3d->font_rect_shifted,
|
||||
DT_LEFT,
|
||||
((d3d->font_color >> 2) & 0x3f3f3f) | 0xff000000);
|
||||
|
||||
d3d->dev->EndScene();
|
||||
}
|
||||
d3d_font->DrawTextA(NULL,
|
||||
msg,
|
||||
-1,
|
||||
&d3d->font_rect,
|
||||
DT_LEFT,
|
||||
d3d->font_color | 0xff000000);
|
||||
|
||||
d3d->dev->EndScene();
|
||||
}
|
||||
|
||||
d3d_font_renderer_t d3d_win32_font = {
|
||||
|
@ -37,9 +37,11 @@ bool font_renderer_create_default(
|
||||
const char *font_path, unsigned font_size)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; font_backends[i]; i++)
|
||||
{
|
||||
const char *path = font_path;
|
||||
|
||||
if (!path)
|
||||
path = font_backends[i]->get_default_font();
|
||||
if (!path)
|
||||
|
@ -40,6 +40,8 @@ typedef struct freetype_renderer
|
||||
static const struct font_atlas *font_renderer_ft_get_atlas(void *data)
|
||||
{
|
||||
font_renderer_t *handle = (font_renderer_t*)data;
|
||||
if (!handle)
|
||||
return NULL;
|
||||
return &handle->atlas;
|
||||
}
|
||||
|
||||
@ -47,6 +49,8 @@ static const struct font_glyph *font_renderer_ft_get_glyph(
|
||||
void *data, uint32_t code)
|
||||
{
|
||||
font_renderer_t *handle = (font_renderer_t*)data;
|
||||
if (!handle)
|
||||
return NULL;
|
||||
return code < ATLAS_SIZE ? &handle->glyphs[code] : NULL;
|
||||
}
|
||||
|
||||
@ -80,6 +84,9 @@ static bool font_renderer_create_atlas(font_renderer_t *handle)
|
||||
{
|
||||
struct font_glyph *glyph = &handle->glyphs[i];
|
||||
|
||||
if (!glyph)
|
||||
continue;
|
||||
|
||||
if (FT_Load_Char(handle->face, i, FT_LOAD_RENDER))
|
||||
{
|
||||
ret = false;
|
||||
@ -124,7 +131,7 @@ static bool font_renderer_create_atlas(font_renderer_t *handle)
|
||||
for (i = 0; i < ATLAS_SIZE; i++)
|
||||
{
|
||||
unsigned r, c;
|
||||
uint8_t *dst = NULL;
|
||||
uint8_t *dst = NULL;
|
||||
unsigned offset_x = (i % ATLAS_COLS) * max_width;
|
||||
unsigned offset_y = (i / ATLAS_COLS) * max_height;
|
||||
|
||||
@ -137,6 +144,7 @@ static bool font_renderer_create_atlas(font_renderer_t *handle)
|
||||
if (buffer[i])
|
||||
{
|
||||
const uint8_t *src = (const uint8_t*)buffer[i];
|
||||
|
||||
for (r = 0; r < handle->glyphs[i].height;
|
||||
r++, dst += handle->atlas.width, src += pitches[i])
|
||||
for (c = 0; c < handle->glyphs[i].width; c++)
|
||||
@ -208,6 +216,7 @@ static const char *font_paths[] = {
|
||||
static const char *font_renderer_ft_get_default_font(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(font_paths); i++)
|
||||
{
|
||||
if (path_file_exists(font_paths[i]))
|
||||
|
@ -44,7 +44,11 @@ typedef struct
|
||||
static void *gl_raster_font_init_font(void *gl_data,
|
||||
const char *font_path, float font_size)
|
||||
{
|
||||
unsigned width, height;
|
||||
uint8_t *tmp_buffer;
|
||||
const struct font_atlas *atlas = NULL;
|
||||
gl_raster_t *font = (gl_raster_t*)calloc(1, sizeof(*font));
|
||||
|
||||
if (!font)
|
||||
return NULL;
|
||||
|
||||
@ -65,10 +69,10 @@ static void *gl_raster_font_init_font(void *gl_data,
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
const struct font_atlas *atlas = font->font_driver->get_atlas(font->font_data);
|
||||
atlas = font->font_driver->get_atlas(font->font_data);
|
||||
|
||||
unsigned width = next_pow2(atlas->width);
|
||||
unsigned height = next_pow2(atlas->height);
|
||||
width = next_pow2(atlas->width);
|
||||
height = next_pow2(atlas->height);
|
||||
|
||||
/* Ideally, we'd use single component textures, but the
|
||||
* difference in ways to do that between core GL and GLES/legacy GL
|
||||
@ -76,12 +80,14 @@ static void *gl_raster_font_init_font(void *gl_data,
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height,
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
uint8_t *tmp_buffer = (uint8_t*)malloc(atlas->width * atlas->height * 4);
|
||||
tmp_buffer = (uint8_t*)malloc(atlas->width * atlas->height * 4);
|
||||
|
||||
if (tmp_buffer)
|
||||
{
|
||||
unsigned i;
|
||||
uint8_t *dst = tmp_buffer;
|
||||
uint8_t *dst = tmp_buffer;
|
||||
const uint8_t *src = atlas->buffer;
|
||||
|
||||
for (i = 0; i < atlas->width * atlas->height; i++)
|
||||
{
|
||||
*dst++ = 0xff;
|
||||
@ -89,6 +95,7 @@ static void *gl_raster_font_init_font(void *gl_data,
|
||||
*dst++ = 0xff;
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, atlas->width,
|
||||
atlas->height, GL_RGBA, GL_UNSIGNED_BYTE, tmp_buffer);
|
||||
free(tmp_buffer);
|
||||
@ -118,27 +125,28 @@ static void gl_raster_font_free_font(void *data)
|
||||
static void render_message(gl_raster_t *font, const char *msg, GLfloat scale,
|
||||
const GLfloat color[4], GLfloat pos_x, GLfloat pos_y)
|
||||
{
|
||||
unsigned i;
|
||||
int x, y, delta_x, delta_y;
|
||||
float inv_tex_size_x, inv_tex_size_y, inv_win_width, inv_win_height;
|
||||
unsigned i, msg_len_full, msg_len;
|
||||
GLfloat font_tex_coords[2 * 6 * MAX_MSG_LEN_CHUNK];
|
||||
GLfloat font_vertex[2 * 6 * MAX_MSG_LEN_CHUNK];
|
||||
GLfloat font_color[4 * 6 * MAX_MSG_LEN_CHUNK];
|
||||
gl_t *gl = font->gl;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, font->tex);
|
||||
|
||||
GLfloat font_tex_coords[2 * 6 * MAX_MSG_LEN_CHUNK];
|
||||
GLfloat font_vertex[2 * 6 * MAX_MSG_LEN_CHUNK];
|
||||
GLfloat font_color[4 * 6 * MAX_MSG_LEN_CHUNK];
|
||||
msg_len_full = strlen(msg);
|
||||
msg_len = min(msg_len_full, MAX_MSG_LEN_CHUNK);
|
||||
|
||||
unsigned msg_len_full = strlen(msg);
|
||||
unsigned msg_len = min(msg_len_full, MAX_MSG_LEN_CHUNK);
|
||||
x = roundf(pos_x * gl->vp.width);
|
||||
y = roundf(pos_y * gl->vp.height);
|
||||
delta_x = 0;
|
||||
delta_y = 0;
|
||||
|
||||
int x = roundf(pos_x * gl->vp.width);
|
||||
int y = roundf(pos_y * gl->vp.height);
|
||||
int delta_x = 0;
|
||||
int delta_y = 0;
|
||||
|
||||
float inv_tex_size_x = 1.0f / font->tex_width;
|
||||
float inv_tex_size_y = 1.0f / font->tex_height;
|
||||
float inv_win_width = 1.0f / font->gl->vp.width;
|
||||
float inv_win_height = 1.0f / font->gl->vp.height;
|
||||
inv_tex_size_x = 1.0f / font->tex_width;
|
||||
inv_tex_size_y = 1.0f / font->tex_height;
|
||||
inv_win_width = 1.0f / font->gl->vp.width;
|
||||
inv_win_height = 1.0f / font->gl->vp.height;
|
||||
|
||||
while (msg_len_full)
|
||||
{
|
||||
@ -148,19 +156,20 @@ static void render_message(gl_raster_t *font, const char *msg, GLfloat scale,
|
||||
|
||||
for (i = 0; i < msg_len; i++)
|
||||
{
|
||||
const struct font_glyph *gly =
|
||||
int off_x, off_y, tex_x, tex_y, width, height;
|
||||
const struct font_glyph *glyph =
|
||||
font->font_driver->get_glyph(font->font_data, (uint8_t)msg[i]);
|
||||
if (!gly)
|
||||
gly = font->font_driver->get_glyph(font->font_data, '?'); /* Do something smarter here ... */
|
||||
if (!gly)
|
||||
if (!glyph)
|
||||
glyph = font->font_driver->get_glyph(font->font_data, '?'); /* Do something smarter here ... */
|
||||
if (!glyph)
|
||||
continue;
|
||||
|
||||
int off_x = gly->draw_offset_x;
|
||||
int off_y = gly->draw_offset_y;
|
||||
int tex_x = gly->atlas_offset_x;
|
||||
int tex_y = gly->atlas_offset_y;
|
||||
int width = gly->width;
|
||||
int height = gly->height;
|
||||
off_x = glyph->draw_offset_x;
|
||||
off_y = glyph->draw_offset_y;
|
||||
tex_x = glyph->atlas_offset_x;
|
||||
tex_y = glyph->atlas_offset_y;
|
||||
width = glyph->width;
|
||||
height = glyph->height;
|
||||
|
||||
emit(0, 0, 1); /* Bottom-left */
|
||||
emit(1, 1, 1); /* Bottom-right */
|
||||
@ -171,8 +180,8 @@ static void render_message(gl_raster_t *font, const char *msg, GLfloat scale,
|
||||
emit(5, 1, 1); /* Bottom-right */
|
||||
#undef emit
|
||||
|
||||
delta_x += gly->advance_x;
|
||||
delta_y -= gly->advance_y;
|
||||
delta_x += glyph->advance_x;
|
||||
delta_y -= glyph->advance_y;
|
||||
}
|
||||
|
||||
gl->coords.tex_coord = font_tex_coords;
|
||||
@ -203,12 +212,13 @@ static void gl_raster_font_render_msg(void *data, const char *msg,
|
||||
GLfloat color[4], color_dark[4];
|
||||
int drop_x, drop_y;
|
||||
bool full_screen;
|
||||
|
||||
gl_t *gl = NULL;
|
||||
gl_raster_t *font = (gl_raster_t*)data;
|
||||
|
||||
if (!font)
|
||||
return;
|
||||
|
||||
gl_t *gl = font->gl;
|
||||
gl = font->gl;
|
||||
|
||||
if (params)
|
||||
{
|
||||
@ -276,7 +286,6 @@ static const struct font_glyph *gl_raster_font_get_glyph(
|
||||
|
||||
if (!font)
|
||||
return NULL;
|
||||
|
||||
return font->font_driver->get_glyph((void*)font->font_driver, code);
|
||||
}
|
||||
|
||||
|
@ -35,9 +35,10 @@
|
||||
|
||||
static void *libdbg_font_init_font(void *gl_data, const char *font_path, float font_size)
|
||||
{
|
||||
gl_t *gl = (gl_t*)gl_data;
|
||||
|
||||
(void)font_path;
|
||||
(void)font_size;
|
||||
gl_t *gl = (gl_t*)gl_data;
|
||||
|
||||
DbgFontConfig cfg;
|
||||
#if defined(SN_TARGET_PSP2)
|
||||
@ -63,10 +64,11 @@ static void libdbg_font_deinit_font(void *data)
|
||||
static void libdbg_font_render_msg(void *data, const char *msg,
|
||||
const struct font_params *params)
|
||||
{
|
||||
(void)data;
|
||||
float x, y, scale;
|
||||
unsigned color;
|
||||
|
||||
(void)data;
|
||||
|
||||
if (params)
|
||||
{
|
||||
x = params->x;
|
||||
|
@ -47,7 +47,7 @@ static void xfonts_render_msg(void *data, const char *msg,
|
||||
const struct font_params *params)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
wchar_t str[PATH_MAX];
|
||||
wchar_t str[PATH_MAX_LENGTH];
|
||||
float x, y;
|
||||
|
||||
if (params)
|
||||
|
@ -25,25 +25,25 @@
|
||||
|
||||
typedef struct GLYPH_ATTR
|
||||
{
|
||||
unsigned short tu1, tv1, tu2, tv2; // Texture coordinates for the image
|
||||
short wOffset; // Pixel offset for glyph start
|
||||
short wWidth; // Pixel width of the glyph
|
||||
short wAdvance; // Pixels to advance after the glyph
|
||||
unsigned short tu1, tv1, tu2, tv2; /* Texture coordinates for the image. */
|
||||
short wOffset; /* Pixel offset for glyph start. */
|
||||
short wWidth; /* Pixel width of the glyph. */
|
||||
short wAdvance; /* Pixels to advance after the glyph. */
|
||||
unsigned short wMask;
|
||||
} GLYPH_ATTR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned long m_dwSavedState;
|
||||
unsigned long m_cMaxGlyph; // Number of entries in the translator table
|
||||
unsigned long m_dwNumGlyphs; // Number of valid glyphs
|
||||
float m_fFontHeight; // Height of the font strike in pixels
|
||||
float m_fFontTopPadding; // Padding above the strike zone
|
||||
float m_fFontBottomPadding; // Padding below the strike zone
|
||||
float m_fFontYAdvance; // Number of pixels to move the cursor for a line feed
|
||||
wchar_t * m_TranslatorTable; // ASCII to glyph lookup table
|
||||
unsigned long m_cMaxGlyph; /* Number of entries in the translator table. */
|
||||
unsigned long m_dwNumGlyphs; /* Number of valid glyphs. */
|
||||
float m_fFontHeight; /* Height of the font strike in pixels. */
|
||||
float m_fFontTopPadding; /* Padding above the strike zone. */
|
||||
float m_fFontBottomPadding; /* Padding below the strike zone. */
|
||||
float m_fFontYAdvance; /* Number of pixels to move the cursor for a line feed. */
|
||||
wchar_t * m_TranslatorTable; /* ASCII to glyph lookup table. */
|
||||
D3DTexture* m_pFontTexture;
|
||||
const GLYPH_ATTR* m_Glyphs; // Array of glyphs
|
||||
const GLYPH_ATTR* m_Glyphs; /* Array of glyphs. */
|
||||
} xdk360_video_font_t;
|
||||
|
||||
static xdk360_video_font_t m_Font;
|
||||
@ -53,18 +53,18 @@ static PackedResource m_xprResource;
|
||||
#define FONTFILEVERSION 5
|
||||
|
||||
typedef struct {
|
||||
unsigned long m_dwFileVersion; // Version of the font file (Must match FONTFILEVERSION)
|
||||
float m_fFontHeight; // Height of the font strike in pixels
|
||||
float m_fFontTopPadding; // Padding above the strike zone
|
||||
float m_fFontBottomPadding; // Padding below the strike zone
|
||||
float m_fFontYAdvance; // Number of pixels to move the cursor for a line feed
|
||||
unsigned short m_cMaxGlyph; // Number of font characters (Should be an odd number to maintain DWORD Alignment)
|
||||
wchar_t m_TranslatorTable[1]; // ASCII to Glyph lookup table, NOTE: It's m_cMaxGlyph+1 in size.
|
||||
unsigned long m_dwFileVersion; /* Version of the font file (Must match FONTFILEVERSION). */
|
||||
float m_fFontHeight; /* Height of the font strike in pixels. */
|
||||
float m_fFontTopPadding; /* Padding above the strike zone. */
|
||||
float m_fFontBottomPadding; /* Padding below the strike zone. */
|
||||
float m_fFontYAdvance; /* Number of pixels to move the cursor for a line feed. */
|
||||
unsigned short m_cMaxGlyph; /* Number of font characters (Should be an odd number to maintain DWORD Alignment). */
|
||||
wchar_t m_TranslatorTable[1]; /* ASCII to Glyph lookup table, NOTE: It's m_cMaxGlyph+1 in size. */
|
||||
} FontFileHeaderImage_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned long m_dwNumGlyphs; // Size of font strike array (First entry is the unknown glyph)
|
||||
GLYPH_ATTR m_Glyphs[1]; // Array of font strike uv's etc... NOTE: It's m_dwNumGlyphs in size
|
||||
unsigned long m_dwNumGlyphs; /* Size of font strike array (First entry is the unknown glyph). */
|
||||
GLYPH_ATTR m_Glyphs[1]; /* Array of font strike uv's etc... NOTE: It's m_dwNumGlyphs in size. */
|
||||
} FontFileStrikesImage_t;
|
||||
|
||||
static const char g_strFontShader[] =
|
||||
@ -113,80 +113,82 @@ static HRESULT xdk360_video_font_create_shaders(
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
LPDIRECT3DDEVICE d3dr = d3d->dev;
|
||||
|
||||
if (!s_FontLocals.m_pFontVertexDecl)
|
||||
{
|
||||
do
|
||||
{
|
||||
static const D3DVERTEXELEMENT9 decl[] =
|
||||
{
|
||||
{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
|
||||
{ 0, 8, D3DDECLTYPE_USHORT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
|
||||
{ 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
|
||||
D3DDECL_END()
|
||||
};
|
||||
|
||||
|
||||
hr = d3dr->CreateVertexDeclaration( decl, &s_FontLocals.m_pFontVertexDecl );
|
||||
|
||||
if (hr >= 0)
|
||||
{
|
||||
ID3DXBuffer* pShaderCode;
|
||||
|
||||
hr = D3DXCompileShader( g_strFontShader, sizeof(g_strFontShader)-1 ,
|
||||
NULL, NULL, "main_vertex", "vs.2.0", 0,&pShaderCode, NULL, NULL );
|
||||
|
||||
if (hr >= 0)
|
||||
{
|
||||
hr = d3dr->CreateVertexShader( ( unsigned long * )pShaderCode->GetBufferPointer(),
|
||||
&s_FontLocals.m_pFontVertexShader );
|
||||
pShaderCode->Release();
|
||||
|
||||
if (hr >= 0)
|
||||
{
|
||||
hr = D3DXCompileShader( g_strFontShader, sizeof(g_strFontShader)-1 ,
|
||||
NULL, NULL, "main_fragment", "ps.2.0", 0,&pShaderCode, NULL, NULL );
|
||||
|
||||
if (hr >= 0)
|
||||
{
|
||||
hr = d3dr->CreatePixelShader((DWORD*)pShaderCode->GetBufferPointer(),
|
||||
&s_FontLocals.m_pFontPixelShader );
|
||||
pShaderCode->Release();
|
||||
|
||||
if (hr >= 0)
|
||||
{
|
||||
hr = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
s_FontLocals.m_pFontVertexShader->Release();
|
||||
}
|
||||
|
||||
s_FontLocals.m_pFontVertexShader = NULL;
|
||||
}
|
||||
|
||||
s_FontLocals.m_pFontVertexDecl->Release();
|
||||
}
|
||||
s_FontLocals.m_pFontVertexDecl = NULL;
|
||||
}while (0);
|
||||
}
|
||||
else
|
||||
if (s_FontLocals.m_pFontVertexDecl)
|
||||
{
|
||||
s_FontLocals.m_pFontVertexDecl->AddRef();
|
||||
s_FontLocals.m_pFontVertexShader->AddRef();
|
||||
s_FontLocals.m_pFontPixelShader->AddRef();
|
||||
hr = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
static const D3DVERTEXELEMENT9 decl[] =
|
||||
{
|
||||
{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
|
||||
{ 0, 8, D3DDECLTYPE_USHORT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
|
||||
{ 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
|
||||
D3DDECL_END()
|
||||
};
|
||||
|
||||
|
||||
hr = d3dr->CreateVertexDeclaration( decl, &s_FontLocals.m_pFontVertexDecl );
|
||||
|
||||
if (hr >= 0)
|
||||
{
|
||||
ID3DXBuffer* pShaderCode;
|
||||
|
||||
hr = D3DXCompileShader( g_strFontShader, sizeof(g_strFontShader)-1 ,
|
||||
NULL, NULL, "main_vertex", "vs.2.0", 0,&pShaderCode, NULL, NULL );
|
||||
|
||||
if (hr >= 0)
|
||||
{
|
||||
hr = d3dr->CreateVertexShader( ( unsigned long * )pShaderCode->GetBufferPointer(),
|
||||
&s_FontLocals.m_pFontVertexShader );
|
||||
pShaderCode->Release();
|
||||
|
||||
if (hr >= 0)
|
||||
{
|
||||
hr = D3DXCompileShader( g_strFontShader, sizeof(g_strFontShader)-1 ,
|
||||
NULL, NULL, "main_fragment", "ps.2.0", 0,&pShaderCode, NULL, NULL );
|
||||
|
||||
if (hr >= 0)
|
||||
{
|
||||
hr = d3dr->CreatePixelShader((DWORD*)pShaderCode->GetBufferPointer(),
|
||||
&s_FontLocals.m_pFontPixelShader );
|
||||
pShaderCode->Release();
|
||||
|
||||
if (hr >= 0)
|
||||
{
|
||||
hr = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
s_FontLocals.m_pFontVertexShader->Release();
|
||||
}
|
||||
|
||||
s_FontLocals.m_pFontVertexShader = NULL;
|
||||
}
|
||||
|
||||
s_FontLocals.m_pFontVertexDecl->Release();
|
||||
}
|
||||
s_FontLocals.m_pFontVertexDecl = NULL;
|
||||
}while(0);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static bool xdk360_init_font(void *data,
|
||||
const char *font_path, unsigned font_size)
|
||||
{
|
||||
(void)font_size;
|
||||
unsigned long dwFileVersion;
|
||||
const void *pFontData = NULL;
|
||||
D3DTexture *pFontTexture = NULL;
|
||||
const unsigned char * pData = NULL;
|
||||
xdk360_video_font_t *font = &m_Font;
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
// Create the font
|
||||
xdk360_video_font_t *font = &m_Font;
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
(void)font_size;
|
||||
|
||||
font->m_pFontTexture = NULL;
|
||||
font->m_dwNumGlyphs = 0L;
|
||||
@ -194,44 +196,41 @@ static bool xdk360_init_font(void *data,
|
||||
font->m_cMaxGlyph = 0;
|
||||
font->m_TranslatorTable = NULL;
|
||||
|
||||
// Create the font
|
||||
/* Create the font. */
|
||||
if (FAILED( m_xprResource.Create(font_path)))
|
||||
goto error;
|
||||
|
||||
D3DTexture *pFontTexture = m_xprResource.GetTexture( "FontTexture" );
|
||||
const void *pFontData = m_xprResource.GetData( "FontData");
|
||||
pFontTexture = m_xprResource.GetTexture( "FontTexture" );
|
||||
pFontData = m_xprResource.GetData( "FontData");
|
||||
|
||||
// Save a copy of the texture
|
||||
font->m_pFontTexture = pFontTexture;
|
||||
/* Save a copy of the texture. */
|
||||
font->m_pFontTexture = pFontTexture;
|
||||
|
||||
// Check version of file (to make sure it matches up with the FontMaker tool)
|
||||
const unsigned char * pData = (const unsigned char*)pFontData;
|
||||
unsigned long dwFileVersion = ((const FontFileHeaderImage_t *)pData)->m_dwFileVersion;
|
||||
/* Check version of file (to make sure it matches up with the FontMaker tool). */
|
||||
pData = (const unsigned char*)pFontData;
|
||||
dwFileVersion = ((const FontFileHeaderImage_t *)pData)->m_dwFileVersion;
|
||||
|
||||
if (dwFileVersion == FONTFILEVERSION)
|
||||
if (dwFileVersion != FONTFILEVERSION)
|
||||
{
|
||||
font->m_fFontHeight = ((const FontFileHeaderImage_t *)pData)->m_fFontHeight;
|
||||
font->m_fFontTopPadding = ((const FontFileHeaderImage_t *)pData)->m_fFontTopPadding;
|
||||
font->m_fFontBottomPadding = ((const FontFileHeaderImage_t *)pData)->m_fFontBottomPadding;
|
||||
font->m_fFontYAdvance = ((const FontFileHeaderImage_t *)pData)->m_fFontYAdvance;
|
||||
|
||||
// Point to the translator string which immediately follows the 4 floats
|
||||
font->m_cMaxGlyph = ((const FontFileHeaderImage_t *)pData)->m_cMaxGlyph;
|
||||
|
||||
font->m_TranslatorTable = const_cast<FontFileHeaderImage_t*>((const FontFileHeaderImage_t *)pData)->m_TranslatorTable;
|
||||
|
||||
pData += CALCFONTFILEHEADERSIZE( font->m_cMaxGlyph + 1 );
|
||||
|
||||
// Read the glyph attributes from the file
|
||||
font->m_dwNumGlyphs = ((const FontFileStrikesImage_t *)pData)->m_dwNumGlyphs;
|
||||
font->m_Glyphs = ((const FontFileStrikesImage_t *)pData)->m_Glyphs;
|
||||
}
|
||||
else
|
||||
{
|
||||
RARCH_ERR( "Incorrect version number on font file.\n" );
|
||||
RARCH_ERR("Incorrect version number on font file.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
font->m_fFontHeight = ((const FontFileHeaderImage_t *)pData)->m_fFontHeight;
|
||||
font->m_fFontTopPadding = ((const FontFileHeaderImage_t *)pData)->m_fFontTopPadding;
|
||||
font->m_fFontBottomPadding = ((const FontFileHeaderImage_t *)pData)->m_fFontBottomPadding;
|
||||
font->m_fFontYAdvance = ((const FontFileHeaderImage_t *)pData)->m_fFontYAdvance;
|
||||
|
||||
/* Point to the translator string which immediately follows the 4 floats. */
|
||||
font->m_cMaxGlyph = ((const FontFileHeaderImage_t *)pData)->m_cMaxGlyph;
|
||||
font->m_TranslatorTable = const_cast<FontFileHeaderImage_t*>((const FontFileHeaderImage_t *)pData)->m_TranslatorTable;
|
||||
|
||||
pData += CALCFONTFILEHEADERSIZE( font->m_cMaxGlyph + 1 );
|
||||
|
||||
/* Read the glyph attributes from the file. */
|
||||
font->m_dwNumGlyphs = ((const FontFileStrikesImage_t *)pData)->m_dwNumGlyphs;
|
||||
font->m_Glyphs = ((const FontFileStrikesImage_t *)pData)->m_Glyphs;
|
||||
|
||||
/* Create the vertex and pixel shaders for rendering the font */
|
||||
if (FAILED(xdk360_video_font_create_shaders(d3d, font)))
|
||||
{
|
||||
@ -287,22 +286,22 @@ static void xdk360_render_msg_post(xdk360_video_font_t * font, void *video_data)
|
||||
|
||||
static void xdk360_render_msg_pre(xdk360_video_font_t * font, void *video_data)
|
||||
{
|
||||
float vTexScale[4];
|
||||
D3DSURFACE_DESC TextureDesc;
|
||||
d3d_video_t *d3d = (d3d_video_t*)video_data;
|
||||
LPDIRECT3DDEVICE d3dr = d3d->dev;
|
||||
|
||||
// Save state
|
||||
/* Save state. */
|
||||
d3dr->GetRenderState( D3DRS_VIEWPORTENABLE, &font->m_dwSavedState );
|
||||
|
||||
// Set the texture scaling factor as a vertex shader constant
|
||||
D3DSURFACE_DESC TextureDesc;
|
||||
/* Set the texture scaling factor as a vertex shader constant. */
|
||||
D3DTexture_GetLevelDesc(font->m_pFontTexture, 0, &TextureDesc); // Get the description
|
||||
|
||||
// Set render state
|
||||
/* Set render state. */
|
||||
d3d_set_texture(d3dr, 0, font->m_pFontTexture);
|
||||
|
||||
// Read the TextureDesc here to ensure no load/hit/store from GetLevelDesc()
|
||||
float vTexScale[4];
|
||||
vTexScale[0] = 1.0f / TextureDesc.Width; // LHS due to int->float conversion
|
||||
/* Read the TextureDesc here to ensure no load/hit/store from GetLevelDesc(). */
|
||||
vTexScale[0] = 1.0f / TextureDesc.Width; /* LHS due to int->float conversion. */
|
||||
vTexScale[1] = 1.0f / TextureDesc.Height;
|
||||
vTexScale[2] = 0.0f;
|
||||
vTexScale[3] = 0.0f;
|
||||
@ -312,93 +311,102 @@ static void xdk360_render_msg_pre(xdk360_video_font_t * font, void *video_data)
|
||||
d3d_set_vertex_shader(d3dr, 0, s_FontLocals.m_pFontVertexShader);
|
||||
d3dr->SetPixelShader(s_FontLocals.m_pFontPixelShader);
|
||||
|
||||
// Set the texture scaling factor as a vertex shader constant
|
||||
// Call here to avoid load hit store from writing to vTexScale above
|
||||
/* Set the texture scaling factor as a vertex shader constant.
|
||||
* Call here to avoid load hit store from writing to vTexScale above
|
||||
*/
|
||||
d3dr->SetVertexShaderConstantF( 2, vTexScale, 1 );
|
||||
}
|
||||
|
||||
static void xdk360_draw_text(xdk360_video_font_t *font, void *video_data,
|
||||
float x, float y, const wchar_t * strText)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)video_data;
|
||||
unsigned long dwNumChars;
|
||||
volatile float *pVertex;
|
||||
float vColor[4], m_fCursorX, m_fCursorY;
|
||||
d3d_video_t *d3d = (d3d_video_t*)video_data;
|
||||
LPDIRECT3DDEVICE d3dr = d3d->dev;
|
||||
|
||||
// Set the color as a vertex shader constant
|
||||
float vColor[4];
|
||||
/* Set the color as a vertex shader constant. */
|
||||
vColor[0] = ( ( 0xffffffff & 0x00ff0000 ) >> 16L ) / 255.0f;
|
||||
vColor[1] = ( ( 0xffffffff & 0x0000ff00 ) >> 8L ) / 255.0f;
|
||||
vColor[2] = ( ( 0xffffffff & 0x000000ff ) >> 0L ) / 255.0f;
|
||||
vColor[3] = ( ( 0xffffffff & 0xff000000 ) >> 24L ) / 255.0f;
|
||||
|
||||
// Perform the actual storing of the color constant here to prevent
|
||||
// a load-hit-store by inserting work between the store and the use of
|
||||
// the vColor array.
|
||||
/* Perform the actual storing of the color constant here to prevent
|
||||
* a load-hit-store by inserting work between the store and the use of
|
||||
* the vColor array. */
|
||||
d3dr->SetVertexShaderConstantF( 1, vColor, 1 );
|
||||
|
||||
float m_fCursorX = floorf(x);
|
||||
float m_fCursorY = floorf(y);
|
||||
m_fCursorX = floorf(x);
|
||||
m_fCursorY = floorf(y);
|
||||
|
||||
// Adjust for padding
|
||||
/* Adjust for padding. */
|
||||
y -= font->m_fFontTopPadding;
|
||||
|
||||
// Begin drawing the vertices
|
||||
/* Begin drawing the vertices
|
||||
* Declared as volatile to force writing in ascending
|
||||
* address order.
|
||||
*
|
||||
* It prevents out of sequence writing in write combined
|
||||
* memory.
|
||||
*/
|
||||
|
||||
// Declared as volatile to force writing in ascending
|
||||
// address order. It prevents out of sequence writing in write combined
|
||||
// memory.
|
||||
|
||||
volatile float * pVertex;
|
||||
|
||||
unsigned long dwNumChars = wcslen(strText);
|
||||
dwNumChars = wcslen(strText);
|
||||
d3dr->BeginVertices(D3DPT_QUADLIST, 4 * dwNumChars,
|
||||
sizeof(XMFLOAT4), (void**)&pVertex);
|
||||
|
||||
// Draw four vertices for each glyph
|
||||
/* Draw four vertices for each glyph. */
|
||||
while (*strText)
|
||||
{
|
||||
// Get the current letter in the string
|
||||
wchar_t letter = *strText++;
|
||||
float fOffset, fAdvance, fWidth, fHeight;
|
||||
unsigned long tu1, tu2, tv1, tv2;
|
||||
const GLYPH_ATTR *pGlyph;
|
||||
wchar_t letter = *strText++; /* Get the current letter in the string */
|
||||
|
||||
/* Handle the newline character. */
|
||||
if (letter == L'\n')
|
||||
{
|
||||
// Handle the newline character
|
||||
m_fCursorX = x;
|
||||
m_fCursorY += font->m_fFontYAdvance * FONT_SCALE(d3d);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Translate unprintable characters
|
||||
const GLYPH_ATTR *pGlyph;
|
||||
|
||||
/* Translate unprintable characters. */
|
||||
if (letter <= font->m_cMaxGlyph)
|
||||
pGlyph = &font->m_Glyphs[font->m_TranslatorTable[letter]];
|
||||
else
|
||||
pGlyph = &font->m_Glyphs[0];
|
||||
|
||||
float fOffset = FONT_SCALE(d3d) * (float)pGlyph->wOffset;
|
||||
float fAdvance = FONT_SCALE(d3d) * (float)pGlyph->wAdvance;
|
||||
float fWidth = FONT_SCALE(d3d) * (float)pGlyph->wWidth;
|
||||
float fHeight = FONT_SCALE(d3d) * font->m_fFontHeight;
|
||||
fOffset = FONT_SCALE(d3d) * (float)pGlyph->wOffset;
|
||||
fAdvance = FONT_SCALE(d3d) * (float)pGlyph->wAdvance;
|
||||
fWidth = FONT_SCALE(d3d) * (float)pGlyph->wWidth;
|
||||
fHeight = FONT_SCALE(d3d) * font->m_fFontHeight;
|
||||
|
||||
m_fCursorX += fOffset;
|
||||
|
||||
// Add the vertices to draw this glyph
|
||||
/* Add the vertices to draw this glyph. */
|
||||
|
||||
unsigned long tu1 = pGlyph->tu1; // Convert shorts to 32 bit longs for in register merging
|
||||
unsigned long tv1 = pGlyph->tv1;
|
||||
unsigned long tu2 = pGlyph->tu2;
|
||||
unsigned long tv2 = pGlyph->tv2;
|
||||
/* Convert shorts to 32 bit longs for in register merging */
|
||||
tu1 = pGlyph->tu1;
|
||||
tv1 = pGlyph->tv1;
|
||||
tu2 = pGlyph->tu2;
|
||||
tv2 = pGlyph->tv2;
|
||||
|
||||
// NOTE: The vertexes are 2 floats for the screen coordinates,
|
||||
// followed by two USHORTS for the u/vs of the character,
|
||||
// terminated with the ARGB 32 bit color.
|
||||
// This makes for 16 bytes per vertex data (Easier to read)
|
||||
// Second NOTE: The uvs are merged and written using a DWORD due
|
||||
// to the write combining hardware being only able to handle 32,
|
||||
// 64 and 128 writes. Never store to write combined memory with
|
||||
// 8 or 16 bit instructions. You've been warned.
|
||||
/* NOTE: The vertexes are 2 floats for the screen coordinates,
|
||||
* followed by two USHORTS for the u/vs of the character,
|
||||
* terminated with the ARGB 32 bit color.
|
||||
*
|
||||
* This makes for 16 bytes per vertex data (Easier to read)
|
||||
*
|
||||
* Second NOTE: The U/V coordinates are merged and written
|
||||
* using a DWORD due to the write combining hardware
|
||||
* being only able to handle 32, 64 and 128 writes.
|
||||
*
|
||||
* Never store to write combined memory with 8 or 16bit
|
||||
* instructions. You've been warned.
|
||||
*/
|
||||
|
||||
// Setup the vertex/screen coordinates
|
||||
/* Setup the vertex/screen coordinates */
|
||||
|
||||
pVertex[0] = m_fCursorX;
|
||||
pVertex[1] = m_fCursorY;
|
||||
@ -425,11 +433,15 @@ static void xdk360_draw_text(xdk360_video_font_t *font, void *video_data,
|
||||
dwNumChars--;
|
||||
}
|
||||
|
||||
// Since we allocated vertex data space based on the string length, we now need to
|
||||
// add some dummy verts for any skipped characters (like newlines, etc.)
|
||||
/* Since we allocated vertex data space
|
||||
* based on the string length, we now need to
|
||||
* add some dummy verts for any skipped
|
||||
* characters (like newlines, etc.)
|
||||
*/
|
||||
while (dwNumChars)
|
||||
{
|
||||
for (unsigned i = 0; i < 16; i++)
|
||||
unsigned i;
|
||||
for (i = 0; i < 16; i++)
|
||||
pVertex[i] = 0;
|
||||
|
||||
pVertex += 16;
|
||||
@ -442,10 +454,10 @@ static void xdk360_draw_text(xdk360_video_font_t *font, void *video_data,
|
||||
static void xdk360_render_msg(void *data, const char *str_msg,
|
||||
const struct font_params *params)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
xdk360_video_font_t *font = &m_Font;
|
||||
wchar_t msg[PATH_MAX];
|
||||
float x, y;
|
||||
wchar_t msg[PATH_MAX_LENGTH];
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
xdk360_video_font_t *font = &m_Font;
|
||||
|
||||
if (params)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user