Rework font API to support loading fonts other than the shared system font (#416)

This commit is contained in:
Chris Feger 2019-03-27 18:32:07 -07:00 committed by fincs
parent 09688ea6fc
commit 2750c4a70b
2 changed files with 76 additions and 24 deletions

View File

@ -157,49 +157,78 @@ enum
/// Ensures the shared system font is mapped.
Result fontEnsureMapped(void);
/// Retrieves the font information structure of the shared system font.
static inline FINF_s* fontGetInfo(void)
/**
* @brief Fixes the pointers internal to a just-loaded font
* @param font Font to fix
* @remark Should never be run on the system font, and only once on any other font.
*/
void fontFixPointers(CFNT_s* font);
/// Gets the currently loaded system font
static inline CFNT_s* fontGetSystemFont(void)
{
extern CFNT_s* g_sharedFont;
return &g_sharedFont->finf;
return g_sharedFont;
}
/// Retrieves the texture sheet information of the shared system font.
static inline TGLP_s* fontGetGlyphInfo(void)
/**
* @brief Retrieves the font information structure of a font.
* @param font Pointer to font structure. If NULL, the shared system font is used.
*/
static inline FINF_s* fontGetInfo(CFNT_s* font)
{
return fontGetInfo()->tglp;
if (!font)
font = fontGetSystemFont();
return &font->finf;
}
/**
* @brief Retrieves the texture sheet information of a font.
* @param font Pointer to font structure. If NULL, the shared system font is used.
*/
static inline TGLP_s* fontGetGlyphInfo(CFNT_s* font)
{
if (!font)
font = fontGetSystemFont();
return fontGetInfo(font)->tglp;
}
/**
* @brief Retrieves the pointer to texture data for the specified texture sheet.
* @param font Pointer to font structure. If NULL, the shared system font is used.
* @param sheetIndex Index of the texture sheet.
*/
static inline void* fontGetGlyphSheetTex(int sheetIndex)
static inline void* fontGetGlyphSheetTex(CFNT_s* font, int sheetIndex)
{
TGLP_s* tglp = fontGetGlyphInfo();
if (!font)
font = fontGetSystemFont();
TGLP_s* tglp = fontGetGlyphInfo(font);
return &tglp->sheetData[sheetIndex*tglp->sheetSize];
}
/**
* @brief Retrieves the glyph index of the specified Unicode codepoint.
* @param font Pointer to font structure. If NULL, the shared system font is used.
* @param codePoint Unicode codepoint.
*/
int fontGlyphIndexFromCodePoint(u32 codePoint);
int fontGlyphIndexFromCodePoint(CFNT_s* font, u32 codePoint);
/**
* @brief Retrieves character width information of the specified glyph.
* @param font Pointer to font structure. If NULL, the shared system font is used.
* @param glyphIndex Index of the glyph.
*/
charWidthInfo_s* fontGetCharWidthInfo(int glyphIndex);
charWidthInfo_s* fontGetCharWidthInfo(CFNT_s* font, int glyphIndex);
/**
* @brief Calculates position information for the specified glyph.
* @param out Output structure in which to write the information.
* @param font Pointer to font structure. If NULL, the shared system font is used.
* @param glyphIndex Index of the glyph.
* @param flags Calculation flags (see GLYPH_POS_* flags).
* @param scaleX Scale factor to apply horizontally.
* @param scaleY Scale factor to apply vertically.
*/
void fontCalcGlyphPos(fontGlyphPos_s* out, int glyphIndex, u32 flags, float scaleX, float scaleY);
void fontCalcGlyphPos(fontGlyphPos_s* out, CFNT_s* font, int glyphIndex, u32 flags, float scaleX, float scaleY);
///@}

View File

@ -8,7 +8,6 @@
CFNT_s* g_sharedFont;
static u32 sharedFontAddr;
static int charPerSheet;
Result fontEnsureMapped(void)
{
@ -26,17 +25,33 @@ Result fontEnsureMapped(void)
return res;
g_sharedFont = (CFNT_s*)(sharedFontAddr+0x80);
charPerSheet = g_sharedFont->finf.tglp->nRows * g_sharedFont->finf.tglp->nLines;
return 0;
}
int fontGlyphIndexFromCodePoint(u32 codePoint)
void fontFixPointers(CFNT_s* font)
{
int ret = g_sharedFont->finf.alterCharIndex;
font->finf.tglp = (TGLP_s*)((u32)(font->finf.tglp) + (u32) font);
font->finf.tglp->sheetData = (u8*)((u32)(font->finf.tglp->sheetData) + (u32) font);
font->finf.cmap = (CMAP_s*)((u32)(font->finf.cmap) + (u32) font);
for (CMAP_s* cmap = font->finf.cmap; cmap->next; cmap = cmap->next)
cmap->next = (CMAP_s*)((u32)(cmap->next) + (u32) font);
font->finf.cwdh = (CWDH_s*)((u32)(font->finf.cwdh) + (u32) font);
for (CWDH_s* cwdh = font->finf.cwdh; cwdh->next; cwdh = cwdh->next)
cwdh->next = (CWDH_s*)((u32)(cwdh->next) + (u32) font);
}
int fontGlyphIndexFromCodePoint(CFNT_s* font, u32 codePoint)
{
if (!font)
font = g_sharedFont;
if (!font)
return -1;
int ret = font->finf.alterCharIndex;
if (codePoint < 0x10000)
{
CMAP_s* cmap;
for (cmap = g_sharedFont->finf.cmap; cmap; cmap = cmap->next)
for (CMAP_s* cmap = font->finf.cmap; cmap; cmap = cmap->next)
{
if (codePoint < cmap->codeBegin || codePoint > cmap->codeEnd)
continue;
@ -67,26 +82,34 @@ int fontGlyphIndexFromCodePoint(u32 codePoint)
return ret;
}
charWidthInfo_s* fontGetCharWidthInfo(int glyphIndex)
charWidthInfo_s* fontGetCharWidthInfo(CFNT_s* font, int glyphIndex)
{
if (!font)
font = g_sharedFont;
if (!font)
return NULL;
charWidthInfo_s* info = NULL;
CWDH_s* cwdh;
for (cwdh = g_sharedFont->finf.cwdh; cwdh && !info; cwdh = cwdh->next)
for (CWDH_s* cwdh = font->finf.cwdh; cwdh && !info; cwdh = cwdh->next)
{
if (glyphIndex < cwdh->startIndex || glyphIndex > cwdh->endIndex)
continue;
info = &cwdh->widths[glyphIndex - cwdh->startIndex];
}
if (!info)
info = &g_sharedFont->finf.defaultWidth;
info = &font->finf.defaultWidth;
return info;
}
void fontCalcGlyphPos(fontGlyphPos_s* out, int glyphIndex, u32 flags, float scaleX, float scaleY)
void fontCalcGlyphPos(fontGlyphPos_s* out, CFNT_s* font, int glyphIndex, u32 flags, float scaleX, float scaleY)
{
FINF_s* finf = &g_sharedFont->finf;
if (!font)
font = g_sharedFont;
if (!font)
return;
FINF_s* finf = &font->finf;
TGLP_s* tglp = finf->tglp;
charWidthInfo_s* cwi = fontGetCharWidthInfo(glyphIndex);
charWidthInfo_s* cwi = fontGetCharWidthInfo(font, glyphIndex);
int charPerSheet = font->finf.tglp->nRows * font->finf.tglp->nLines;
int sheetId = glyphIndex / charPerSheet;
int glInSheet = glyphIndex % charPerSheet;