Always fallback to hardcoded font when default.png is missing

This commit is contained in:
UnknownShadow200 2024-05-01 17:48:54 +10:00
parent 72ea074fa4
commit e98906b706
9 changed files with 233 additions and 223 deletions

View File

@ -539,6 +539,12 @@ static void DrawBitmappedTextCore(struct Bitmap* bmp, struct DrawTextArgs* args,
static void DrawBitmappedText(struct Bitmap* bmp, struct DrawTextArgs* args, int x, int y) {
int offset = Drawer2D_ShadowOffset(args->font->size);
if (!fontBitmap.scan0) {
if (args->useShadow) FallbackFont_DrawText(args, bmp, x, y, true);
FallbackFont_DrawText(args, bmp, x, y, false);
return;
}
if (args->useShadow) {
DrawBitmappedTextCore(bmp, args, x + offset, y + offset, true);
}
@ -550,6 +556,8 @@ static int MeasureBitmappedWidth(const struct DrawTextArgs* args) {
int xPadding, width;
cc_string text;
if (!fontBitmap.scan0) return FallbackFont_TextWidth(args);
/* adjust coords to make drawn text match GDI fonts */
xPadding = Drawer2D_XPadding(point);
width = 0;

View File

@ -260,9 +260,6 @@ void Platform_Init(void) {
DisableFpuExceptions();
Platform_ReadonlyFilesystem = true;
// TODO: Redesign Drawer2D to better handle this
Options_SetBool(OPT_USE_CHAT_FONT, true);
dfs_init(DFS_DEFAULT_LOCATION);
timer_init();
rtc_init();

View File

@ -425,9 +425,6 @@ void Platform_Init(void) {
InitNetworking();
cpuStartTiming(1);
// TODO: Redesign Drawer2D to better handle this
Options_Load();
Options_SetBool(OPT_USE_CHAT_FONT, true);
}
void Platform_Free(void) { }

View File

@ -227,8 +227,6 @@ cc_result Socket_CheckWritable(cc_socket s, cc_bool* writable) {
void Platform_Init(void) {
ResetGraph(0);
Stopwatch_Init();
Options_SetBool(OPT_USE_CHAT_FONT, true);
}
void Platform_Free(void) { }

View File

@ -213,8 +213,6 @@ cc_result Socket_CheckWritable(cc_socket s, cc_bool* writable) {
*#########################################################################################################################*/
void Platform_Init(void) {
Stopwatch_Init();
Options_SetBool(OPT_USE_CHAT_FONT, true);
}
void Platform_Free(void) { }

View File

@ -500,9 +500,6 @@ static void CreateRootDirectory(void) {
}
void Platform_Init(void) {
// TODO: Redesign Drawer2D to better handle this
//Options_SetBool(OPT_USE_CHAT_FONT, true);
CreateRootDirectory();
socketInitializeDefault();
}

View File

@ -31,6 +31,224 @@ struct IGameComponent SystemFonts_Component = {
};
/*########################################################################################################################*
*------------------------------------------------------Fallback font------------------------------------------------------*
*#########################################################################################################################*/
#define FallbackFont_ValidChar(c) ((c) > 32 && (c) < 127)
#define FallbackFont_ToIndex(c) ((c) - 33) /* First valid char is ! */
#define SPACE_WIDTH 2
#define CELL_SIZE 8
#define FallbackFont_GetRows(c) (FallbackFont_ValidChar(c) ? font_bitmap[FallbackFont_ToIndex(c)] : missing_cell)
#define FallbackFont_GetScale(size) ((size) >> 3)
static const cc_uint8 missing_cell[CELL_SIZE] = {
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
};
/* 8x8 font bitmap, represented with 1 bit for each pixel */
/* Source: Goodly's texture pack for ClassiCube */
static const cc_uint8 font_bitmap[][CELL_SIZE] = {
{ 0x01,0x01,0x01,0x01,0x01,0x00,0x01,0x00 }, /* ! */
{ 0x05,0x05,0x05,0x00,0x00,0x00,0x00,0x00 }, /* " */
{ 0x0A,0x0A,0x1F,0x0A,0x1F,0x0A,0x0A,0x00 }, /* # */
{ 0x04,0x1F,0x01,0x1F,0x10,0x1F,0x04,0x00 }, /* $ */
{ 0x00,0x21,0x11,0x08,0x04,0x22,0x21,0x00 }, /* % */
{ 0x0C,0x12,0x0C,0x2E,0x19,0x11,0x2E,0x00 }, /* & */
{ 0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00 }, /* ' */
{ 0x04,0x02,0x01,0x01,0x01,0x02,0x04,0x00 }, /* ( */
{ 0x01,0x02,0x04,0x04,0x04,0x02,0x01,0x00 }, /* ) */
{ 0x00,0x02,0x07,0x02,0x05,0x00,0x00,0x00 }, /* * */
{ 0x00,0x04,0x04,0x1F,0x04,0x04,0x00,0x00 }, /* + */
{ 0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x01 }, /* , */
{ 0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00 }, /* - */
{ 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00 }, /* . */
{ 0x08,0x08,0x04,0x04,0x02,0x02,0x01,0x00 }, /* / */
{ 0x06,0x09,0x0D,0x0B,0x09,0x09,0x06,0x00 }, /* 0 */
{ 0x02,0x03,0x02,0x02,0x02,0x02,0x07,0x00 }, /* 1 */
{ 0x06,0x09,0x08,0x04,0x02,0x09,0x0F,0x00 }, /* 2 */
{ 0x06,0x09,0x08,0x06,0x08,0x09,0x06,0x00 }, /* 3 */
{ 0x05,0x05,0x05,0x0F,0x04,0x04,0x04,0x00 }, /* 4 */
{ 0x0F,0x01,0x07,0x08,0x08,0x09,0x06,0x00 }, /* 5 */
{ 0x06,0x09,0x01,0x07,0x09,0x09,0x06,0x00 }, /* 6 */
{ 0x0F,0x08,0x08,0x04,0x04,0x02,0x02,0x00 }, /* 7 */
{ 0x06,0x09,0x09,0x06,0x09,0x09,0x06,0x00 }, /* 8 */
{ 0x06,0x09,0x09,0x0E,0x08,0x09,0x06,0x00 }, /* 9 */
{ 0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00 }, /* : */
{ 0x00,0x02,0x02,0x00,0x00,0x02,0x02,0x01 }, /* ; */
{ 0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00 }, /* < */
{ 0x00,0x00,0x1F,0x00,0x00,0x1F,0x00,0x00 }, /* = */
{ 0x00,0x01,0x02,0x04,0x02,0x01,0x00,0x00 }, /* > */
{ 0x07,0x09,0x08,0x04,0x02,0x00,0x02,0x00 }, /* ? */
{ 0x0E,0x11,0x1D,0x1D,0x1D,0x01,0x0E,0x00 }, /* @ */
{ 0x06,0x09,0x09,0x0F,0x09,0x09,0x09,0x00 }, /* A */
{ 0x07,0x09,0x09,0x07,0x09,0x09,0x07,0x00 }, /* B */
{ 0x06,0x09,0x01,0x01,0x01,0x09,0x06,0x00 }, /* C */
{ 0x07,0x09,0x09,0x09,0x09,0x09,0x07,0x00 }, /* D */
{ 0x0F,0x01,0x01,0x07,0x01,0x01,0x0F,0x00 }, /* E */
{ 0x0F,0x01,0x01,0x07,0x01,0x01,0x01,0x00 }, /* F */
{ 0x06,0x09,0x01,0x0D,0x09,0x09,0x06,0x00 }, /* G */
{ 0x09,0x09,0x09,0x0F,0x09,0x09,0x09,0x00 }, /* H */
{ 0x07,0x02,0x02,0x02,0x02,0x02,0x07,0x00 }, /* I */
{ 0x08,0x08,0x08,0x08,0x08,0x09,0x07,0x00 }, /* J */
{ 0x09,0x09,0x05,0x03,0x05,0x09,0x09,0x00 }, /* K */
{ 0x01,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 }, /* L */
{ 0x11,0x1B,0x15,0x11,0x11,0x11,0x11,0x00 }, /* M */
{ 0x09,0x0B,0x0D,0x09,0x09,0x09,0x09,0x00 }, /* N */
{ 0x06,0x09,0x09,0x09,0x09,0x09,0x06,0x00 }, /* O */
{ 0x07,0x09,0x09,0x07,0x01,0x01,0x01,0x00 }, /* P */
{ 0x06,0x09,0x09,0x09,0x09,0x05,0x0E,0x00 }, /* Q */
{ 0x07,0x09,0x09,0x07,0x09,0x09,0x09,0x00 }, /* R */
{ 0x06,0x09,0x01,0x06,0x08,0x09,0x06,0x00 }, /* S */
{ 0x07,0x02,0x02,0x02,0x02,0x02,0x02,0x00 }, /* T */
{ 0x09,0x09,0x09,0x09,0x09,0x09,0x06,0x00 }, /* U */
{ 0x11,0x11,0x11,0x11,0x11,0x0A,0x04,0x00 }, /* V */
{ 0x11,0x11,0x11,0x11,0x15,0x1B,0x11,0x00 }, /* W */
{ 0x11,0x11,0x0A,0x04,0x0A,0x11,0x11,0x00 }, /* X */
{ 0x11,0x11,0x0A,0x04,0x04,0x04,0x04,0x00 }, /* Y */
{ 0x0F,0x08,0x04,0x02,0x01,0x01,0x0F,0x00 }, /* Z */
{ 0x07,0x01,0x01,0x01,0x01,0x01,0x07,0x00 }, /* [ */
{ 0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x00 }, /* \ */
{ 0x07,0x04,0x04,0x04,0x04,0x04,0x07,0x00 }, /* ] */
{ 0x04,0x0A,0x11,0x00,0x00,0x00,0x00,0x00 }, /* ^ */
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F }, /* _ */
{ 0x01,0x01,0x02,0x00,0x00,0x00,0x00,0x00 }, /* ` */
{ 0x00,0x00,0x0E,0x09,0x09,0x0D,0x0B,0x00 }, /* a */
{ 0x01,0x01,0x07,0x09,0x09,0x09,0x07,0x00 }, /* b */
{ 0x00,0x00,0x06,0x09,0x01,0x09,0x06,0x00 }, /* c */
{ 0x08,0x08,0x0E,0x09,0x09,0x09,0x0E,0x00 }, /* d */
{ 0x00,0x00,0x06,0x09,0x0F,0x01,0x0E,0x00 }, /* e */
{ 0x06,0x01,0x07,0x01,0x01,0x01,0x01,0x00 }, /* f */
{ 0x00,0x00,0x0E,0x09,0x09,0x0E,0x08,0x07 }, /* g */
{ 0x01,0x01,0x07,0x09,0x09,0x09,0x09,0x00 }, /* h */
{ 0x01,0x00,0x01,0x01,0x01,0x01,0x01,0x00 }, /* i */
{ 0x08,0x00,0x08,0x08,0x08,0x08,0x09,0x06 }, /* j */
{ 0x01,0x01,0x09,0x05,0x03,0x05,0x09,0x00 }, /* k */
{ 0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x00 }, /* l */
{ 0x00,0x00,0x0B,0x15,0x15,0x11,0x11,0x00 }, /* m */
{ 0x00,0x00,0x07,0x09,0x09,0x09,0x09,0x00 }, /* n */
{ 0x00,0x00,0x06,0x09,0x09,0x09,0x06,0x00 }, /* o */
{ 0x00,0x00,0x07,0x09,0x09,0x07,0x01,0x01 }, /* p */
{ 0x00,0x00,0x0E,0x09,0x09,0x0E,0x08,0x08 }, /* q */
{ 0x00,0x00,0x05,0x03,0x01,0x01,0x01,0x00 }, /* r */
{ 0x00,0x00,0x0E,0x01,0x06,0x08,0x07,0x00 }, /* s */
{ 0x02,0x02,0x07,0x02,0x02,0x02,0x02,0x00 }, /* t */
{ 0x00,0x00,0x09,0x09,0x09,0x09,0x0E,0x00 }, /* u */
{ 0x00,0x00,0x09,0x09,0x09,0x05,0x03,0x00 }, /* v */
{ 0x00,0x00,0x11,0x11,0x15,0x15,0x1A,0x00 }, /* w */
{ 0x00,0x00,0x05,0x05,0x02,0x05,0x05,0x00 }, /* x */
{ 0x00,0x00,0x09,0x09,0x09,0x0E,0x08,0x07 }, /* y */
{ 0x00,0x00,0x0F,0x08,0x04,0x02,0x0F,0x00 }, /* z */
{ 0x04,0x02,0x02,0x01,0x02,0x02,0x04,0x00 }, /* { */
{ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 }, /* | */
{ 0x01,0x02,0x02,0x04,0x02,0x02,0x01,0x00 }, /* } */
{ 0x00,0x00,0x26,0x19,0x00,0x00,0x00,0x00 }, /* ~ */
};
static int Fallback_CellWidth(const cc_uint8* rows) {
int y, width, widest = 0;
for (y = 0; y < CELL_SIZE; y++)
{
widest = max(widest, rows[y]);
}
width = Math_ilog2(widest) + 1;
return width + 1; /* add 1 for padding */
}
int FallbackFont_TextWidth(const struct DrawTextArgs* args) {
cc_string left = args->text, part;
int size = args->font->size;
int scale = FallbackFont_GetScale(size);
char colorCode = 'f';
int i, width = 0;
while (Drawer2D_UNSAFE_NextPart(&left, &part, &colorCode))
{
for (i = 0; i < part.length; i++)
{
cc_uint8 c = part.buffer[i];
if (c == ' ') {
width += SPACE_WIDTH * scale;
} else {
width += Fallback_CellWidth(FallbackFont_GetRows(c)) * scale;
}
}
}
width = max(1, width);
if (args->useShadow) width += 1 * scale;
return width;
}
static void Fallback_DrawCell(struct Bitmap* bmp, int x, int y,
int scale, const cc_uint8* rows, BitmapCol color) {
int dst_width = CELL_SIZE * scale;
int dst_height = CELL_SIZE * scale;
int xx, srcX, dstX;
int yy, srcY, dstY;
BitmapCol* dst_row;
cc_uint8 src_row;
for (yy = 0; yy < dst_height; yy++)
{
srcY = yy / scale;
dstY = y + yy;
if (dstY < 0 || dstY >= bmp->height) continue;
dst_row = Bitmap_GetRow(bmp, dstY);
src_row = rows[srcY];
for (xx = 0; xx < dst_width; xx++)
{
srcX = xx / scale;
dstX = x + xx;
if (dstX < 0 || dstX >= bmp->width) continue;
if (src_row & (1 << srcX)) {
dst_row[dstX] = color;
}
}
}
}
void FallbackFont_DrawText(struct DrawTextArgs* args, struct Bitmap* bmp, int x, int y, cc_bool shadow) {
cc_string left = args->text, part;
int size = args->font->size;
int scale = FallbackFont_GetScale(size);
char colorCode = 'f';
const cc_uint8* rows;
BitmapCol color;
int i;
if (shadow) {
x += 1 * scale;
y += 1 * scale;
}
/* adjust coords to make drawn text match GDI fonts */
y += (args->font->height - size) / 2;
while (Drawer2D_UNSAFE_NextPart(&left, &part, &colorCode))
{
color = Drawer2D_GetColor(colorCode);
if (shadow) color = GetShadowColor(color);
for (i = 0; i < part.length; i++)
{
cc_uint8 c = part.buffer[i];
if (c == ' ') { x += SPACE_WIDTH * scale; continue; }
rows = FallbackFont_GetRows(c);
Fallback_DrawCell(bmp, x, y, scale, rows, color);
x += Fallback_CellWidth(rows) * scale;
}
}
}
/*########################################################################################################################*
*--------------------------------------------------------Freetype---------------------------------------------------------*
*#########################################################################################################################*/
@ -737,118 +955,6 @@ void SysFont_DrawText(struct DrawTextArgs* args, struct Bitmap* bmp, int x, int
interop_SysTextDraw(args, bmp, x, y, shadow);
}
#else
#define SysFont_ValidChar(c) ((c) > 32 && (c) < 127)
#define SysFont_ToIndex(c) ((c) - 33) /* First valid char is ! */
#define SPACE_WIDTH 2
#define CELL_SIZE 8
#define SysFont_GetRows(c) (SysFont_ValidChar(c) ? font_bitmap[SysFont_ToIndex(c)] : missing_cell)
static cc_uint8 missing_cell[CELL_SIZE] = {
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
};
/* 8x8 font bitmap, represented with 1 bit for each pixel */
/* Source: Goodly's texture pack for ClassiCube */
static cc_uint8 font_bitmap[][CELL_SIZE] = {
{ 0x01,0x01,0x01,0x01,0x01,0x00,0x01,0x00 }, /* ! */
{ 0x05,0x05,0x05,0x00,0x00,0x00,0x00,0x00 }, /* " */
{ 0x0A,0x0A,0x1F,0x0A,0x1F,0x0A,0x0A,0x00 }, /* # */
{ 0x04,0x1F,0x01,0x1F,0x10,0x1F,0x04,0x00 }, /* $ */
{ 0x00,0x21,0x11,0x08,0x04,0x22,0x21,0x00 }, /* % */
{ 0x0C,0x12,0x0C,0x2E,0x19,0x11,0x2E,0x00 }, /* & */
{ 0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00 }, /* ' */
{ 0x04,0x02,0x01,0x01,0x01,0x02,0x04,0x00 }, /* ( */
{ 0x01,0x02,0x04,0x04,0x04,0x02,0x01,0x00 }, /* ) */
{ 0x00,0x02,0x07,0x02,0x05,0x00,0x00,0x00 }, /* * */
{ 0x00,0x04,0x04,0x1F,0x04,0x04,0x00,0x00 }, /* + */
{ 0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x01 }, /* , */
{ 0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00 }, /* - */
{ 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00 }, /* . */
{ 0x08,0x08,0x04,0x04,0x02,0x02,0x01,0x00 }, /* / */
{ 0x06,0x09,0x0D,0x0B,0x09,0x09,0x06,0x00 }, /* 0 */
{ 0x02,0x03,0x02,0x02,0x02,0x02,0x07,0x00 }, /* 1 */
{ 0x06,0x09,0x08,0x04,0x02,0x09,0x0F,0x00 }, /* 2 */
{ 0x06,0x09,0x08,0x06,0x08,0x09,0x06,0x00 }, /* 3 */
{ 0x05,0x05,0x05,0x0F,0x04,0x04,0x04,0x00 }, /* 4 */
{ 0x0F,0x01,0x07,0x08,0x08,0x09,0x06,0x00 }, /* 5 */
{ 0x06,0x09,0x01,0x07,0x09,0x09,0x06,0x00 }, /* 6 */
{ 0x0F,0x08,0x08,0x04,0x04,0x02,0x02,0x00 }, /* 7 */
{ 0x06,0x09,0x09,0x06,0x09,0x09,0x06,0x00 }, /* 8 */
{ 0x06,0x09,0x09,0x0E,0x08,0x09,0x06,0x00 }, /* 9 */
{ 0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00 }, /* : */
{ 0x00,0x02,0x02,0x00,0x00,0x02,0x02,0x01 }, /* ; */
{ 0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00 }, /* < */
{ 0x00,0x00,0x1F,0x00,0x00,0x1F,0x00,0x00 }, /* = */
{ 0x00,0x01,0x02,0x04,0x02,0x01,0x00,0x00 }, /* > */
{ 0x07,0x09,0x08,0x04,0x02,0x00,0x02,0x00 }, /* ? */
{ 0x0E,0x11,0x1D,0x1D,0x1D,0x01,0x0E,0x00 }, /* @ */
{ 0x06,0x09,0x09,0x0F,0x09,0x09,0x09,0x00 }, /* A */
{ 0x07,0x09,0x09,0x07,0x09,0x09,0x07,0x00 }, /* B */
{ 0x06,0x09,0x01,0x01,0x01,0x09,0x06,0x00 }, /* C */
{ 0x07,0x09,0x09,0x09,0x09,0x09,0x07,0x00 }, /* D */
{ 0x0F,0x01,0x01,0x07,0x01,0x01,0x0F,0x00 }, /* E */
{ 0x0F,0x01,0x01,0x07,0x01,0x01,0x01,0x00 }, /* F */
{ 0x06,0x09,0x01,0x0D,0x09,0x09,0x06,0x00 }, /* G */
{ 0x09,0x09,0x09,0x0F,0x09,0x09,0x09,0x00 }, /* H */
{ 0x07,0x02,0x02,0x02,0x02,0x02,0x07,0x00 }, /* I */
{ 0x08,0x08,0x08,0x08,0x08,0x09,0x07,0x00 }, /* J */
{ 0x09,0x09,0x05,0x03,0x05,0x09,0x09,0x00 }, /* K */
{ 0x01,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 }, /* L */
{ 0x11,0x1B,0x15,0x11,0x11,0x11,0x11,0x00 }, /* M */
{ 0x09,0x0B,0x0D,0x09,0x09,0x09,0x09,0x00 }, /* N */
{ 0x06,0x09,0x09,0x09,0x09,0x09,0x06,0x00 }, /* O */
{ 0x07,0x09,0x09,0x07,0x01,0x01,0x01,0x00 }, /* P */
{ 0x06,0x09,0x09,0x09,0x09,0x05,0x0E,0x00 }, /* Q */
{ 0x07,0x09,0x09,0x07,0x09,0x09,0x09,0x00 }, /* R */
{ 0x06,0x09,0x01,0x06,0x08,0x09,0x06,0x00 }, /* S */
{ 0x07,0x02,0x02,0x02,0x02,0x02,0x02,0x00 }, /* T */
{ 0x09,0x09,0x09,0x09,0x09,0x09,0x06,0x00 }, /* U */
{ 0x11,0x11,0x11,0x11,0x11,0x0A,0x04,0x00 }, /* V */
{ 0x11,0x11,0x11,0x11,0x15,0x1B,0x11,0x00 }, /* W */
{ 0x11,0x11,0x0A,0x04,0x0A,0x11,0x11,0x00 }, /* X */
{ 0x11,0x11,0x0A,0x04,0x04,0x04,0x04,0x00 }, /* Y */
{ 0x0F,0x08,0x04,0x02,0x01,0x01,0x0F,0x00 }, /* Z */
{ 0x07,0x01,0x01,0x01,0x01,0x01,0x07,0x00 }, /* [ */
{ 0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x00 }, /* \ */
{ 0x07,0x04,0x04,0x04,0x04,0x04,0x07,0x00 }, /* ] */
{ 0x04,0x0A,0x11,0x00,0x00,0x00,0x00,0x00 }, /* ^ */
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F }, /* _ */
{ 0x01,0x01,0x02,0x00,0x00,0x00,0x00,0x00 }, /* ` */
{ 0x00,0x00,0x0E,0x09,0x09,0x0D,0x0B,0x00 }, /* a */
{ 0x01,0x01,0x07,0x09,0x09,0x09,0x07,0x00 }, /* b */
{ 0x00,0x00,0x06,0x09,0x01,0x09,0x06,0x00 }, /* c */
{ 0x08,0x08,0x0E,0x09,0x09,0x09,0x0E,0x00 }, /* d */
{ 0x00,0x00,0x06,0x09,0x0F,0x01,0x0E,0x00 }, /* e */
{ 0x06,0x01,0x07,0x01,0x01,0x01,0x01,0x00 }, /* f */
{ 0x00,0x00,0x0E,0x09,0x09,0x0E,0x08,0x07 }, /* g */
{ 0x01,0x01,0x07,0x09,0x09,0x09,0x09,0x00 }, /* h */
{ 0x01,0x00,0x01,0x01,0x01,0x01,0x01,0x00 }, /* i */
{ 0x08,0x00,0x08,0x08,0x08,0x08,0x09,0x06 }, /* j */
{ 0x01,0x01,0x09,0x05,0x03,0x05,0x09,0x00 }, /* k */
{ 0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x00 }, /* l */
{ 0x00,0x00,0x0B,0x15,0x15,0x11,0x11,0x00 }, /* m */
{ 0x00,0x00,0x07,0x09,0x09,0x09,0x09,0x00 }, /* n */
{ 0x00,0x00,0x06,0x09,0x09,0x09,0x06,0x00 }, /* o */
{ 0x00,0x00,0x07,0x09,0x09,0x07,0x01,0x01 }, /* p */
{ 0x00,0x00,0x0E,0x09,0x09,0x0E,0x08,0x08 }, /* q */
{ 0x00,0x00,0x05,0x03,0x01,0x01,0x01,0x00 }, /* r */
{ 0x00,0x00,0x0E,0x01,0x06,0x08,0x07,0x00 }, /* s */
{ 0x02,0x02,0x07,0x02,0x02,0x02,0x02,0x00 }, /* t */
{ 0x00,0x00,0x09,0x09,0x09,0x09,0x0E,0x00 }, /* u */
{ 0x00,0x00,0x09,0x09,0x09,0x05,0x03,0x00 }, /* v */
{ 0x00,0x00,0x11,0x11,0x15,0x15,0x1A,0x00 }, /* w */
{ 0x00,0x00,0x05,0x05,0x02,0x05,0x05,0x00 }, /* x */
{ 0x00,0x00,0x09,0x09,0x09,0x0E,0x08,0x07 }, /* y */
{ 0x00,0x00,0x0F,0x08,0x04,0x02,0x0F,0x00 }, /* z */
{ 0x04,0x02,0x02,0x01,0x02,0x02,0x04,0x00 }, /* { */
{ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 }, /* | */
{ 0x01,0x02,0x02,0x04,0x02,0x02,0x01,0x00 }, /* } */
{ 0x00,0x00,0x26,0x19,0x00,0x00,0x00,0x00 }, /* ~ */
};
void SysFonts_SaveCache(void) { }
cc_result SysFonts_Register(const cc_string* path, SysFont_RegisterCallback callback) {
return ERR_NOT_SUPPORTED;
@ -867,7 +973,7 @@ cc_result SysFont_Make(struct FontDesc* desc, const cc_string* fontName, int siz
desc->flags = flags;
desc->height = Drawer2D_AdjHeight(size);
desc->handle = (void*)(size / 8);
desc->handle = (void*);
return 0;
}
@ -879,106 +985,11 @@ void SysFont_Free(struct FontDesc* desc) {
desc->handle = NULL;
}
static int CellWidth(cc_uint8* rows) {
int y, width, widest = 0;
for (y = 0; y < CELL_SIZE; y++)
{
widest = max(widest, rows[y]);
}
width = Math_ilog2(widest) + 1;
return width + 1; /* add 1 for padding */
}
int SysFont_TextWidth(struct DrawTextArgs* args) {
cc_string left = args->text, part;
int scale = (int)args->font->handle;
char colorCode = 'f';
int i, width = 0;
while (Drawer2D_UNSAFE_NextPart(&left, &part, &colorCode))
{
for (i = 0; i < part.length; i++)
{
cc_uint8 c = part.buffer[i];
if (c == ' ') {
width += SPACE_WIDTH * scale;
} else {
width += CellWidth(SysFont_GetRows(c)) * scale;
}
}
}
width = max(1, width);
if (args->useShadow) width += 1 * scale;
return width;
}
static void DrawCell(struct Bitmap* bmp, int x, int y,
int scale, cc_uint8 * rows, BitmapCol color) {
int dst_width = CELL_SIZE * scale;
int dst_height = CELL_SIZE * scale;
int xx, srcX, dstX;
int yy, srcY, dstY;
BitmapCol* dst_row;
cc_uint8 src_row;
for (yy = 0; yy < dst_height; yy++)
{
srcY = yy / scale;
dstY = y + yy;
if (dstY < 0 || dstY >= bmp->height) continue;
dst_row = Bitmap_GetRow(bmp, dstY);
src_row = rows[srcY];
for (xx = 0; xx < dst_width; xx++)
{
srcX = xx / scale;
dstX = x + xx;
if (dstX < 0 || dstX >= bmp->width) continue;
if (src_row & (1 << srcX)) {
dst_row[dstX] = color;
}
}
}
return FallbackFont_TextWidth(args);
}
void SysFont_DrawText(struct DrawTextArgs* args, struct Bitmap* bmp, int x, int y, cc_bool shadow) {
cc_string left = args->text, part;
int scale = (int)args->font->handle;
int size = args->font->size;
char colorCode = 'f';
cc_uint8* rows;
BitmapCol color;
int i;
if (shadow) {
x += 1 * scale;
y += 1 * scale;
}
/* adjust coords to make drawn text match GDI fonts */
y += (args->font->height - size) / 2;
while (Drawer2D_UNSAFE_NextPart(&left, &part, &colorCode))
{
color = Drawer2D_GetColor(colorCode);
if (shadow) color = GetShadowColor(color);
for (i = 0; i < part.length; i++)
{
cc_uint8 c = part.buffer[i];
if (c == ' ') { x += SPACE_WIDTH * scale; continue; }
rows = SysFont_GetRows(c);
DrawCell(bmp, x, y, scale, rows, color);
x += CellWidth(rows) * scale;
}
}
FallbackFont_DrawText(args, size, bmp, x, y, shadow);
}
#endif

View File

@ -11,6 +11,9 @@ struct IGameComponent;
struct StringsBuffer;
extern struct IGameComponent SystemFonts_Component;
int FallbackFont_TextWidth(const struct DrawTextArgs* args);
void FallbackFont_DrawText(struct DrawTextArgs* args, struct Bitmap* bmp, int x, int y, cc_bool shadow);
/* Allocates a new system font from the given arguments */
cc_result SysFont_Make(struct FontDesc* desc, const cc_string* fontName, int size, int flags);
/* Frees an allocated system font */

View File

@ -391,6 +391,7 @@ void OnscreenKeyboard_Open(struct OpenKeyboardArgs* args) {
}
nn::swkbd::MuteAllSound(false);
// TODO
Mem_Set(&appear_arg, 0, sizeof(appear_arg));
appear_arg.inputFormArg.hintText = u"I'm a hint.";