Add font smoothing thanks to @Maschell

It seems smoothER, but there may be room for more improvement
This commit is contained in:
vgmoose 2016-10-16 15:07:30 -04:00
parent e33c9894f1
commit b0aeaef5bf
4 changed files with 37 additions and 20 deletions

16
src/gui/FreeTypeGX.cpp Normal file → Executable file
View File

@ -23,6 +23,7 @@
#include "FreeTypeGX.h"
#include "video/CVideo.h"
#include "video/shaders/Texture2DShader.h"
#include "utils/logger.h"
using namespace std;
@ -369,7 +370,7 @@ int16_t FreeTypeGX::getStyleOffsetHeight(int16_t format, uint16_t pixelSize)
* @return The number of characters printed.
*/
uint16_t FreeTypeGX::drawText(CVideo *video, int16_t x, int16_t y, int16_t z, const wchar_t *text, int16_t pixelSize, const glm::vec4 & color, uint16_t textStyle, uint16_t textWidth, const float &textBlur, const float &colorBlurIntensity, const glm::vec4 & blurColor)
uint16_t FreeTypeGX::drawText(CVideo *video, int16_t x, int16_t y, int16_t z, const wchar_t *text, int16_t pixelSize, const glm::vec4 & color, uint16_t textStyle, uint16_t textWidth, const float &textBlur, const float & colorBlurIntensity, const glm::vec4 & blurColor, const float & internalRenderingScale)
{
if (!text)
return 0;
@ -389,7 +390,6 @@ uint16_t FreeTypeGX::drawText(CVideo *video, int16_t x, int16_t y, int16_t z, co
}
int i = 0;
while (text[i])
{
ftgxCharData* glyphData = cacheGlyphData(text[i], pixelSize);
@ -400,9 +400,9 @@ uint16_t FreeTypeGX::drawText(CVideo *video, int16_t x, int16_t y, int16_t z, co
{
FT_Get_Kerning(ftFace, fontData[pixelSize].ftgxCharMap[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta);
x_pos += (pairDelta.x >> 6);
}
copyTextureToFramebuffer(video, glyphData->texture, x_pos + glyphData->renderOffsetX + x_offset, y + glyphData->renderOffsetY - y_offset, z, color, textBlur, colorBlurIntensity, blurColor);
}
copyTextureToFramebuffer(video, glyphData->texture,x_pos + glyphData->renderOffsetX + x_offset, y + glyphData->renderOffsetY - y_offset, z, color, textBlur, colorBlurIntensity, blurColor,internalRenderingScale);
x_pos += glyphData->glyphAdvanceX;
++printed;
@ -547,13 +547,13 @@ void FreeTypeGX::getOffset(const wchar_t *text, int16_t pixelSize, uint16_t widt
* @param screenY The screen Y coordinate at which to output the rendered texture.
* @param color Color to apply to the texture.
*/
void FreeTypeGX::copyTextureToFramebuffer(CVideo *pVideo, GX2Texture *texture, int16_t x, int16_t y, int16_t z, const glm::vec4 & color, const float & defaultBlur, const float & blurIntensity, const glm::vec4 & blurColor)
void FreeTypeGX::copyTextureToFramebuffer(CVideo *pVideo, GX2Texture *texture, int16_t x, int16_t y, int16_t z, const glm::vec4 & color, const float & defaultBlur, const float & blurIntensity, const glm::vec4 & blurColor, const float & internalRenderingScale)
{
static const f32 imageAngle = 0.0f;
static const f32 blurScale = 2.0f;
static const f32 blurScale = (2.0f/ (internalRenderingScale));
f32 offsetLeft = 2.0f * ((f32)x + 0.5f * (f32)texture->surface.width) * (f32)pVideo->getWidthScaleFactor();
f32 offsetTop = 2.0f * ((f32)y - 0.5f * (f32)texture->surface.height) * (f32)pVideo->getHeightScaleFactor();
f32 offsetLeft = blurScale * ((f32)x + 0.5f * (f32)texture->surface.width) * (f32)pVideo->getWidthScaleFactor();
f32 offsetTop = blurScale * ((f32)y - 0.5f * (f32)texture->surface.height) * (f32)pVideo->getHeightScaleFactor();
f32 widthScale = blurScale * (f32)texture->surface.width * pVideo->getWidthScaleFactor();
f32 heightScale = blurScale * (f32)texture->surface.height * pVideo->getHeightScaleFactor();

4
src/gui/FreeTypeGX.h Normal file → Executable file
View File

@ -134,14 +134,14 @@ class FreeTypeGX
uint16_t cacheGlyphDataComplete(int16_t pixelSize);
void loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData);
void copyTextureToFramebuffer(CVideo * pVideo, GX2Texture *tex, int16_t screenX, int16_t screenY, int16_t screenZ, const glm::vec4 & color, const float &textBlur, const float &colorBlurIntensity, const glm::vec4 & blurColor);
void copyTextureToFramebuffer(CVideo * pVideo, GX2Texture *tex, int16_t screenX, int16_t screenY, int16_t screenZ, const glm::vec4 & color, const float &textBlur, const float &colorBlurIntensity, const glm::vec4 & blurColor, const float & internalRenderingScale);
public:
FreeTypeGX(const uint8_t* fontBuffer, FT_Long bufferSize, bool lastFace = false);
~FreeTypeGX();
uint16_t drawText(CVideo * pVideo, int16_t x, int16_t y, int16_t z, const wchar_t *text, int16_t pixelSize, const glm::vec4 & color,
uint16_t textStyling, uint16_t textWidth, const float &textBlur, const float &colorBlurIntensity, const glm::vec4 & blurColor);
uint16_t textStyling, uint16_t textWidth, const float &textBlur, const float &colorBlurIntensity, const glm::vec4 & blurColor, const float & internalRenderingScale);
uint16_t getWidth(const wchar_t *text, int16_t pixelSize);
uint16_t getCharWidth(const wchar_t wChar, int16_t pixelSize, const wchar_t prevChar = 0x0000);

35
src/gui/GuiText.cpp Normal file → Executable file
View File

@ -20,6 +20,7 @@
FreeTypeGX * GuiText::presentFont = NULL;
int GuiText::presetSize = 28;
int GuiText::presetInternalRenderingScale = 2.0f; //Lets render the font at the doubled size. This make it even smoother!
int GuiText::presetMaxWidth = 0xFFFF;
int GuiText::presetAlignment = ALIGN_CENTER | ALIGN_MIDDLE;
GX2ColorF32 GuiText::presetColor = (GX2ColorF32){ 1.0f, 1.0f, 1.0f, 1.0f };
@ -52,6 +53,7 @@ GuiText::GuiText()
blurGlowIntensity = 0.0f;
blurAlpha = 0.0f;
blurGlowColor = glm::vec4(0.0f);
internalRenderingScale = presetInternalRenderingScale;
}
GuiText::GuiText(const char * t, int s, const glm::vec4 & c)
@ -74,6 +76,7 @@ GuiText::GuiText(const char * t, int s, const glm::vec4 & c)
blurGlowIntensity = 0.0f;
blurAlpha = 0.0f;
blurGlowColor = glm::vec4(0.0f);
internalRenderingScale = presetInternalRenderingScale;
if(t)
{
@ -105,6 +108,7 @@ GuiText::GuiText(const wchar_t * t, int s, const glm::vec4 & c)
blurGlowIntensity = 0.0f;
blurAlpha = 0.0f;
blurGlowColor = glm::vec4(0.0f);
internalRenderingScale = presetInternalRenderingScale;
if(t)
{
@ -141,6 +145,7 @@ GuiText::GuiText(const char * t)
blurGlowIntensity = 0.0f;
blurAlpha = 0.0f;
blurGlowColor = glm::vec4(0.0f);
internalRenderingScale = presetInternalRenderingScale;
if(t)
{
@ -530,16 +535,23 @@ void GuiText::draw(CVideo *pVideo)
color[3] = getAlpha();
blurGlowColor[3] = blurAlpha * getAlpha();
int newSize = size * getScale();
float finalRenderingScale = 2.0f * internalRenderingScale;
int newSize = size * getScale() * finalRenderingScale;
int normal_size = size * getScale();
if(newSize != currentSize)
{
currentSize = newSize;
currentSize = normal_size;
if(text)
textWidth = font->getWidth(text, currentSize);
textWidth = font->getWidth(text, normal_size);
}
f32 x_pos = getCenterX() * finalRenderingScale;
f32 y_pos = getCenterY() * finalRenderingScale;
if(maxWidth > 0 && maxWidth <= textWidth)
{
if(wrapMode == DOTTED) // text dotted
@ -552,11 +564,12 @@ void GuiText::draw(CVideo *pVideo)
textDynWidth.resize(textDyn.size());
for(u32 i = 0; i < textDynWidth.size(); i++)
textDynWidth[i] = font->getWidth(textDyn[i], currentSize);
textDynWidth[i] = font->getWidth(textDyn[i], newSize);
}
if(textDyn.size() > 0)
font->drawText(pVideo, getCenterX(), getCenterY(), getDepth(), textDyn[textDyn.size()-1], currentSize, color, alignment, textDynWidth[textDyn.size()-1], defaultBlur, blurGlowIntensity, blurGlowColor);
font->drawText(pVideo, x_pos, y_pos, getDepth(), textDyn[textDyn.size()-1], newSize, color, alignment, textDynWidth[textDyn.size()-1], defaultBlur, blurGlowIntensity, blurGlowColor,finalRenderingScale);
}
else if(wrapMode == SCROLL_HORIZONTAL)
@ -564,11 +577,12 @@ void GuiText::draw(CVideo *pVideo)
scrollText(pVideo->getFrameCount());
if(textDyn.size() > 0)
font->drawText(pVideo, getCenterX(), getCenterY(), getDepth(), textDyn[textDyn.size()-1], currentSize, color, alignment, maxWidth, defaultBlur, blurGlowIntensity, blurGlowColor);
font->drawText(pVideo, x_pos, y_pos, getDepth(), textDyn[textDyn.size()-1], newSize, color, alignment, maxWidth*finalRenderingScale, defaultBlur, blurGlowIntensity, blurGlowColor,finalRenderingScale);
}
else if(wrapMode == WRAP)
{
int lineheight = currentSize + 6;
int lineheight = newSize + 6;
int yoffset = 0;
int voffset = 0;
@ -580,7 +594,7 @@ void GuiText::draw(CVideo *pVideo)
textDynWidth.resize(textDyn.size());
for(u32 i = 0; i < textDynWidth.size(); i++)
textDynWidth[i] = font->getWidth(textDyn[i], currentSize);
textDynWidth[i] = font->getWidth(textDyn[i], newSize);
}
if(alignment & ALIGN_MIDDLE)
@ -588,13 +602,14 @@ void GuiText::draw(CVideo *pVideo)
for(u32 i = 0; i < textDyn.size(); i++)
{
font->drawText(pVideo, getCenterX(), getCenterY() + voffset + yoffset, getDepth(), textDyn[i], currentSize, color, alignment, textDynWidth[i], defaultBlur, blurGlowIntensity, blurGlowColor);
font->drawText(pVideo, x_pos, y_pos + voffset + yoffset, getDepth(), textDyn[i], newSize, color, alignment, textDynWidth[i], defaultBlur, blurGlowIntensity, blurGlowColor,finalRenderingScale);
yoffset -= lineheight;
}
}
}
else
{
font->drawText(pVideo, getCenterX(), getCenterY(), getDepth(), text, currentSize, color, alignment, textWidth, defaultBlur, blurGlowIntensity, blurGlowColor);
uint16_t newtextWidth = font->getWidth(text, newSize);
font->drawText(pVideo, x_pos, y_pos, getDepth(), text, newSize, color, alignment, newtextWidth, defaultBlur, blurGlowIntensity, blurGlowColor,finalRenderingScale);
}
}

2
src/gui/GuiText.h Normal file → Executable file
View File

@ -104,6 +104,7 @@ protected:
static FreeTypeGX * presentFont;
static int presetSize;
static int presetMaxWidth;
static int presetInternalRenderingScale;
static int presetAlignment;
static GX2ColorF32 presetColor;
@ -134,6 +135,7 @@ protected:
float blurGlowIntensity;
float blurAlpha;
glm::vec4 blurGlowColor;
float internalRenderingScale;
};
#endif