mirror of
https://github.com/dborth/fceugx.git
synced 2025-01-05 21:38:17 +01:00
text alignment corrections
This commit is contained in:
parent
179f55ba26
commit
3180dd627b
@ -24,7 +24,7 @@
|
||||
|
||||
static FT_Library ftLibrary; /**< FreeType FT_Library instance. */
|
||||
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. */
|
||||
|
||||
FreeTypeGX *fontSystem[MAX_FONT_SIZE+1];
|
||||
|
||||
@ -81,7 +81,8 @@ wchar_t* charToWideChar(const char* strChar)
|
||||
* @param textureFormat Optional format (GX_TF_*) of the texture as defined by the libogc gx.h header file. If not specified default value is GX_TF_RGBA8.
|
||||
* @param vertexIndex Optional vertex format index (GX_VTXFMT*) of the glyph textures as defined by the libogc gx.h header file. If not specified default value is GX_VTXFMT1.
|
||||
*/
|
||||
FreeTypeGX::FreeTypeGX(FT_UInt pixelSize, uint8_t textureFormat, uint8_t vertexIndex) {
|
||||
FreeTypeGX::FreeTypeGX(FT_UInt pixelSize, uint8_t textureFormat, uint8_t vertexIndex)
|
||||
{
|
||||
this->textureFormat = textureFormat;
|
||||
this->setVertexFormat(vertexIndex);
|
||||
this->setCompatibilityMode(FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_PASSCLR | FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_NONE);
|
||||
@ -92,7 +93,8 @@ FreeTypeGX::FreeTypeGX(FT_UInt pixelSize, uint8_t textureFormat, uint8_t vertexI
|
||||
/**
|
||||
* Default destructor for the FreeTypeGX class.
|
||||
*/
|
||||
FreeTypeGX::~FreeTypeGX() {
|
||||
FreeTypeGX::~FreeTypeGX()
|
||||
{
|
||||
this->unloadFont();
|
||||
}
|
||||
|
||||
@ -105,9 +107,9 @@ FreeTypeGX::~FreeTypeGX() {
|
||||
*
|
||||
* @param vertexIndex Vertex format index (GX_VTXFMT*) of the glyph textures as defined by the libogc gx.h header file.
|
||||
*/
|
||||
void FreeTypeGX::setVertexFormat(uint8_t vertexIndex) {
|
||||
void FreeTypeGX::setVertexFormat(uint8_t vertexIndex)
|
||||
{
|
||||
this->vertexIndex = vertexIndex;
|
||||
|
||||
GX_SetVtxAttrFmt(this->vertexIndex, GX_VA_POS, GX_POS_XY, GX_S16, 0);
|
||||
GX_SetVtxAttrFmt(this->vertexIndex, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
||||
GX_SetVtxAttrFmt(this->vertexIndex, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||
@ -123,7 +125,8 @@ void FreeTypeGX::setVertexFormat(uint8_t vertexIndex) {
|
||||
*
|
||||
* @param compatibilityMode Compatibility descritor (FTGX_COMPATIBILITY_*) as defined in FreeTypeGX.h
|
||||
*/
|
||||
void FreeTypeGX::setCompatibilityMode(uint32_t compatibilityMode) {
|
||||
void FreeTypeGX::setCompatibilityMode(uint32_t compatibilityMode)
|
||||
{
|
||||
this->compatibilityMode = compatibilityMode;
|
||||
}
|
||||
|
||||
@ -133,9 +136,12 @@ void FreeTypeGX::setCompatibilityMode(uint32_t compatibilityMode) {
|
||||
* This function calls the GX_SetTevOp and GX_SetVtxDesc functions with the compatibility parameters specified
|
||||
* in setCompatibilityMode.
|
||||
*/
|
||||
void FreeTypeGX::setDefaultMode() {
|
||||
if(this->compatibilityMode) {
|
||||
switch(this->compatibilityMode & 0x00FF) {
|
||||
void FreeTypeGX::setDefaultMode()
|
||||
{
|
||||
if(this->compatibilityMode)
|
||||
{
|
||||
switch(this->compatibilityMode & 0x00FF)
|
||||
{
|
||||
case FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_MODULATE:
|
||||
GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
|
||||
break;
|
||||
@ -155,7 +161,8 @@ void FreeTypeGX::setDefaultMode() {
|
||||
break;
|
||||
}
|
||||
|
||||
switch(this->compatibilityMode & 0xFF00) {
|
||||
switch(this->compatibilityMode & 0xFF00)
|
||||
{
|
||||
case FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_NONE:
|
||||
GX_SetVtxDesc(GX_VA_TEX0, GX_NONE);
|
||||
break;
|
||||
@ -179,14 +186,12 @@ void FreeTypeGX::setDefaultMode() {
|
||||
*
|
||||
* This routine clears all members of the font map structure and frees all allocated memory back to the system.
|
||||
*/
|
||||
void FreeTypeGX::unloadFont() {
|
||||
void FreeTypeGX::unloadFont()
|
||||
{
|
||||
if(this->fontData.size() == 0)
|
||||
return;
|
||||
|
||||
for( std::map<wchar_t, ftgxCharData>::iterator i = this->fontData.begin(); i != this->fontData.end(); i++) {
|
||||
for(std::map<wchar_t, ftgxCharData>::iterator i = this->fontData.begin(); i != this->fontData.end(); i++)
|
||||
free(i->second.glyphDataTexture);
|
||||
}
|
||||
|
||||
this->fontData.clear();
|
||||
}
|
||||
|
||||
@ -199,10 +204,12 @@ void FreeTypeGX::unloadFont() {
|
||||
* @param textureFormat The texture format to which the data is to be converted.
|
||||
* @return The correctly adjusted texture width.
|
||||
*/
|
||||
uint16_t FreeTypeGX::adjustTextureWidth(uint16_t textureWidth, uint8_t textureFormat) {
|
||||
uint16_t FreeTypeGX::adjustTextureWidth(uint16_t textureWidth, uint8_t textureFormat)
|
||||
{
|
||||
uint16_t alignment;
|
||||
|
||||
switch(textureFormat) {
|
||||
switch(textureFormat)
|
||||
{
|
||||
case GX_TF_I4: /* 8x8 Tiles - 4-bit Intensity */
|
||||
case GX_TF_I8: /* 8x4 Tiles - 8-bit Intensity */
|
||||
case GX_TF_IA4: /* 8x4 Tiles - 4-bit Intensity, , 4-bit Alpha */
|
||||
@ -218,7 +225,6 @@ uint16_t FreeTypeGX::adjustTextureWidth(uint16_t textureWidth, uint8_t textureFo
|
||||
break;
|
||||
}
|
||||
return textureWidth % alignment == 0 ? textureWidth : alignment + textureWidth - (textureWidth % alignment);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,10 +236,12 @@ uint16_t FreeTypeGX::adjustTextureWidth(uint16_t textureWidth, uint8_t textureFo
|
||||
* @param textureFormat The texture format to which the data is to be converted.
|
||||
* @return The correctly adjusted texture height.
|
||||
*/
|
||||
uint16_t FreeTypeGX::adjustTextureHeight(uint16_t textureHeight, uint8_t textureFormat) {
|
||||
uint16_t FreeTypeGX::adjustTextureHeight(uint16_t textureHeight, uint8_t textureFormat)
|
||||
{
|
||||
uint16_t alignment;
|
||||
|
||||
switch(textureFormat) {
|
||||
switch(textureFormat)
|
||||
{
|
||||
case GX_TF_I4: /* 8x8 Tiles - 4-bit Intensity */
|
||||
alignment = 8;
|
||||
break;
|
||||
@ -249,7 +257,6 @@ uint16_t FreeTypeGX::adjustTextureHeight(uint16_t textureHeight, uint8_t texture
|
||||
break;
|
||||
}
|
||||
return textureHeight % alignment == 0 ? textureHeight : alignment + textureHeight - (textureHeight % alignment);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -261,7 +268,8 @@ uint16_t FreeTypeGX::adjustTextureHeight(uint16_t textureHeight, uint8_t texture
|
||||
* @param charCode The requested glyph's character code.
|
||||
* @return A pointer to the allocated font structure.
|
||||
*/
|
||||
ftgxCharData *FreeTypeGX::cacheGlyphData(wchar_t charCode) {
|
||||
ftgxCharData *FreeTypeGX::cacheGlyphData(wchar_t charCode)
|
||||
{
|
||||
FT_UInt gIndex;
|
||||
uint16_t textureWidth = 0, textureHeight = 0;
|
||||
|
||||
@ -276,13 +284,14 @@ ftgxCharData *FreeTypeGX::cacheGlyphData(wchar_t charCode) {
|
||||
textureHeight = adjustTextureHeight(glyphBitmap->rows, this->textureFormat);
|
||||
|
||||
this->fontData[charCode] = (ftgxCharData){
|
||||
ftSlot->bitmap_left,
|
||||
ftSlot->advance.x >> 6,
|
||||
gIndex,
|
||||
textureWidth,
|
||||
textureHeight,
|
||||
ftSlot->bitmap_top,
|
||||
ftSlot->bitmap_top,
|
||||
textureHeight - ftSlot->bitmap_top,
|
||||
glyphBitmap->rows - ftSlot->bitmap_top,
|
||||
NULL
|
||||
};
|
||||
this->loadGlyphData(glyphBitmap, &this->fontData[charCode]);
|
||||
@ -290,7 +299,6 @@ ftgxCharData *FreeTypeGX::cacheGlyphData(wchar_t charCode) {
|
||||
return &this->fontData[charCode];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -300,19 +308,17 @@ ftgxCharData *FreeTypeGX::cacheGlyphData(wchar_t charCode) {
|
||||
* This routine locates each character in the configured font face and renders the glyph's bitmap.
|
||||
* Each bitmap and relevant information is loaded into its own quickly addressible structure within an instance-specific map.
|
||||
*/
|
||||
uint16_t FreeTypeGX::cacheGlyphDataComplete() {
|
||||
uint16_t FreeTypeGX::cacheGlyphDataComplete()
|
||||
{
|
||||
uint16_t i = 0;
|
||||
FT_UInt gIndex;
|
||||
FT_ULong charCode = FT_Get_First_Char( ftFace, &gIndex );
|
||||
while ( gIndex != 0 ) {
|
||||
|
||||
if(this->cacheGlyphData(charCode) != NULL) {
|
||||
while ( gIndex != 0 )
|
||||
{
|
||||
if(this->cacheGlyphData(charCode) != NULL)
|
||||
i++;
|
||||
}
|
||||
|
||||
charCode = FT_Get_Next_Char( ftFace, charCode, &gIndex );
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
@ -325,19 +331,22 @@ uint16_t FreeTypeGX::cacheGlyphDataComplete() {
|
||||
* @param bmp A pointer to the most recently rendered glyph's bitmap.
|
||||
* @param charData A pointer to an allocated ftgxCharData structure whose data represent that of the last rendered glyph.
|
||||
*/
|
||||
void FreeTypeGX::loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData) {
|
||||
|
||||
void FreeTypeGX::loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData)
|
||||
{
|
||||
uint32_t *glyphData = (uint32_t *)memalign(32, charData->textureWidth * charData->textureHeight * 4);
|
||||
memset(glyphData, 0x00, charData->textureWidth * charData->textureHeight * 4);
|
||||
|
||||
for (uint16_t imagePosY = 0; imagePosY < bmp->rows; imagePosY++) {
|
||||
for (uint16_t imagePosX = 0; imagePosX < bmp->width; imagePosX++) {
|
||||
for (uint16_t imagePosY = 0; imagePosY < bmp->rows; imagePosY++)
|
||||
{
|
||||
for (uint16_t imagePosX = 0; imagePosX < bmp->width; imagePosX++)
|
||||
{
|
||||
uint32_t pixel = (uint32_t) bmp->buffer[imagePosY * bmp->width + imagePosX];
|
||||
glyphData[imagePosY * charData->textureWidth + imagePosX] = 0x00000000 | (pixel << 24) | (pixel << 16) | (pixel << 8) | pixel;
|
||||
}
|
||||
}
|
||||
|
||||
switch(this->textureFormat) {
|
||||
switch(this->textureFormat)
|
||||
{
|
||||
case GX_TF_I4:
|
||||
charData->glyphDataTexture = Metaphrasis::convertBufferToI4(glyphData, charData->textureWidth, charData->textureHeight);
|
||||
break;
|
||||
@ -361,7 +370,6 @@ void FreeTypeGX::loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData) {
|
||||
charData->glyphDataTexture = Metaphrasis::convertBufferToRGBA8(glyphData, charData->textureWidth, charData->textureHeight);
|
||||
break;
|
||||
}
|
||||
|
||||
free(glyphData);
|
||||
}
|
||||
|
||||
@ -373,18 +381,14 @@ void FreeTypeGX::loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData) {
|
||||
* @param width Current pixel width of the string.
|
||||
* @param format Positional format of the string.
|
||||
*/
|
||||
uint16_t FreeTypeGX::getStyleOffsetWidth(uint16_t width, uint16_t format) {
|
||||
|
||||
if (format & FTGX_JUSTIFY_LEFT ) {
|
||||
int16_t FreeTypeGX::getStyleOffsetWidth(uint16_t width, uint16_t format)
|
||||
{
|
||||
if (format & FTGX_JUSTIFY_LEFT)
|
||||
return 0;
|
||||
}
|
||||
else if (format & FTGX_JUSTIFY_CENTER ) {
|
||||
return width >> 1;
|
||||
}
|
||||
else if (format & FTGX_JUSTIFY_RIGHT ) {
|
||||
return width;
|
||||
}
|
||||
|
||||
else if (format & FTGX_JUSTIFY_CENTER)
|
||||
return -(width >> 1);
|
||||
else if (format & FTGX_JUSTIFY_RIGHT)
|
||||
return -width;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -396,17 +400,32 @@ uint16_t FreeTypeGX::getStyleOffsetWidth(uint16_t width, uint16_t format) {
|
||||
* @param offset Current pixel offset data of the string.
|
||||
* @param format Positional format of the string.
|
||||
*/
|
||||
uint16_t FreeTypeGX::getStyleOffsetHeight(ftgxDataOffset offset, uint16_t format) {
|
||||
if (format & FTGX_ALIGN_TOP ) {
|
||||
return -offset.max;
|
||||
}
|
||||
else if (format & FTGX_ALIGN_MIDDLE ) {
|
||||
return -offset.max;
|
||||
}
|
||||
else if (format & FTGX_ALIGN_BOTTOM ) {
|
||||
return offset.min;
|
||||
}
|
||||
int16_t FreeTypeGX::getStyleOffsetHeight(ftgxDataOffset *offset, uint16_t format)
|
||||
{
|
||||
switch(format & FTGX_ALIGN_MASK)
|
||||
{
|
||||
case FTGX_ALIGN_TOP:
|
||||
return offset->ascender;
|
||||
|
||||
default:
|
||||
case FTGX_ALIGN_MIDDLE:
|
||||
return (offset->ascender + offset->descender + 1) >> 1;
|
||||
|
||||
case FTGX_ALIGN_BOTTOM:
|
||||
return offset->descender;
|
||||
|
||||
case FTGX_ALIGN_BASELINE:
|
||||
return 0;
|
||||
|
||||
case FTGX_ALIGN_GLYPH_TOP:
|
||||
return offset->max;
|
||||
|
||||
case FTGX_ALIGN_GLYPH_MIDDLE:
|
||||
return (offset->max + offset->min + 1) >> 1;
|
||||
|
||||
case FTGX_ALIGN_GLYPH_BOTTOM:
|
||||
return offset->min;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -423,47 +442,57 @@ uint16_t FreeTypeGX::getStyleOffsetHeight(ftgxDataOffset offset, uint16_t format
|
||||
* @param textStyle Flags which specify any styling which should be applied to the rendered string.
|
||||
* @return The number of characters printed.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
uint16_t strLength = wcslen(text);
|
||||
uint16_t x_pos = x, printed = 0;
|
||||
uint16_t x_offset = 0, y_offset = 0;
|
||||
GXTexObj glyphTexture;
|
||||
FT_Vector pairDelta;
|
||||
ftgxDataOffset offset;
|
||||
|
||||
if(textStyle & 0x000F) {
|
||||
if(textStyle & FTGX_JUSTIFY_MASK)
|
||||
{
|
||||
x_offset = this->getStyleOffsetWidth(this->getWidth(text), textStyle);
|
||||
}
|
||||
if(textStyle & 0x00F0) {
|
||||
y_offset = this->getStyleOffsetHeight(this->getOffset(text), textStyle);
|
||||
if(textStyle & FTGX_ALIGN_MASK)
|
||||
{
|
||||
this->getOffset(text, &offset);
|
||||
y_offset = this->getStyleOffsetHeight(&offset, textStyle);
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < strLength; i++) {
|
||||
|
||||
for (uint16_t i = 0; i < strLength; i++)
|
||||
{
|
||||
ftgxCharData* glyphData = NULL;
|
||||
if( this->fontData.find(text[i]) != this->fontData.end() ) {
|
||||
if( this->fontData.find(text[i]) != this->fontData.end() )
|
||||
{
|
||||
glyphData = &this->fontData[text[i]];
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
glyphData = this->cacheGlyphData(text[i]);
|
||||
}
|
||||
|
||||
if(glyphData != NULL) {
|
||||
|
||||
if(this->ftKerningEnabled && i) {
|
||||
if(glyphData != NULL)
|
||||
{
|
||||
if(this->ftKerningEnabled && i)
|
||||
{
|
||||
FT_Get_Kerning( ftFace, this->fontData[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta );
|
||||
x_pos += pairDelta.x >> 6;
|
||||
}
|
||||
|
||||
GX_InitTexObj(&glyphTexture, glyphData->glyphDataTexture, glyphData->textureWidth, glyphData->textureHeight, this->textureFormat, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
this->copyTextureToFramebuffer(&glyphTexture, glyphData->textureWidth, glyphData->textureHeight, x_pos - 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;
|
||||
printed++;
|
||||
}
|
||||
}
|
||||
|
||||
if(textStyle & 0x0F00) {
|
||||
this->drawTextFeature(x - x_offset, y, this->getWidth(text), this->getOffset(text), textStyle, color);
|
||||
if(textStyle & FTGX_STYLE_MASK)
|
||||
{
|
||||
this->getOffset(text, &offset);
|
||||
this->drawTextFeature(x + x_offset, y + y_offset, this->getWidth(text), &offset, textStyle, color);
|
||||
}
|
||||
|
||||
return printed;
|
||||
@ -472,46 +501,20 @@ uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color
|
||||
/**
|
||||
* \overload
|
||||
*/
|
||||
uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t const *text, GXColor color, uint16_t textStyle) {
|
||||
uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t const *text, GXColor color, uint16_t textStyle)
|
||||
{
|
||||
return this->drawText(x, y, (wchar_t *)text, color, textStyle);
|
||||
}
|
||||
|
||||
void FreeTypeGX::drawTextFeature(int16_t x, int16_t y, uint16_t width, ftgxDataOffset offsetData, uint16_t format, GXColor color) {
|
||||
void FreeTypeGX::drawTextFeature(int16_t x, int16_t y, uint16_t width, ftgxDataOffset *offsetData, uint16_t format, GXColor color)
|
||||
{
|
||||
uint16_t featureHeight = this->ftPointSize >> 4 > 0 ? this->ftPointSize >> 4 : 1;
|
||||
|
||||
if (format & FTGX_STYLE_UNDERLINE ) {
|
||||
switch(format & 0x00F0) {
|
||||
case FTGX_ALIGN_TOP:
|
||||
this->copyFeatureToFramebuffer(width, featureHeight, x, y + offsetData.max + 1, color);
|
||||
break;
|
||||
case FTGX_ALIGN_MIDDLE:
|
||||
this->copyFeatureToFramebuffer(width, featureHeight, x, y + ((offsetData.max - offsetData.min) >> 1) + 1, color);
|
||||
break;
|
||||
case FTGX_ALIGN_BOTTOM:
|
||||
this->copyFeatureToFramebuffer(width, featureHeight, x, y - offsetData.min, color);
|
||||
break;
|
||||
default:
|
||||
this->copyFeatureToFramebuffer(width, featureHeight, x, y + 1, color);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (format & FTGX_STYLE_UNDERLINE)
|
||||
this->copyFeatureToFramebuffer(width, featureHeight, x, y + 1, color);
|
||||
|
||||
if (format & FTGX_STYLE_STRIKE ) {
|
||||
switch(format & 0x00F0) {
|
||||
case FTGX_ALIGN_TOP:
|
||||
this->copyFeatureToFramebuffer(width, featureHeight, x, y + ((offsetData.max + offsetData.min) >> 1), color);
|
||||
break;
|
||||
case FTGX_ALIGN_MIDDLE:
|
||||
this->copyFeatureToFramebuffer(width, featureHeight, x, y, color);
|
||||
break;
|
||||
case FTGX_ALIGN_BOTTOM:
|
||||
this->copyFeatureToFramebuffer(width, featureHeight, x, y - ((offsetData.max + offsetData.min) >> 1), color);
|
||||
break;
|
||||
default:
|
||||
this->copyFeatureToFramebuffer(width, featureHeight, x, y - ((offsetData.max - offsetData.min) >> 1), color);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (format & FTGX_STYLE_STRIKE)
|
||||
this->copyFeatureToFramebuffer(width, featureHeight, x, y - ((offsetData->max) >> 1), color);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -523,31 +526,35 @@ void FreeTypeGX::drawTextFeature(int16_t x, int16_t y, uint16_t width, ftgxDataO
|
||||
* @param text NULL terminated string to calculate.
|
||||
* @return The width of the text string in pixels.
|
||||
*/
|
||||
uint16_t FreeTypeGX::getWidth(wchar_t *text) {
|
||||
uint16_t FreeTypeGX::getWidth(wchar_t *text)
|
||||
{
|
||||
uint16_t strLength = wcslen(text);
|
||||
uint16_t strWidth = 0;
|
||||
FT_Vector pairDelta;
|
||||
|
||||
for (uint16_t i = 0; i < strLength; i++) {
|
||||
for (uint16_t i = 0; i < strLength; i++)
|
||||
{
|
||||
|
||||
ftgxCharData* glyphData = NULL;
|
||||
if( this->fontData.find(text[i]) != this->fontData.end() ) {
|
||||
if( this->fontData.find(text[i]) != this->fontData.end() )
|
||||
{
|
||||
glyphData = &this->fontData[text[i]];
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
glyphData = this->cacheGlyphData(text[i]);
|
||||
}
|
||||
|
||||
if(glyphData != NULL) {
|
||||
if(this->ftKerningEnabled && (i > 0)) {
|
||||
if(glyphData != NULL)
|
||||
{
|
||||
if(this->ftKerningEnabled && (i > 0))
|
||||
{
|
||||
FT_Get_Kerning( ftFace, this->fontData[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta );
|
||||
strWidth += pairDelta.x >> 6;
|
||||
}
|
||||
|
||||
strWidth += glyphData->glyphAdvanceX;
|
||||
}
|
||||
}
|
||||
|
||||
return strWidth;
|
||||
}
|
||||
|
||||
@ -555,7 +562,8 @@ uint16_t FreeTypeGX::getWidth(wchar_t *text) {
|
||||
*
|
||||
* \overload
|
||||
*/
|
||||
uint16_t FreeTypeGX::getWidth(wchar_t const *text) {
|
||||
uint16_t FreeTypeGX::getWidth(wchar_t const *text)
|
||||
{
|
||||
return this->getWidth((wchar_t *)text);
|
||||
}
|
||||
|
||||
@ -568,17 +576,19 @@ uint16_t FreeTypeGX::getWidth(wchar_t const *text) {
|
||||
* @param text NULL terminated string to calculate.
|
||||
* @return The height of the text string in pixels.
|
||||
*/
|
||||
uint16_t FreeTypeGX::getHeight(wchar_t *text) {
|
||||
ftgxDataOffset offset = this->getOffset(text);
|
||||
|
||||
return offset.max + offset.min;
|
||||
uint16_t FreeTypeGX::getHeight(wchar_t *text)
|
||||
{
|
||||
ftgxDataOffset offset;
|
||||
this->getOffset(text, &offset);
|
||||
return offset.max - offset.min;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* \overload
|
||||
*/
|
||||
uint16_t FreeTypeGX::getHeight(wchar_t const *text) {
|
||||
uint16_t FreeTypeGX::getHeight(wchar_t const *text)
|
||||
{
|
||||
return this->getHeight((wchar_t *)text);
|
||||
}
|
||||
|
||||
@ -589,37 +599,46 @@ uint16_t FreeTypeGX::getHeight(wchar_t const *text) {
|
||||
* pixel height below the font origin line and returns the values in an addressible structure.
|
||||
*
|
||||
* @param text NULL terminated string to calculate.
|
||||
* @return The max and min values above and below the font origin line.
|
||||
* @param offset returns the max and min values above and below the font origin line
|
||||
*
|
||||
*/
|
||||
ftgxDataOffset FreeTypeGX::getOffset(wchar_t *text) {
|
||||
void FreeTypeGX::getOffset(wchar_t *text, ftgxDataOffset* offset)
|
||||
{
|
||||
uint16_t strLength = wcslen(text);
|
||||
uint16_t strMax = 0, strMin = 0;
|
||||
int16_t strMax = 0, strMin = 9999;
|
||||
|
||||
for (uint16_t i = 0; i < strLength; i++) {
|
||||
for (uint16_t i = 0; i < strLength; i++)
|
||||
{
|
||||
|
||||
ftgxCharData* glyphData = NULL;
|
||||
if( this->fontData.find(text[i]) != this->fontData.end() ) {
|
||||
if( this->fontData.find(text[i]) != this->fontData.end() )
|
||||
{
|
||||
glyphData = &this->fontData[text[i]];
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
glyphData = this->cacheGlyphData(text[i]);
|
||||
}
|
||||
|
||||
if(glyphData != NULL) {
|
||||
if(glyphData != NULL)
|
||||
{
|
||||
strMax = glyphData->renderOffsetMax > strMax ? glyphData->renderOffsetMax : strMax;
|
||||
strMin = glyphData->renderOffsetMin > strMin ? glyphData->renderOffsetMin : strMin;
|
||||
strMin = glyphData->renderOffsetMin < strMin ? glyphData->renderOffsetMin : strMin;
|
||||
}
|
||||
}
|
||||
|
||||
return (ftgxDataOffset){strMax, strMin};
|
||||
offset->ascender = ftFace->size->metrics.ascender>>6;
|
||||
offset->descender = ftFace->size->metrics.descender>>6;
|
||||
offset->max = strMax;
|
||||
offset->min = strMin;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* \overload
|
||||
*/
|
||||
ftgxDataOffset FreeTypeGX::getOffset(wchar_t const *text) {
|
||||
return this->getOffset(text);
|
||||
void FreeTypeGX::getOffset(wchar_t const *text, ftgxDataOffset* offset)
|
||||
{
|
||||
this->getOffset(text, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -634,8 +653,8 @@ ftgxDataOffset FreeTypeGX::getOffset(wchar_t const *text) {
|
||||
* @param screenY The screen Y coordinate at which to output the rendered texture.
|
||||
* @param color Color to apply to the texture.
|
||||
*/
|
||||
void FreeTypeGX::copyTextureToFramebuffer(GXTexObj *texObj, f32 texWidth, f32 texHeight, int16_t screenX, int16_t screenY, GXColor color) {
|
||||
|
||||
void FreeTypeGX::copyTextureToFramebuffer(GXTexObj *texObj, f32 texWidth, f32 texHeight, int16_t screenX, int16_t screenY, GXColor color)
|
||||
{
|
||||
GX_LoadTexObj(texObj, GX_TEXMAP0);
|
||||
GX_InvalidateTexAll();
|
||||
|
||||
@ -643,21 +662,21 @@ void FreeTypeGX::copyTextureToFramebuffer(GXTexObj *texObj, f32 texWidth, f32 te
|
||||
GX_SetVtxDesc (GX_VA_TEX0, GX_DIRECT);
|
||||
|
||||
GX_Begin(GX_QUADS, this->vertexIndex, 4);
|
||||
GX_Position2s16(screenX, screenY);
|
||||
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||
GX_TexCoord2f32(0.0f, 0.0f);
|
||||
GX_Position2s16(screenX, screenY);
|
||||
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||
GX_TexCoord2f32(0.0f, 0.0f);
|
||||
|
||||
GX_Position2s16(texWidth + screenX, screenY);
|
||||
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||
GX_TexCoord2f32(1.0f, 0.0f);
|
||||
GX_Position2s16(texWidth + screenX, screenY);
|
||||
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||
GX_TexCoord2f32(1.0f, 0.0f);
|
||||
|
||||
GX_Position2s16(texWidth + screenX, texHeight + screenY);
|
||||
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||
GX_TexCoord2f32(1.0f, 1.0f);
|
||||
GX_Position2s16(texWidth + screenX, texHeight + screenY);
|
||||
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||
GX_TexCoord2f32(1.0f, 1.0f);
|
||||
|
||||
GX_Position2s16(screenX, texHeight + screenY);
|
||||
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||
GX_TexCoord2f32(0.0f, 1.0f);
|
||||
GX_Position2s16(screenX, texHeight + screenY);
|
||||
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||
GX_TexCoord2f32(0.0f, 1.0f);
|
||||
GX_End();
|
||||
GX_DrawDone();
|
||||
|
||||
@ -675,23 +694,23 @@ void FreeTypeGX::copyTextureToFramebuffer(GXTexObj *texObj, f32 texWidth, f32 te
|
||||
* @param screenY The screen Y coordinate at which to output the quad.
|
||||
* @param color Color to apply to the texture.
|
||||
*/
|
||||
void FreeTypeGX::copyFeatureToFramebuffer(f32 featureWidth, f32 featureHeight, int16_t screenX, int16_t screenY, GXColor color) {
|
||||
|
||||
void FreeTypeGX::copyFeatureToFramebuffer(f32 featureWidth, f32 featureHeight, int16_t screenX, int16_t screenY, GXColor color)
|
||||
{
|
||||
GX_SetTevOp (GX_TEVSTAGE0, GX_PASSCLR);
|
||||
GX_SetVtxDesc (GX_VA_TEX0, GX_NONE);
|
||||
|
||||
GX_Begin(GX_QUADS, this->vertexIndex, 4);
|
||||
GX_Position2s16(screenX, screenY);
|
||||
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||
GX_Position2s16(screenX, screenY);
|
||||
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||
|
||||
GX_Position2s16(featureWidth + screenX, screenY);
|
||||
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||
GX_Position2s16(featureWidth + screenX, screenY);
|
||||
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||
|
||||
GX_Position2s16(featureWidth + screenX, featureHeight + screenY);
|
||||
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||
GX_Position2s16(featureWidth + screenX, featureHeight + screenY);
|
||||
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||
|
||||
GX_Position2s16(screenX, featureHeight + screenY);
|
||||
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||
GX_Position2s16(screenX, featureHeight + screenY);
|
||||
GX_Color4u8(color.r, color.g, color.b, color.a);
|
||||
GX_End();
|
||||
GX_DrawDone();
|
||||
|
||||
|
@ -169,15 +169,16 @@
|
||||
* Font face character glyph relevant data structure.
|
||||
*/
|
||||
typedef struct ftgxCharData_ {
|
||||
uint16_t glyphAdvanceX; /**< Character glyph X coordinate advance in pixels. */
|
||||
uint16_t glyphIndex; /**< Charachter glyph index in the font face. */
|
||||
int16_t renderOffsetX; /**< Texture X axis bearing offset. */
|
||||
uint16_t glyphAdvanceX; /**< Character glyph X coordinate advance in pixels. */
|
||||
uint16_t glyphIndex; /**< Charachter glyph index in the font face. */
|
||||
|
||||
uint16_t textureWidth; /**< Texture width in pixels/bytes. */
|
||||
uint16_t textureHeight; /**< Texture glyph height in pixels/bytes. */
|
||||
uint16_t textureWidth; /**< Texture width in pixels/bytes. */
|
||||
uint16_t textureHeight; /**< Texture glyph height in pixels/bytes. */
|
||||
|
||||
uint16_t renderOffsetY; /**< Texture Y axis bearing offset. */
|
||||
uint16_t renderOffsetMax; /**< Texture Y axis bearing maximum value. */
|
||||
uint16_t renderOffsetMin; /**< Texture Y axis bearing minimum value. */
|
||||
int16_t renderOffsetY; /**< Texture Y axis bearing offset. */
|
||||
int16_t renderOffsetMax; /**< Texture Y axis bearing maximum value. */
|
||||
int16_t renderOffsetMin; /**< Texture Y axis bearing minimum value. */
|
||||
|
||||
uint32_t* glyphDataTexture; /**< Glyph texture bitmap data buffer. */
|
||||
} ftgxCharData;
|
||||
@ -187,23 +188,35 @@ typedef struct ftgxCharData_ {
|
||||
* Offset structure which hold both a maximum and minimum value.
|
||||
*/
|
||||
typedef struct ftgxDataOffset_ {
|
||||
int16_t max; /**< Maximum data offset. */
|
||||
int16_t min; /**< Minimum data offset. */
|
||||
int16_t ascender; /**< Maximum data offset. */
|
||||
int16_t descender; /**< Minimum data offset. */
|
||||
int16_t max; /**< Maximum data offset. */
|
||||
int16_t min; /**< Minimum data offset. */
|
||||
} ftgxDataOffset;
|
||||
|
||||
typedef struct ftgxCharData_ ftgxCharData;
|
||||
typedef struct ftgxDataOffset_ ftgxDataOffset;
|
||||
|
||||
#define _TEXT(t) L ## t /**< Unicode helper macro. */
|
||||
|
||||
#define FTGX_NULL 0x0000
|
||||
#define FTGX_JUSTIFY_LEFT 0x0001
|
||||
#define FTGX_JUSTIFY_CENTER 0x0002
|
||||
#define FTGX_JUSTIFY_RIGHT 0x0004
|
||||
#define FTGX_JUSTIFY_MASK 0x000f
|
||||
|
||||
#define FTGX_ALIGN_TOP 0x0010
|
||||
#define FTGX_ALIGN_MIDDLE 0x0020
|
||||
#define FTGX_ALIGN_BOTTOM 0x0040
|
||||
#define FTGX_ALIGN_BASELINE 0x0080
|
||||
#define FTGX_ALIGN_GLYPH_TOP 0x0100
|
||||
#define FTGX_ALIGN_GLYPH_MIDDLE 0x0200
|
||||
#define FTGX_ALIGN_GLYPH_BOTTOM 0x0400
|
||||
#define FTGX_ALIGN_MASK 0x0ff0
|
||||
|
||||
#define FTGX_STYLE_UNDERLINE 0x0100
|
||||
#define FTGX_STYLE_STRIKE 0x0200
|
||||
#define FTGX_STYLE_UNDERLINE 0x1000
|
||||
#define FTGX_STYLE_STRIKE 0x2000
|
||||
#define FTGX_STYLE_MASK 0xf000
|
||||
|
||||
#define FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_MODULATE 0X0001
|
||||
#define FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_DECAL 0X0002
|
||||
@ -250,8 +263,8 @@ class FreeTypeGX {
|
||||
static uint16_t adjustTextureWidth(uint16_t textureWidth, uint8_t textureFormat);
|
||||
static uint16_t adjustTextureHeight(uint16_t textureHeight, uint8_t textureFormat);
|
||||
|
||||
static uint16_t getStyleOffsetWidth(uint16_t width, uint16_t format);
|
||||
static uint16_t getStyleOffsetHeight(ftgxDataOffset offset, uint16_t format);
|
||||
static int16_t getStyleOffsetWidth(uint16_t width, uint16_t format);
|
||||
static int16_t getStyleOffsetHeight(ftgxDataOffset *offset, uint16_t format);
|
||||
|
||||
void unloadFont();
|
||||
ftgxCharData *cacheGlyphData(wchar_t charCode);
|
||||
@ -260,7 +273,7 @@ class FreeTypeGX {
|
||||
|
||||
void setDefaultMode();
|
||||
|
||||
void drawTextFeature(int16_t x, int16_t y, uint16_t width, ftgxDataOffset offsetData, uint16_t format, GXColor color);
|
||||
void drawTextFeature(int16_t x, int16_t y, uint16_t width, ftgxDataOffset *offsetData, uint16_t format, GXColor color);
|
||||
void copyTextureToFramebuffer(GXTexObj *texObj, f32 texWidth, f32 texHeight, int16_t screenX, int16_t screenY, GXColor color);
|
||||
void copyFeatureToFramebuffer(f32 featureWidth, f32 featureHeight, int16_t screenX, int16_t screenY, GXColor color);
|
||||
|
||||
@ -278,8 +291,8 @@ class FreeTypeGX {
|
||||
uint16_t getWidth(wchar_t const *text);
|
||||
uint16_t getHeight(wchar_t *text);
|
||||
uint16_t getHeight(wchar_t const *text);
|
||||
ftgxDataOffset getOffset(wchar_t *text);
|
||||
ftgxDataOffset getOffset(wchar_t const *text);
|
||||
void getOffset(wchar_t *text, ftgxDataOffset* offset);
|
||||
void getOffset(wchar_t const *text, ftgxDataOffset* offset);
|
||||
};
|
||||
|
||||
#endif /* FREETYPEGX_H_ */
|
||||
|
@ -227,11 +227,6 @@ void GuiText::Draw()
|
||||
currentSize = newSize;
|
||||
}
|
||||
|
||||
int voffset = 0;
|
||||
|
||||
if(alignmentVert == ALIGN_MIDDLE)
|
||||
voffset = -newSize/2 + 2;
|
||||
|
||||
if(maxWidth > 0)
|
||||
{
|
||||
char * tmpText = strdup(origText);
|
||||
@ -279,7 +274,7 @@ void GuiText::Draw()
|
||||
}
|
||||
}
|
||||
if(textDyn)
|
||||
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop()+voffset, textDyn, c, style);
|
||||
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop(), textDyn, c, style);
|
||||
}
|
||||
else if(wrap)
|
||||
{
|
||||
@ -328,8 +323,10 @@ void GuiText::Draw()
|
||||
i++;
|
||||
}
|
||||
|
||||
int voffset = 0;
|
||||
|
||||
if(alignmentVert == ALIGN_MIDDLE)
|
||||
voffset = voffset - (lineheight*linenum)/2 + lineheight/2;
|
||||
voffset = -(lineheight*linenum)/2 + lineheight/2;
|
||||
|
||||
for(i=0; i < linenum; i++)
|
||||
{
|
||||
@ -339,13 +336,13 @@ void GuiText::Draw()
|
||||
}
|
||||
else
|
||||
{
|
||||
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop()+voffset, textDyn, c, style);
|
||||
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop(), textDyn, c, style);
|
||||
}
|
||||
free(tmpText);
|
||||
}
|
||||
else
|
||||
{
|
||||
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop()+voffset, text, c, style);
|
||||
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop(), text, c, style);
|
||||
}
|
||||
this->UpdateEffects();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user