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 "FreeTypeGX.h"
#include "video/CVideo.h" #include "video/CVideo.h"
#include "video/shaders/Texture2DShader.h" #include "video/shaders/Texture2DShader.h"
#include "utils/logger.h"
using namespace std; using namespace std;
@ -369,7 +370,7 @@ int16_t FreeTypeGX::getStyleOffsetHeight(int16_t format, uint16_t pixelSize)
* @return The number of characters printed. * @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) if (!text)
return 0; 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; int i = 0;
while (text[i]) while (text[i])
{ {
ftgxCharData* glyphData = cacheGlyphData(text[i], pixelSize); 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); FT_Get_Kerning(ftFace, fontData[pixelSize].ftgxCharMap[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta);
x_pos += (pairDelta.x >> 6); 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; x_pos += glyphData->glyphAdvanceX;
++printed; ++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 screenY The screen Y coordinate at which to output the rendered texture.
* @param color Color to apply to the 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 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 offsetLeft = blurScale * ((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 offsetTop = blurScale * ((f32)y - 0.5f * (f32)texture->surface.height) * (f32)pVideo->getHeightScaleFactor();
f32 widthScale = blurScale * (f32)texture->surface.width * pVideo->getWidthScaleFactor(); f32 widthScale = blurScale * (f32)texture->surface.width * pVideo->getWidthScaleFactor();
f32 heightScale = blurScale * (f32)texture->surface.height * pVideo->getHeightScaleFactor(); 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); uint16_t cacheGlyphDataComplete(int16_t pixelSize);
void loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData); 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: public:
FreeTypeGX(const uint8_t* fontBuffer, FT_Long bufferSize, bool lastFace = false); FreeTypeGX(const uint8_t* fontBuffer, FT_Long bufferSize, bool lastFace = false);
~FreeTypeGX(); ~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 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 getWidth(const wchar_t *text, int16_t pixelSize);
uint16_t getCharWidth(const wchar_t wChar, int16_t pixelSize, const wchar_t prevChar = 0x0000); 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; FreeTypeGX * GuiText::presentFont = NULL;
int GuiText::presetSize = 28; 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::presetMaxWidth = 0xFFFF;
int GuiText::presetAlignment = ALIGN_CENTER | ALIGN_MIDDLE; int GuiText::presetAlignment = ALIGN_CENTER | ALIGN_MIDDLE;
GX2ColorF32 GuiText::presetColor = (GX2ColorF32){ 1.0f, 1.0f, 1.0f, 1.0f }; GX2ColorF32 GuiText::presetColor = (GX2ColorF32){ 1.0f, 1.0f, 1.0f, 1.0f };
@ -52,6 +53,7 @@ GuiText::GuiText()
blurGlowIntensity = 0.0f; blurGlowIntensity = 0.0f;
blurAlpha = 0.0f; blurAlpha = 0.0f;
blurGlowColor = glm::vec4(0.0f); blurGlowColor = glm::vec4(0.0f);
internalRenderingScale = presetInternalRenderingScale;
} }
GuiText::GuiText(const char * t, int s, const glm::vec4 & c) 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; blurGlowIntensity = 0.0f;
blurAlpha = 0.0f; blurAlpha = 0.0f;
blurGlowColor = glm::vec4(0.0f); blurGlowColor = glm::vec4(0.0f);
internalRenderingScale = presetInternalRenderingScale;
if(t) if(t)
{ {
@ -105,6 +108,7 @@ GuiText::GuiText(const wchar_t * t, int s, const glm::vec4 & c)
blurGlowIntensity = 0.0f; blurGlowIntensity = 0.0f;
blurAlpha = 0.0f; blurAlpha = 0.0f;
blurGlowColor = glm::vec4(0.0f); blurGlowColor = glm::vec4(0.0f);
internalRenderingScale = presetInternalRenderingScale;
if(t) if(t)
{ {
@ -141,6 +145,7 @@ GuiText::GuiText(const char * t)
blurGlowIntensity = 0.0f; blurGlowIntensity = 0.0f;
blurAlpha = 0.0f; blurAlpha = 0.0f;
blurGlowColor = glm::vec4(0.0f); blurGlowColor = glm::vec4(0.0f);
internalRenderingScale = presetInternalRenderingScale;
if(t) if(t)
{ {
@ -530,16 +535,23 @@ void GuiText::draw(CVideo *pVideo)
color[3] = getAlpha(); color[3] = getAlpha();
blurGlowColor[3] = blurAlpha * 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) if(newSize != currentSize)
{ {
currentSize = newSize; currentSize = normal_size;
if(text) 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(maxWidth > 0 && maxWidth <= textWidth)
{ {
if(wrapMode == DOTTED) // text dotted if(wrapMode == DOTTED) // text dotted
@ -552,11 +564,12 @@ void GuiText::draw(CVideo *pVideo)
textDynWidth.resize(textDyn.size()); textDynWidth.resize(textDyn.size());
for(u32 i = 0; i < textDynWidth.size(); i++) 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) 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) else if(wrapMode == SCROLL_HORIZONTAL)
@ -564,11 +577,12 @@ void GuiText::draw(CVideo *pVideo)
scrollText(pVideo->getFrameCount()); scrollText(pVideo->getFrameCount());
if(textDyn.size() > 0) 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) else if(wrapMode == WRAP)
{ {
int lineheight = currentSize + 6; int lineheight = newSize + 6;
int yoffset = 0; int yoffset = 0;
int voffset = 0; int voffset = 0;
@ -580,7 +594,7 @@ void GuiText::draw(CVideo *pVideo)
textDynWidth.resize(textDyn.size()); textDynWidth.resize(textDyn.size());
for(u32 i = 0; i < textDynWidth.size(); i++) 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) if(alignment & ALIGN_MIDDLE)
@ -588,13 +602,14 @@ void GuiText::draw(CVideo *pVideo)
for(u32 i = 0; i < textDyn.size(); i++) 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; yoffset -= lineheight;
} }
} }
} }
else 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 FreeTypeGX * presentFont;
static int presetSize; static int presetSize;
static int presetMaxWidth; static int presetMaxWidth;
static int presetInternalRenderingScale;
static int presetAlignment; static int presetAlignment;
static GX2ColorF32 presetColor; static GX2ColorF32 presetColor;
@ -134,6 +135,7 @@ protected:
float blurGlowIntensity; float blurGlowIntensity;
float blurAlpha; float blurAlpha;
glm::vec4 blurGlowColor; glm::vec4 blurGlowColor;
float internalRenderingScale;
}; };
#endif #endif