|
@@ -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 y = -bitmap->top;
|
|
|
|
|
- int32_t w = bitmap->bitmap.width;
|
|
|
|
|
- int32_t h = bitmap->bitmap.rows;
|
|
|
|
|
|
|
+ int32_t xx = bitmap->left;
|
|
|
|
|
+ int32_t yy = -bitmap->top;
|
|
|
|
|
+ int32_t ww = bitmap->bitmap.width;
|
|
|
|
|
+ int32_t hh = bitmap->bitmap.rows;
|
|
|
|
|
|
|
|
- _glyphInfo.offset_x = (float) x;
|
|
|
|
|
- _glyphInfo.offset_y = (float) y;
|
|
|
|
|
- _glyphInfo.width = (float) w;
|
|
|
|
|
- _glyphInfo.height = (float) h;
|
|
|
|
|
|
|
+ _glyphInfo.offset_x = (float) xx;
|
|
|
|
|
+ _glyphInfo.offset_y = (float) yy;
|
|
|
|
|
+ _glyphInfo.width = (float) ww;
|
|
|
|
|
+ _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,
|
|
|
|
|
- bitmap->bitmap.buffer + (ii * stride) * charsize, w * charsize * depth);
|
|
|
|
|
|
|
+ memcpy(out, input, pitch);
|
|
|
|
|
+
|
|
|
|
|
+ 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)
|
|
|
|
|
- {
|
|
|
|
|
- dh = 2;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ uint32_t nw = ww + dw * 2;
|
|
|
|
|
+ uint32_t nh = hh + 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_y -= (float) dh;
|
|
|
|
|
- _glyphInfo.width = (float) nw;
|
|
|
|
|
- _glyphInfo.height = (float) nh;
|
|
|
|
|
|
|
+ _glyphInfo.offset_x -= (float)dw;
|
|
|
|
|
+ _glyphInfo.offset_y -= (float)dh;
|
|
|
|
|
+ _glyphInfo.width = (float)nw;
|
|
|
|
|
+ _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;
|
|
|
|
|
- m_cachedFonts[fontIdx].fontInfo = ttf->getFontInfo();
|
|
|
|
|
- m_cachedFonts[fontIdx].fontInfo.fontType = _fontType;
|
|
|
|
|
- m_cachedFonts[fontIdx].fontInfo.pixelSize = _pixelSize;
|
|
|
|
|
- m_cachedFonts[fontIdx].cachedGlyphs.clear();
|
|
|
|
|
- m_cachedFonts[fontIdx].masterFontHandle.idx = bx::HandleAlloc::invalid;
|
|
|
|
|
- FontHandle ret = {fontIdx};
|
|
|
|
|
- return ret;
|
|
|
|
|
|
|
+ CachedFont& font = m_cachedFonts[fontIdx];
|
|
|
|
|
+ font.trueTypeFont = ttf;
|
|
|
|
|
+ font.fontInfo = ttf->getFontInfo();
|
|
|
|
|
+ font.fontInfo.fontType = _fontType;
|
|
|
|
|
+ font.fontInfo.pixelSize = _pixelSize;
|
|
|
|
|
+ font.cachedGlyphs.clear();
|
|
|
|
|
+ font.masterFontHandle.idx = bx::HandleAlloc::invalid;
|
|
|
|
|
+
|
|
|
|
|
+ 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];
|
|
|
|
|
- FontInfo& fontInfo = font.fontInfo;
|
|
|
|
|
|
|
+ CachedFont& baseFont = m_cachedFonts[_baseFontHandle.idx];
|
|
|
|
|
+ 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;
|
|
|
|
|
- m_cachedFonts[fontIdx].trueTypeFont = NULL;
|
|
|
|
|
- m_cachedFonts[fontIdx].masterFontHandle = _baseFontHandle;
|
|
|
|
|
- FontHandle ret = {fontIdx};
|
|
|
|
|
- return ret;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ CachedFont& font = m_cachedFonts[fontIdx];
|
|
|
|
|
+ font.cachedGlyphs.clear();
|
|
|
|
|
+ font.fontInfo = newFontInfo;
|
|
|
|
|
+ font.trueTypeFont = NULL;
|
|
|
|
|
+ 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;
|
|
|
|
|
- m_cachedFonts[_handle.idx].trueTypeFont = NULL;
|
|
|
|
|
|
|
+ delete font.trueTypeFont;
|
|
|
|
|
+ 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 (font.trueTypeFont != NULL)
|
|
|
|
|
|
|
+ if (NULL == font.trueTypeFont)
|
|
|
|
|
+ {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for (uint32_t ii = 0, end = wcslen(_string); ii < end; ++ii)
|
|
|
{
|
|
{
|
|
|
- //parse string
|
|
|
|
|
- for (uint32_t ii = 0, end = wcslen(_string); ii < end; ++ii)
|
|
|
|
|
|
|
+ CodePoint codePoint = _string[ii];
|
|
|
|
|
+ if (!preloadGlyph(_handle, codePoint) )
|
|
|
{
|
|
{
|
|
|
- //if glyph cached, continue
|
|
|
|
|
- CodePoint codePoint = _string[ii];
|
|
|
|
|
- if (!preloadGlyph(_handle, codePoint) )
|
|
|
|
|
- {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- return true;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- 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 (font.trueTypeFont != NULL)
|
|
|
|
|
|
|
+ if (NULL != font.trueTypeFont)
|
|
|
{
|
|
{
|
|
|
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
|
|
|
|
|
- if (font.masterFontHandle.idx != bgfx::invalidHandle)
|
|
|
|
|
- {
|
|
|
|
|
- if (preloadGlyph(font.masterFontHandle, _codePoint) )
|
|
|
|
|
- {
|
|
|
|
|
- const GlyphInfo* glyph = getGlyphInfo(font.masterFontHandle, _codePoint);
|
|
|
|
|
-
|
|
|
|
|
- GlyphInfo glyphInfo = *glyph;
|
|
|
|
|
- glyphInfo.advance_x = (glyphInfo.advance_x * fontInfo.scale);
|
|
|
|
|
- glyphInfo.advance_y = (glyphInfo.advance_y * fontInfo.scale);
|
|
|
|
|
- glyphInfo.offset_x = (glyphInfo.offset_x * fontInfo.scale);
|
|
|
|
|
- glyphInfo.offset_y = (glyphInfo.offset_y * fontInfo.scale);
|
|
|
|
|
- glyphInfo.height = (glyphInfo.height * fontInfo.scale);
|
|
|
|
|
- glyphInfo.width = (glyphInfo.width * fontInfo.scale);
|
|
|
|
|
-
|
|
|
|
|
- // store cached glyph
|
|
|
|
|
- font.cachedGlyphs[_codePoint] = glyphInfo;
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const GlyphInfo* glyph = getGlyphInfo(font.masterFontHandle, _codePoint);
|
|
|
|
|
+
|
|
|
|
|
+ GlyphInfo glyphInfo = *glyph;
|
|
|
|
|
+ glyphInfo.advance_x = (glyphInfo.advance_x * fontInfo.scale);
|
|
|
|
|
+ glyphInfo.advance_y = (glyphInfo.advance_y * fontInfo.scale);
|
|
|
|
|
+ glyphInfo.offset_x = (glyphInfo.offset_x * fontInfo.scale);
|
|
|
|
|
+ glyphInfo.offset_y = (glyphInfo.offset_y * fontInfo.scale);
|
|
|
|
|
+ glyphInfo.height = (glyphInfo.height * fontInfo.scale);
|
|
|
|
|
+ glyphInfo.width = (glyphInfo.width * fontInfo.scale);
|
|
|
|
|
+
|
|
|
|
|
+ font.cachedGlyphs[_codePoint] = glyphInfo;
|
|
|
|
|
+ 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) )
|
|
|
|
|
- {
|
|
|
|
|
- it = cachedGlyphs.find(_codePoint);
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
|
|
+ if (!preloadGlyph(_handle, _codePoint) )
|
|
|
{
|
|
{
|
|
|
return NULL;
|
|
return NULL;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ it = cachedGlyphs.find(_codePoint);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ BX_CHECK(it != cachedGlyphs.end(), "Failed to preload glyph.");
|
|
|
return &it->second;
|
|
return &it->second;
|
|
|
}
|
|
}
|
|
|
|
|
|