mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-11-01 08:25:18 +01:00
use I4 instead of RGBA8 for fonts (much less memory)
This commit is contained in:
parent
09c3376827
commit
66da7346b9
@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
#include "FreeTypeGX.h"
|
#include "FreeTypeGX.h"
|
||||||
|
|
||||||
|
#define ALIGN8(x) (((x) + 7) & ~7)
|
||||||
|
|
||||||
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. */
|
||||||
@ -233,27 +235,30 @@ ftgxCharData *FreeTypeGX::cacheGlyphData(wchar_t charCode)
|
|||||||
FT_UInt gIndex;
|
FT_UInt gIndex;
|
||||||
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, (FT_ULong) charCode);
|
||||||
if (!FT_Load_Glyph(ftFace, gIndex, FT_LOAD_DEFAULT | FT_LOAD_RENDER ))
|
if (gIndex != 0 && FT_Load_Glyph(ftFace, gIndex, FT_LOAD_DEFAULT | FT_LOAD_RENDER) == 0)
|
||||||
{
|
{
|
||||||
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 = ALIGN8(glyphBitmap->width);
|
||||||
textureHeight = adjustTextureHeight(glyphBitmap->rows);
|
textureHeight = ALIGN8(glyphBitmap->rows);
|
||||||
|
if(textureWidth == 0)
|
||||||
|
textureWidth = 8;
|
||||||
|
if(textureHeight == 0)
|
||||||
|
textureHeight = 8;
|
||||||
|
|
||||||
|
this->fontData[charCode].renderOffsetX = (int16_t) ftFace->glyph->bitmap_left;
|
||||||
|
this->fontData[charCode].glyphAdvanceX = (uint16_t) (ftFace->glyph->advance.x >> 6);
|
||||||
|
this->fontData[charCode].glyphIndex = (uint32_t) gIndex;
|
||||||
|
this->fontData[charCode].textureWidth = (uint16_t) textureWidth;
|
||||||
|
this->fontData[charCode].textureHeight = (uint16_t) textureHeight;
|
||||||
|
this->fontData[charCode].renderOffsetY = (int16_t) ftFace->glyph->bitmap_top;
|
||||||
|
this->fontData[charCode].renderOffsetMax = (int16_t) ftFace->glyph->bitmap_top;
|
||||||
|
this->fontData[charCode].renderOffsetMin = (int16_t) glyphBitmap->rows - ftFace->glyph->bitmap_top;
|
||||||
|
this->fontData[charCode].glyphDataTexture = NULL;
|
||||||
|
|
||||||
this->fontData[charCode] = (ftgxCharData){
|
|
||||||
ftSlot->bitmap_left,
|
|
||||||
ftSlot->advance.x >> 6,
|
|
||||||
gIndex,
|
|
||||||
textureWidth,
|
|
||||||
textureHeight,
|
|
||||||
ftSlot->bitmap_top,
|
|
||||||
ftSlot->bitmap_top,
|
|
||||||
glyphBitmap->rows - ftSlot->bitmap_top,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
this->loadGlyphData(glyphBitmap, &this->fontData[charCode]);
|
this->loadGlyphData(glyphBitmap, &this->fontData[charCode]);
|
||||||
|
|
||||||
return &this->fontData[charCode];
|
return &this->fontData[charCode];
|
||||||
@ -295,31 +300,38 @@ uint16_t FreeTypeGX::cacheGlyphDataComplete()
|
|||||||
*/
|
*/
|
||||||
void FreeTypeGX::loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData)
|
void FreeTypeGX::loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData)
|
||||||
{
|
{
|
||||||
int length = charData->textureWidth * charData->textureHeight * 4;
|
int glyphSize = (charData->textureWidth * charData->textureHeight) >> 1;
|
||||||
|
|
||||||
uint8_t * glyphData = (uint8_t *) memalign(32, length);
|
uint8_t *glyphData = (uint8_t *) memalign(32, glyphSize);
|
||||||
if(!glyphData)
|
memset(glyphData, 0x00, glyphSize);
|
||||||
return;
|
|
||||||
|
|
||||||
memset(glyphData, 0x00, length);
|
|
||||||
|
|
||||||
uint8_t *src = (uint8_t *)bmp->buffer;
|
uint8_t *src = (uint8_t *)bmp->buffer;
|
||||||
uint32_t offset;
|
uint8_t *dst = glyphData;
|
||||||
|
int32_t pos, x1, y1, x, y;
|
||||||
|
|
||||||
for (int imagePosY = 0; imagePosY < bmp->rows; ++imagePosY)
|
for(y1 = 0; y1 < bmp->rows; y1 += 8)
|
||||||
{
|
{
|
||||||
for (int imagePosX = 0; imagePosX < bmp->width; ++imagePosX)
|
for(x1 = 0; x1 < bmp->width; x1 += 8)
|
||||||
{
|
{
|
||||||
offset = ((((imagePosY >> 2) * (charData->textureWidth >> 2) + (imagePosX >> 2)) << 5) + ((imagePosY & 3) << 2) + (imagePosX & 3)) << 1;
|
for(y = y1; y < (y1 + 8); y++)
|
||||||
glyphData[offset] = *src;
|
{
|
||||||
glyphData[offset+1] = *src;
|
for(x = x1; x < (x1 + 8); x += 2, dst++)
|
||||||
glyphData[offset+32] = *src;
|
{
|
||||||
glyphData[offset+33] = *src;
|
if(x >= bmp->width || y >= bmp->rows)
|
||||||
++src;
|
continue;
|
||||||
|
|
||||||
|
pos = y * bmp->width + x;
|
||||||
|
*dst = (src[pos] & 0xF0);
|
||||||
|
|
||||||
|
if(x+1 < bmp->width)
|
||||||
|
*dst |= (src[pos + 1] >> 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DCFlushRange(glyphData, length);
|
}
|
||||||
charData->glyphDataTexture = (uint32_t *) glyphData;
|
}
|
||||||
|
|
||||||
|
DCFlushRange(glyphData, glyphSize);
|
||||||
|
charData->glyphDataTexture = glyphData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -430,7 +442,7 @@ uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color
|
|||||||
x_pos += pairDelta.x >> 6;
|
x_pos += pairDelta.x >> 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
GX_InitTexObj(&glyphTexture, glyphData->glyphDataTexture, glyphData->textureWidth, glyphData->textureHeight, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
GX_InitTexObj(&glyphTexture, glyphData->glyphDataTexture, glyphData->textureWidth, glyphData->textureHeight, GX_TF_I4, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||||
this->copyTextureToFramebuffer(&glyphTexture, glyphData->textureWidth, glyphData->textureHeight, x_pos + glyphData->renderOffsetX + x_offset, y - glyphData->renderOffsetY + y_offset, color);
|
this->copyTextureToFramebuffer(&glyphTexture, glyphData->textureWidth, glyphData->textureHeight, x_pos + glyphData->renderOffsetX + x_offset, y - glyphData->renderOffsetY + y_offset, color);
|
||||||
|
|
||||||
x_pos += glyphData->glyphAdvanceX;
|
x_pos += glyphData->glyphAdvanceX;
|
||||||
|
@ -51,7 +51,7 @@ typedef struct ftgxCharData_ {
|
|||||||
int16_t renderOffsetMax; /**< Texture Y axis bearing maximum value. */
|
int16_t renderOffsetMax; /**< Texture Y axis bearing maximum value. */
|
||||||
int16_t renderOffsetMin; /**< Texture Y axis bearing minimum value. */
|
int16_t renderOffsetMin; /**< Texture Y axis bearing minimum value. */
|
||||||
|
|
||||||
uint32_t* glyphDataTexture; /**< Glyph texture bitmap data buffer. */
|
uint8_t* glyphDataTexture; /**< Glyph texture bitmap data buffer. */
|
||||||
} ftgxCharData;
|
} ftgxCharData;
|
||||||
|
|
||||||
/*! \struct ftgxDataOffset_
|
/*! \struct ftgxDataOffset_
|
||||||
|
Loading…
Reference in New Issue
Block a user