This commit is contained in:
dborth 2010-06-29 18:55:56 +00:00
parent a7a6b41e60
commit 4f424661b7

View File

@ -22,6 +22,8 @@
#include "FreeTypeGX.h" #include "FreeTypeGX.h"
#define EXPLODE_UINT8_TO_UINT32(x) (x << 24) | (x << 16) | (x << 8) | x
static FT_Library ftLibrary; /**< FreeType FT_Library instance. */ static FT_Library ftLibrary; /**< FreeType FT_Library instance. */
static FT_Face ftFace; /**< FreeType reusable FT_Face typographic object. */ static FT_Face ftFace; /**< FreeType reusable FT_Face typographic object. */
static FT_GlyphSlot ftSlot; /**< FreeType reusable FT_GlyphSlot glyph container object. */ static FT_GlyphSlot ftSlot; /**< FreeType reusable FT_GlyphSlot glyph container object. */
@ -72,7 +74,7 @@ void ClearFontData()
wchar_t* charToWideChar(const char* strChar) wchar_t* charToWideChar(const char* strChar)
{ {
wchar_t *strWChar = new(std::nothrow) wchar_t[strlen(strChar) + 1]; wchar_t *strWChar = new wchar_t[strlen(strChar) + 1];
if(!strWChar) if(!strWChar)
return NULL; return NULL;
@ -82,8 +84,9 @@ wchar_t* charToWideChar(const char* strChar)
strWChar[bt] = (wchar_t)'\0'; strWChar[bt] = (wchar_t)'\0';
return strWChar; return strWChar;
} }
wchar_t *tempDest = strWChar; wchar_t *tempDest = strWChar;
while ((*tempDest++ = *strChar++)); while((*tempDest++ = *strChar++));
return strWChar; return strWChar;
} }
@ -274,10 +277,10 @@ ftgxCharData *FreeTypeGX::cacheGlyphData(wchar_t charCode)
uint16_t textureWidth = 0, textureHeight = 0; uint16_t textureWidth = 0, textureHeight = 0;
gIndex = FT_Get_Char_Index( ftFace, charCode ); gIndex = FT_Get_Char_Index( ftFace, charCode );
if (!FT_Load_Glyph(ftFace, gIndex, FT_LOAD_DEFAULT )) { if (!FT_Load_Glyph(ftFace, gIndex, FT_LOAD_DEFAULT | FT_LOAD_RENDER ))
FT_Render_Glyph( ftSlot, FT_RENDER_MODE_NORMAL ); {
if(ftSlot->format == FT_GLYPH_FORMAT_BITMAP)
if(ftSlot->format == FT_GLYPH_FORMAT_BITMAP) { {
FT_Bitmap *glyphBitmap = &ftSlot->bitmap; FT_Bitmap *glyphBitmap = &ftSlot->bitmap;
textureWidth = adjustTextureWidth(glyphBitmap->width); textureWidth = adjustTextureWidth(glyphBitmap->width);
@ -336,15 +339,17 @@ void FreeTypeGX::loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData)
uint32_t *glyphData = (uint32_t *)memalign(32, charData->textureWidth * charData->textureHeight * 4); uint32_t *glyphData = (uint32_t *)memalign(32, charData->textureWidth * charData->textureHeight * 4);
memset(glyphData, 0x00, charData->textureWidth * charData->textureHeight * 4); memset(glyphData, 0x00, charData->textureWidth * charData->textureHeight * 4);
uint32_t bmprows = bmp->rows; uint8_t *src = (uint8_t *)bmp->buffer;
uint32_t bmpwid = bmp->width; uint32_t *dest = glyphData, *ptr = dest;
for (uint32_t imagePosY = 0; imagePosY < bmprows; imagePosY++)
for (int imagePosY = 0; imagePosY < bmp->rows; imagePosY++)
{ {
for (uint32_t imagePosX = 0; imagePosX < bmpwid; imagePosX++) for (int imagePosX = 0; imagePosX < bmp->width; imagePosX++)
{ {
uint32_t pixel = (uint32_t) bmp->buffer[imagePosY * bmpwid + imagePosX]; *ptr++ = EXPLODE_UINT8_TO_UINT32(*src);
glyphData[imagePosY * charData->textureWidth + imagePosX] = 0x00000000 | (pixel << 24) | (pixel << 16) | (pixel << 8) | pixel; src++;
} }
ptr = dest += charData->textureWidth;
} }
charData->glyphDataTexture = convertBufferToRGBA8(glyphData, charData->textureWidth, charData->textureHeight); charData->glyphDataTexture = convertBufferToRGBA8(glyphData, charData->textureWidth, charData->textureHeight);
free(glyphData); free(glyphData);
@ -421,7 +426,6 @@ int16_t FreeTypeGX::getStyleOffsetHeight(ftgxDataOffset *offset, uint16_t format
*/ */
uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color, uint16_t textStyle) uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color, uint16_t textStyle)
{ {
uint32_t strLength = wcslen(text);
uint16_t x_pos = x, printed = 0; uint16_t x_pos = x, printed = 0;
uint16_t x_offset = 0, y_offset = 0; uint16_t x_offset = 0, y_offset = 0;
GXTexObj glyphTexture; GXTexObj glyphTexture;
@ -438,12 +442,11 @@ uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color
y_offset = this->getStyleOffsetHeight(&offset, textStyle); y_offset = this->getStyleOffsetHeight(&offset, textStyle);
} }
std::map<wchar_t, ftgxCharData>::iterator thisEnd =this->fontData.end(); int i = 0;
while (text[i])
for (uint32_t i = 0; i < strLength; ++i)
{ {
ftgxCharData* glyphData = NULL; ftgxCharData* glyphData = NULL;
if( this->fontData.find(text[i]) != thisEnd) if (this->fontData.find(text[i]) != this->fontData.end())
{ {
glyphData = &this->fontData[text[i]]; glyphData = &this->fontData[text[i]];
} }
@ -452,11 +455,11 @@ uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color
glyphData = this->cacheGlyphData(text[i]); glyphData = this->cacheGlyphData(text[i]);
} }
if(glyphData != NULL) if (glyphData != NULL)
{ {
if(this->ftKerningEnabled && i) if (this->ftKerningEnabled && i)
{ {
FT_Get_Kerning( ftFace, this->fontData[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta ); FT_Get_Kerning(ftFace, this->fontData[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta);
x_pos += pairDelta.x >> 6; x_pos += pairDelta.x >> 6;
} }
@ -466,6 +469,7 @@ uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color
x_pos += glyphData->glyphAdvanceX; x_pos += glyphData->glyphAdvanceX;
++printed; ++printed;
} }
++i;
} }
if(textStyle & FTGX_STYLE_MASK) if(textStyle & FTGX_STYLE_MASK)
@ -507,16 +511,14 @@ void FreeTypeGX::drawTextFeature(int16_t x, int16_t y, uint16_t width, ftgxDataO
*/ */
uint16_t FreeTypeGX::getWidth(wchar_t *text) uint16_t FreeTypeGX::getWidth(wchar_t *text)
{ {
FT_Vector pairDelta;
uint32_t strLength = wcslen(text);
uint16_t strWidth = 0; uint16_t strWidth = 0;
FT_Vector pairDelta;
std::map<wchar_t, ftgxCharData>::iterator thisEnd =this->fontData.end(); int i = 0;
while (text[i])
for (uint32_t i = 0; i < strLength; ++i)
{ {
ftgxCharData* glyphData = NULL; ftgxCharData* glyphData = NULL;
if(this->fontData.find(text[i]) != thisEnd) if (this->fontData.find(text[i]) != this->fontData.end())
{ {
glyphData = &this->fontData[text[i]]; glyphData = &this->fontData[text[i]];
} }
@ -525,15 +527,17 @@ uint16_t FreeTypeGX::getWidth(wchar_t *text)
glyphData = this->cacheGlyphData(text[i]); glyphData = this->cacheGlyphData(text[i]);
} }
if(glyphData != NULL) if (glyphData != NULL)
{ {
if(this->ftKerningEnabled && (i > 0)) if (this->ftKerningEnabled && (i > 0))
{ {
FT_Get_Kerning(ftFace, this->fontData[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta); FT_Get_Kerning(ftFace, this->fontData[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta);
strWidth += pairDelta.x >> 6; strWidth += pairDelta.x >> 6;
} }
strWidth += glyphData->glyphAdvanceX; strWidth += glyphData->glyphAdvanceX;
} }
++i;
} }
return strWidth; return strWidth;
} }
@ -584,15 +588,13 @@ uint16_t FreeTypeGX::getHeight(wchar_t const *text)
*/ */
void FreeTypeGX::getOffset(wchar_t *text, ftgxDataOffset* offset) void FreeTypeGX::getOffset(wchar_t *text, ftgxDataOffset* offset)
{ {
uint32_t strLength = wcslen(text);
int16_t strMax = 0, strMin = 9999; int16_t strMax = 0, strMin = 9999;
std::map<wchar_t, ftgxCharData>::iterator thisEnd =this->fontData.end();
for (uint32_t i = 0; i < strLength; ++i) int i = 0;
while (text[i])
{ {
ftgxCharData* glyphData = NULL; ftgxCharData* glyphData = NULL;
if( this->fontData.find(text[i]) != thisEnd) if (this->fontData.find(text[i]) != this->fontData.end())
{ {
glyphData = &this->fontData[text[i]]; glyphData = &this->fontData[text[i]];
} }
@ -606,6 +608,7 @@ void FreeTypeGX::getOffset(wchar_t *text, ftgxDataOffset* offset)
strMax = glyphData->renderOffsetMax > strMax ? glyphData->renderOffsetMax : strMax; strMax = glyphData->renderOffsetMax > strMax ? glyphData->renderOffsetMax : strMax;
strMin = glyphData->renderOffsetMin < strMin ? glyphData->renderOffsetMin : strMin; strMin = glyphData->renderOffsetMin < strMin ? glyphData->renderOffsetMin : strMin;
} }
++i;
} }
offset->ascender = ftFace->size->metrics.ascender>>6; offset->ascender = ftFace->size->metrics.ascender>>6;
offset->descender = ftFace->size->metrics.descender>>6; offset->descender = ftFace->size->metrics.descender>>6;