mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2025-02-17 20:31:57 -05:00
Cleanup.
This commit is contained in:
parent
ed9761e9c9
commit
18c4e37d66
1 changed files with 92 additions and 105 deletions
|
@ -105,7 +105,7 @@ bool TrueTypeFont::init(const uint8_t* _buffer, uint32_t _bufferSize, int32_t _f
|
||||||
if (error == FT_Err_Unknown_File_Format)
|
if (error == FT_Err_Unknown_File_Format)
|
||||||
{
|
{
|
||||||
// the font file could be opened and read, but it appears
|
// the font file could be opened and read, but it appears
|
||||||
//that its font format is unsupported
|
// that its font format is unsupported
|
||||||
FT_Done_FreeType(holder->library);
|
FT_Done_FreeType(holder->library);
|
||||||
delete holder;
|
delete holder;
|
||||||
return false;
|
return false;
|
||||||
|
@ -270,7 +270,7 @@ bool TrueTypeFont::bakeGlyphSubpixel(CodePoint _codePoint, GlyphInfo& _glyphInfo
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void make_distance_map(uint8_t* _img, uint8_t* _outImg, uint32_t _width, uint32_t _height)
|
static void makeDistanceMap(const uint8_t* _img, uint8_t* _outImg, uint32_t _width, uint32_t _height)
|
||||||
{
|
{
|
||||||
int16_t* xdist = (int16_t*)malloc(_width * _height * sizeof(int16_t) );
|
int16_t* xdist = (int16_t*)malloc(_width * _height * sizeof(int16_t) );
|
||||||
int16_t* ydist = (int16_t*)malloc(_width * _height * sizeof(int16_t) );
|
int16_t* ydist = (int16_t*)malloc(_width * _height * sizeof(int16_t) );
|
||||||
|
@ -394,65 +394,61 @@ bool TrueTypeFont::bakeGlyphDistance(CodePoint _codePoint, GlyphInfo& _glyphInfo
|
||||||
|
|
||||||
FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;
|
FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;
|
||||||
|
|
||||||
int32_t x = bitmap->left;
|
int32_t xx = bitmap->left;
|
||||||
int32_t y = -bitmap->top;
|
int32_t yy = -bitmap->top;
|
||||||
int32_t w = bitmap->bitmap.width;
|
int32_t ww = bitmap->bitmap.width;
|
||||||
int32_t h = bitmap->bitmap.rows;
|
int32_t hh = bitmap->bitmap.rows;
|
||||||
|
|
||||||
_glyphInfo.offset_x = (float) x;
|
_glyphInfo.offset_x = (float) xx;
|
||||||
_glyphInfo.offset_y = (float) y;
|
_glyphInfo.offset_y = (float) yy;
|
||||||
_glyphInfo.width = (float) w;
|
_glyphInfo.width = (float) ww;
|
||||||
_glyphInfo.height = (float) h;
|
_glyphInfo.height = (float) hh;
|
||||||
_glyphInfo.advance_x = (float)slot->advance.x / 64.0f;
|
_glyphInfo.advance_x = (float)slot->advance.x / 64.0f;
|
||||||
_glyphInfo.advance_y = (float)slot->advance.y / 64.0f;
|
_glyphInfo.advance_y = (float)slot->advance.y / 64.0f;
|
||||||
|
|
||||||
int32_t charsize = 1;
|
|
||||||
int32_t depth = 1;
|
int32_t depth = 1;
|
||||||
int32_t stride = bitmap->bitmap.pitch;
|
int32_t stride = bitmap->bitmap.pitch;
|
||||||
|
|
||||||
for (int32_t ii = 0; ii < h; ++ii)
|
uint32_t pitch = ww * depth;
|
||||||
|
uint8_t* out = _outBuffer;
|
||||||
|
uint8_t* input = bitmap->bitmap.buffer;
|
||||||
|
for (int32_t ii = 0; ii < hh; ++ii)
|
||||||
{
|
{
|
||||||
memcpy(_outBuffer + (ii * w) * charsize * depth,
|
memcpy(out, input, pitch);
|
||||||
bitmap->bitmap.buffer + (ii * stride) * charsize, w * charsize * depth);
|
|
||||||
|
out += pitch;
|
||||||
|
input += stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_Done_Glyph(glyph);
|
FT_Done_Glyph(glyph);
|
||||||
|
|
||||||
if (w * h > 0)
|
if (ww * hh > 0)
|
||||||
{
|
{
|
||||||
uint32_t dw = 6;
|
uint32_t dw = 6;
|
||||||
uint32_t dh = 6;
|
uint32_t dh = 6;
|
||||||
if (dw < 2)
|
|
||||||
{
|
|
||||||
dw = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dh < 2)
|
uint32_t nw = ww + dw * 2;
|
||||||
{
|
uint32_t nh = hh + dh * 2;
|
||||||
dh = 2;
|
BX_CHECK(nw * nh < 128 * 128, "Buffer overflow (size %d)", nw * nh);
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t nw = w + dw * 2;
|
|
||||||
uint32_t nh = h + dh * 2;
|
|
||||||
BX_CHECK(nw * nh < 128 * 128, "buffer overflow");
|
|
||||||
uint32_t buffSize = nw * nh * sizeof(uint8_t);
|
uint32_t buffSize = nw * nh * sizeof(uint8_t);
|
||||||
|
|
||||||
uint8_t* alphaImg = (uint8_t*) malloc(buffSize);
|
uint8_t* alphaImg = (uint8_t*)malloc(buffSize);
|
||||||
memset(alphaImg, 0, nw * nh * sizeof(uint8_t) );
|
memset(alphaImg, 0, nw * nh * sizeof(uint8_t) );
|
||||||
|
|
||||||
//copy the original buffer to the temp one
|
//copy the original buffer to the temp one
|
||||||
for (uint32_t ii = dh; ii < nh - dh; ++ii)
|
for (uint32_t ii = dh; ii < nh - dh; ++ii)
|
||||||
{
|
{
|
||||||
memcpy(alphaImg + ii * nw + dw, _outBuffer + (ii - dh) * w, w);
|
memcpy(alphaImg + ii * nw + dw, _outBuffer + (ii - dh) * ww, ww);
|
||||||
}
|
}
|
||||||
|
|
||||||
make_distance_map(alphaImg, _outBuffer, nw, nh);
|
makeDistanceMap(alphaImg, _outBuffer, nw, nh);
|
||||||
free(alphaImg);
|
free(alphaImg);
|
||||||
|
|
||||||
_glyphInfo.offset_x -= (float) dw;
|
_glyphInfo.offset_x -= (float)dw;
|
||||||
_glyphInfo.offset_y -= (float) dh;
|
_glyphInfo.offset_y -= (float)dh;
|
||||||
_glyphInfo.width = (float) nw;
|
_glyphInfo.width = (float)nw;
|
||||||
_glyphInfo.height = (float) nh;
|
_glyphInfo.height = (float)nh;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -541,7 +537,7 @@ TrueTypeHandle FontManager::createTtf(const uint8_t* _buffer, uint32_t _size)
|
||||||
m_cachedFiles[id].bufferSize = _size;
|
m_cachedFiles[id].bufferSize = _size;
|
||||||
memcpy(m_cachedFiles[id].buffer, _buffer, _size);
|
memcpy(m_cachedFiles[id].buffer, _buffer, _size);
|
||||||
|
|
||||||
TrueTypeHandle ret = {id};
|
TrueTypeHandle ret = { id };
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,12 +550,12 @@ void FontManager::destroyTtf(TrueTypeHandle _handle)
|
||||||
m_filesHandles.free(_handle.idx);
|
m_filesHandles.free(_handle.idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
FontHandle FontManager::createFontByPixelSize(TrueTypeHandle _tt_handle, uint32_t _typefaceIndex, uint32_t _pixelSize, uint32_t _fontType)
|
FontHandle FontManager::createFontByPixelSize(TrueTypeHandle _ttfHandle, uint32_t _typefaceIndex, uint32_t _pixelSize, uint32_t _fontType)
|
||||||
{
|
{
|
||||||
BX_CHECK(bgfx::invalidHandle != _tt_handle.idx, "Invalid handle used");
|
BX_CHECK(bgfx::invalidHandle != _ttfHandle.idx, "Invalid handle used");
|
||||||
|
|
||||||
TrueTypeFont* ttf = new TrueTypeFont();
|
TrueTypeFont* ttf = new TrueTypeFont();
|
||||||
if (!ttf->init(m_cachedFiles[_tt_handle.idx].buffer, m_cachedFiles[_tt_handle.idx].bufferSize, _typefaceIndex, _pixelSize) )
|
if (!ttf->init(m_cachedFiles[_ttfHandle.idx].buffer, m_cachedFiles[_ttfHandle.idx].bufferSize, _typefaceIndex, _pixelSize) )
|
||||||
{
|
{
|
||||||
delete ttf;
|
delete ttf;
|
||||||
FontHandle invalid = { bx::HandleAlloc::invalid };
|
FontHandle invalid = { bx::HandleAlloc::invalid };
|
||||||
|
@ -569,21 +565,23 @@ FontHandle FontManager::createFontByPixelSize(TrueTypeHandle _tt_handle, uint32_
|
||||||
uint16_t fontIdx = m_fontHandles.alloc();
|
uint16_t fontIdx = m_fontHandles.alloc();
|
||||||
BX_CHECK(fontIdx != bx::HandleAlloc::invalid, "Invalid handle used");
|
BX_CHECK(fontIdx != bx::HandleAlloc::invalid, "Invalid handle used");
|
||||||
|
|
||||||
m_cachedFonts[fontIdx].trueTypeFont = ttf;
|
CachedFont& font = m_cachedFonts[fontIdx];
|
||||||
m_cachedFonts[fontIdx].fontInfo = ttf->getFontInfo();
|
font.trueTypeFont = ttf;
|
||||||
m_cachedFonts[fontIdx].fontInfo.fontType = _fontType;
|
font.fontInfo = ttf->getFontInfo();
|
||||||
m_cachedFonts[fontIdx].fontInfo.pixelSize = _pixelSize;
|
font.fontInfo.fontType = _fontType;
|
||||||
m_cachedFonts[fontIdx].cachedGlyphs.clear();
|
font.fontInfo.pixelSize = _pixelSize;
|
||||||
m_cachedFonts[fontIdx].masterFontHandle.idx = bx::HandleAlloc::invalid;
|
font.cachedGlyphs.clear();
|
||||||
FontHandle ret = {fontIdx};
|
font.masterFontHandle.idx = bx::HandleAlloc::invalid;
|
||||||
return ret;
|
|
||||||
|
FontHandle handle = { fontIdx };
|
||||||
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
FontHandle FontManager::createScaledFontToPixelSize(FontHandle _baseFontHandle, uint32_t _pixelSize)
|
FontHandle FontManager::createScaledFontToPixelSize(FontHandle _baseFontHandle, uint32_t _pixelSize)
|
||||||
{
|
{
|
||||||
BX_CHECK(bgfx::invalidHandle != _baseFontHandle.idx, "Invalid handle used");
|
BX_CHECK(bgfx::invalidHandle != _baseFontHandle.idx, "Invalid handle used");
|
||||||
CachedFont& font = m_cachedFonts[_baseFontHandle.idx];
|
CachedFont& baseFont = m_cachedFonts[_baseFontHandle.idx];
|
||||||
FontInfo& fontInfo = font.fontInfo;
|
FontInfo& fontInfo = baseFont.fontInfo;
|
||||||
|
|
||||||
FontInfo newFontInfo = fontInfo;
|
FontInfo newFontInfo = fontInfo;
|
||||||
newFontInfo.pixelSize = _pixelSize;
|
newFontInfo.pixelSize = _pixelSize;
|
||||||
|
@ -597,25 +595,30 @@ FontHandle FontManager::createScaledFontToPixelSize(FontHandle _baseFontHandle,
|
||||||
|
|
||||||
uint16_t fontIdx = m_fontHandles.alloc();
|
uint16_t fontIdx = m_fontHandles.alloc();
|
||||||
BX_CHECK(fontIdx != bx::HandleAlloc::invalid, "Invalid handle used");
|
BX_CHECK(fontIdx != bx::HandleAlloc::invalid, "Invalid handle used");
|
||||||
m_cachedFonts[fontIdx].cachedGlyphs.clear();
|
|
||||||
m_cachedFonts[fontIdx].fontInfo = newFontInfo;
|
CachedFont& font = m_cachedFonts[fontIdx];
|
||||||
m_cachedFonts[fontIdx].trueTypeFont = NULL;
|
font.cachedGlyphs.clear();
|
||||||
m_cachedFonts[fontIdx].masterFontHandle = _baseFontHandle;
|
font.fontInfo = newFontInfo;
|
||||||
FontHandle ret = {fontIdx};
|
font.trueTypeFont = NULL;
|
||||||
return ret;
|
font.masterFontHandle = _baseFontHandle;
|
||||||
|
|
||||||
|
FontHandle handle = { fontIdx };
|
||||||
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FontManager::destroyFont(FontHandle _handle)
|
void FontManager::destroyFont(FontHandle _handle)
|
||||||
{
|
{
|
||||||
BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used");
|
BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used");
|
||||||
|
|
||||||
if (m_cachedFonts[_handle.idx].trueTypeFont != NULL)
|
CachedFont& font = m_cachedFonts[_handle.idx];
|
||||||
|
|
||||||
|
if (font.trueTypeFont != NULL)
|
||||||
{
|
{
|
||||||
delete m_cachedFonts[_handle.idx].trueTypeFont;
|
delete font.trueTypeFont;
|
||||||
m_cachedFonts[_handle.idx].trueTypeFont = NULL;
|
font.trueTypeFont = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cachedFonts[_handle.idx].cachedGlyphs.clear();
|
font.cachedGlyphs.clear();
|
||||||
m_fontHandles.free(_handle.idx);
|
m_fontHandles.free(_handle.idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -624,24 +627,21 @@ bool FontManager::preloadGlyph(FontHandle _handle, const wchar_t* _string)
|
||||||
BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used");
|
BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used");
|
||||||
CachedFont& font = m_cachedFonts[_handle.idx];
|
CachedFont& font = m_cachedFonts[_handle.idx];
|
||||||
|
|
||||||
//if truetype present
|
if (NULL == font.trueTypeFont)
|
||||||
if (font.trueTypeFont != NULL)
|
|
||||||
{
|
{
|
||||||
//parse string
|
return false;
|
||||||
for (uint32_t ii = 0, end = wcslen(_string); ii < end; ++ii)
|
|
||||||
{
|
|
||||||
//if glyph cached, continue
|
|
||||||
CodePoint codePoint = _string[ii];
|
|
||||||
if (!preloadGlyph(_handle, codePoint) )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
for (uint32_t ii = 0, end = wcslen(_string); ii < end; ++ii)
|
||||||
|
{
|
||||||
|
CodePoint codePoint = _string[ii];
|
||||||
|
if (!preloadGlyph(_handle, codePoint) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FontManager::preloadGlyph(FontHandle _handle, CodePoint _codePoint)
|
bool FontManager::preloadGlyph(FontHandle _handle, CodePoint _codePoint)
|
||||||
|
@ -649,28 +649,23 @@ bool FontManager::preloadGlyph(FontHandle _handle, CodePoint _codePoint)
|
||||||
BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used");
|
BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used");
|
||||||
CachedFont& font = m_cachedFonts[_handle.idx];
|
CachedFont& font = m_cachedFonts[_handle.idx];
|
||||||
FontInfo& fontInfo = font.fontInfo;
|
FontInfo& fontInfo = font.fontInfo;
|
||||||
//check if glyph not already present
|
|
||||||
GlyphHashMap::iterator iter = font.cachedGlyphs.find(_codePoint);
|
GlyphHashMap::iterator iter = font.cachedGlyphs.find(_codePoint);
|
||||||
if (iter != font.cachedGlyphs.end() )
|
if (iter != font.cachedGlyphs.end() )
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if truetype present
|
if (NULL != font.trueTypeFont)
|
||||||
if (font.trueTypeFont != NULL)
|
|
||||||
{
|
{
|
||||||
GlyphInfo glyphInfo;
|
GlyphInfo glyphInfo;
|
||||||
|
|
||||||
//bake glyph as bitmap to buffer
|
|
||||||
switch (font.fontInfo.fontType)
|
switch (font.fontInfo.fontType)
|
||||||
{
|
{
|
||||||
case FONT_TYPE_ALPHA:
|
case FONT_TYPE_ALPHA:
|
||||||
font.trueTypeFont->bakeGlyphAlpha(_codePoint, glyphInfo, m_buffer);
|
font.trueTypeFont->bakeGlyphAlpha(_codePoint, glyphInfo, m_buffer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//case FONT_TYPE_LCD:
|
|
||||||
//font.m_trueTypeFont->bakeGlyphSubpixel(codePoint, glyphInfo, m_buffer);
|
|
||||||
//break;
|
|
||||||
case FONT_TYPE_DISTANCE:
|
case FONT_TYPE_DISTANCE:
|
||||||
font.trueTypeFont->bakeGlyphDistance(_codePoint, glyphInfo, m_buffer);
|
font.trueTypeFont->bakeGlyphDistance(_codePoint, glyphInfo, m_buffer);
|
||||||
break;
|
break;
|
||||||
|
@ -683,7 +678,6 @@ bool FontManager::preloadGlyph(FontHandle _handle, CodePoint _codePoint)
|
||||||
BX_CHECK(false, "TextureType not supported yet");
|
BX_CHECK(false, "TextureType not supported yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
//copy bitmap to texture
|
|
||||||
if (!addBitmap(glyphInfo, m_buffer) )
|
if (!addBitmap(glyphInfo, m_buffer) )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -696,32 +690,25 @@ bool FontManager::preloadGlyph(FontHandle _handle, CodePoint _codePoint)
|
||||||
glyphInfo.height = (glyphInfo.height * fontInfo.scale);
|
glyphInfo.height = (glyphInfo.height * fontInfo.scale);
|
||||||
glyphInfo.width = (glyphInfo.width * fontInfo.scale);
|
glyphInfo.width = (glyphInfo.width * fontInfo.scale);
|
||||||
|
|
||||||
// store cached glyph
|
|
||||||
font.cachedGlyphs[_codePoint] = glyphInfo;
|
font.cachedGlyphs[_codePoint] = glyphInfo;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (font.masterFontHandle.idx != bgfx::invalidHandle
|
||||||
|
&& preloadGlyph(font.masterFontHandle, _codePoint) )
|
||||||
{
|
{
|
||||||
//retrieve glyph from parent font if any
|
const GlyphInfo* glyph = getGlyphInfo(font.masterFontHandle, _codePoint);
|
||||||
if (font.masterFontHandle.idx != bgfx::invalidHandle)
|
|
||||||
{
|
|
||||||
if (preloadGlyph(font.masterFontHandle, _codePoint) )
|
|
||||||
{
|
|
||||||
const GlyphInfo* glyph = getGlyphInfo(font.masterFontHandle, _codePoint);
|
|
||||||
|
|
||||||
GlyphInfo glyphInfo = *glyph;
|
GlyphInfo glyphInfo = *glyph;
|
||||||
glyphInfo.advance_x = (glyphInfo.advance_x * fontInfo.scale);
|
glyphInfo.advance_x = (glyphInfo.advance_x * fontInfo.scale);
|
||||||
glyphInfo.advance_y = (glyphInfo.advance_y * fontInfo.scale);
|
glyphInfo.advance_y = (glyphInfo.advance_y * fontInfo.scale);
|
||||||
glyphInfo.offset_x = (glyphInfo.offset_x * fontInfo.scale);
|
glyphInfo.offset_x = (glyphInfo.offset_x * fontInfo.scale);
|
||||||
glyphInfo.offset_y = (glyphInfo.offset_y * fontInfo.scale);
|
glyphInfo.offset_y = (glyphInfo.offset_y * fontInfo.scale);
|
||||||
glyphInfo.height = (glyphInfo.height * fontInfo.scale);
|
glyphInfo.height = (glyphInfo.height * fontInfo.scale);
|
||||||
glyphInfo.width = (glyphInfo.width * fontInfo.scale);
|
glyphInfo.width = (glyphInfo.width * fontInfo.scale);
|
||||||
|
|
||||||
// store cached glyph
|
font.cachedGlyphs[_codePoint] = glyphInfo;
|
||||||
font.cachedGlyphs[_codePoint] = glyphInfo;
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -737,18 +724,18 @@ const GlyphInfo* FontManager::getGlyphInfo(FontHandle _handle, CodePoint _codePo
|
||||||
{
|
{
|
||||||
const GlyphHashMap& cachedGlyphs = m_cachedFonts[_handle.idx].cachedGlyphs;
|
const GlyphHashMap& cachedGlyphs = m_cachedFonts[_handle.idx].cachedGlyphs;
|
||||||
GlyphHashMap::const_iterator it = cachedGlyphs.find(_codePoint);
|
GlyphHashMap::const_iterator it = cachedGlyphs.find(_codePoint);
|
||||||
|
|
||||||
if (it == cachedGlyphs.end() )
|
if (it == cachedGlyphs.end() )
|
||||||
{
|
{
|
||||||
if (preloadGlyph(_handle, _codePoint) )
|
if (!preloadGlyph(_handle, _codePoint) )
|
||||||
{
|
|
||||||
it = cachedGlyphs.find(_codePoint);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it = cachedGlyphs.find(_codePoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BX_CHECK(it != cachedGlyphs.end(), "Failed to preload glyph.");
|
||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue