mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-03-25 14:21:55 +02:00
Fix font rendering for color and formatting codes (#1017)
* Fix "Colormatic" splash text rendering as single color Signed-off-by: Ayush Thoren <ayushthoren@gmail.com> * Use per-vertex coloring in a single batch Signed-off-by: Ayush Thoren <ayushthoren@gmail.com> * Fix font rendering for color and formatting codes Signed-off-by: Ayush Thoren <ayushthoren@gmail.com> --------- Signed-off-by: Ayush Thoren <ayushthoren@gmail.com>
This commit is contained in:
@@ -130,6 +130,7 @@ Font::~Font()
|
||||
}
|
||||
#endif
|
||||
|
||||
// Legacy helper used by renderCharacter() only.
|
||||
void Font::renderStyleLine(float x0, float y0, float x1, float y1)
|
||||
{
|
||||
Tesselator* t = Tesselator::getInstance();
|
||||
@@ -146,61 +147,32 @@ void Font::renderStyleLine(float x0, float y0, float x1, float y1)
|
||||
t->end();
|
||||
}
|
||||
|
||||
void Font::addCharacterQuad(wchar_t c)
|
||||
void Font::addSolidQuad(float x0, float y0, float x1, float y1)
|
||||
{
|
||||
float xOff = c % m_cols * m_charWidth;
|
||||
float yOff = c / m_cols * m_charHeight; // was m_charWidth — wrong when glyphs aren't square
|
||||
float width = charWidths[c] - .01f;
|
||||
float height = m_charHeight - .01f;
|
||||
float fontWidth = m_cols * m_charWidth;
|
||||
float fontHeight = m_rows * m_charHeight;
|
||||
const float shear = m_italic ? (height * 0.25f) : 0.0f;
|
||||
float x0 = xPos, x1 = xPos + width + shear;
|
||||
float y0 = yPos, y1 = yPos + height;
|
||||
|
||||
Tesselator *t = Tesselator::getInstance();
|
||||
t->tex(xOff / fontWidth, (yOff + 7.99f) / fontHeight);
|
||||
t->tex(0.0f, 0.0f);
|
||||
t->vertex(x0, y1, 0.0f);
|
||||
t->tex((xOff + width) / fontWidth, (yOff + 7.99f) / fontHeight);
|
||||
t->tex(0.0f, 0.0f);
|
||||
t->vertex(x1, y1, 0.0f);
|
||||
t->tex((xOff + width) / fontWidth, yOff / fontHeight);
|
||||
t->tex(0.0f, 0.0f);
|
||||
t->vertex(x1, y0, 0.0f);
|
||||
t->tex(xOff / fontWidth, yOff / fontHeight);
|
||||
t->tex(0.0f, 0.0f);
|
||||
t->vertex(x0, y0, 0.0f);
|
||||
|
||||
if (m_bold)
|
||||
{
|
||||
float dx = 1.0f;
|
||||
t->tex(xOff / fontWidth, (yOff + 7.99f) / fontHeight);
|
||||
t->vertex(x0 + dx, y1, 0.0f);
|
||||
t->tex((xOff + width) / fontWidth, (yOff + 7.99f) / fontHeight);
|
||||
t->vertex(x1 + dx, y1, 0.0f);
|
||||
t->tex((xOff + width) / fontWidth, yOff / fontHeight);
|
||||
t->vertex(x1 + dx, y0, 0.0f);
|
||||
t->tex(xOff / fontWidth, yOff / fontHeight);
|
||||
t->vertex(x0 + dx, y0, 0.0f);
|
||||
}
|
||||
|
||||
xPos += static_cast<float>(charWidths[c]);
|
||||
}
|
||||
|
||||
void Font::renderCharacter(wchar_t c)
|
||||
void Font::emitCharacterGeometry(wchar_t c)
|
||||
{
|
||||
float xOff = c % m_cols * m_charWidth;
|
||||
float yOff = c / m_cols * m_charHeight; // was m_charWidth — wrong when glyphs aren't square
|
||||
|
||||
float width = charWidths[c] - .01f;
|
||||
float height = m_charHeight - .01f;
|
||||
|
||||
float fontWidth = m_cols * m_charWidth;
|
||||
float fontHeight = m_rows * m_charHeight;
|
||||
|
||||
const float shear = m_italic ? (height * 0.25f) : 0.0f;
|
||||
float x0 = xPos, x1 = xPos + width + shear;
|
||||
float y0 = yPos, y1 = yPos + height;
|
||||
|
||||
Tesselator *t = Tesselator::getInstance();
|
||||
t->begin();
|
||||
t->tex(xOff / fontWidth, (yOff + 7.99f) / fontHeight);
|
||||
t->vertex(x0, y1, 0.0f);
|
||||
t->tex((xOff + width) / fontWidth, (yOff + 7.99f) / fontHeight);
|
||||
@@ -209,12 +181,10 @@ void Font::renderCharacter(wchar_t c)
|
||||
t->vertex(x1, y0, 0.0f);
|
||||
t->tex(xOff / fontWidth, yOff / fontHeight);
|
||||
t->vertex(x0, y0, 0.0f);
|
||||
t->end();
|
||||
|
||||
if (m_bold)
|
||||
{
|
||||
float dx = 1.0f;
|
||||
t->begin();
|
||||
t->tex(xOff / fontWidth, (yOff + 7.99f) / fontHeight);
|
||||
t->vertex(x0 + dx, y1, 0.0f);
|
||||
t->tex((xOff + width) / fontWidth, (yOff + 7.99f) / fontHeight);
|
||||
@@ -223,8 +193,45 @@ void Font::renderCharacter(wchar_t c)
|
||||
t->vertex(x1 + dx, y0, 0.0f);
|
||||
t->tex(xOff / fontWidth, yOff / fontHeight);
|
||||
t->vertex(x0 + dx, y0, 0.0f);
|
||||
t->end();
|
||||
}
|
||||
}
|
||||
|
||||
void Font::addCharacterQuad(wchar_t c)
|
||||
{
|
||||
float height = m_charHeight - .01f;
|
||||
float x0 = xPos;
|
||||
float y0 = yPos;
|
||||
float y1 = yPos + height;
|
||||
float advance = static_cast<float>(charWidths[c]);
|
||||
|
||||
emitCharacterGeometry(c);
|
||||
|
||||
if (m_underline)
|
||||
{
|
||||
addSolidQuad(x0, y1 - 1.0f, xPos + advance, y1);
|
||||
}
|
||||
|
||||
if (m_strikethrough)
|
||||
{
|
||||
float mid = y0 + height * 0.5f;
|
||||
addSolidQuad(x0, mid - 0.5f, xPos + advance, mid + 0.5f);
|
||||
}
|
||||
|
||||
xPos += advance;
|
||||
}
|
||||
|
||||
// Legacy helper used by drawLiteral() only.
|
||||
void Font::renderCharacter(wchar_t c)
|
||||
{
|
||||
float height = m_charHeight - .01f;
|
||||
float x0 = xPos;
|
||||
float y0 = yPos;
|
||||
float y1 = yPos + height;
|
||||
|
||||
Tesselator *t = Tesselator::getInstance();
|
||||
t->begin();
|
||||
emitCharacterGeometry(c);
|
||||
t->end();
|
||||
|
||||
if (m_underline)
|
||||
renderStyleLine(x0, y1 - 1.0f, xPos + static_cast<float>(charWidths[c]), y1);
|
||||
@@ -289,7 +296,7 @@ static bool isSectionFormatCode(wchar_t ca)
|
||||
return l == L'l' || l == L'o' || l == L'n' || l == L'm' || l == L'r' || l == L'k';
|
||||
}
|
||||
|
||||
void Font::draw(const wstring &str, bool dropShadow)
|
||||
void Font::draw(const wstring &str, bool dropShadow, int initialColor)
|
||||
{
|
||||
// Bind the texture
|
||||
textures->bindTexture(m_textureLocation);
|
||||
@@ -297,8 +304,11 @@ void Font::draw(const wstring &str, bool dropShadow)
|
||||
m_bold = m_italic = m_underline = m_strikethrough = false;
|
||||
wstring cleanStr = sanitize(str);
|
||||
|
||||
int currentColor = initialColor;
|
||||
|
||||
Tesselator *t = Tesselator::getInstance();
|
||||
t->begin();
|
||||
t->color(currentColor & 0x00ffffff, (currentColor >> 24) & 255);
|
||||
|
||||
for (int i = 0; i < static_cast<int>(cleanStr.length()); ++i)
|
||||
{
|
||||
@@ -310,10 +320,8 @@ void Font::draw(const wstring &str, bool dropShadow)
|
||||
wchar_t ca = cleanStr[i+1];
|
||||
if (!isSectionFormatCode(ca))
|
||||
{
|
||||
t->end();
|
||||
renderCharacter(167);
|
||||
renderCharacter(ca);
|
||||
t->begin();
|
||||
addCharacterQuad(167);
|
||||
addCharacterQuad(ca);
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
@@ -329,7 +337,12 @@ void Font::draw(const wstring &str, bool dropShadow)
|
||||
else if (l == L'o') m_italic = true;
|
||||
else if (l == L'n') m_underline = true;
|
||||
else if (l == L'm') m_strikethrough = true;
|
||||
else if (l == L'r') m_bold = m_italic = m_underline = m_strikethrough = noise = false;
|
||||
else if (l == L'r')
|
||||
{
|
||||
m_bold = m_italic = m_underline = m_strikethrough = noise = false;
|
||||
currentColor = initialColor;
|
||||
t->color(currentColor & 0x00ffffff, (currentColor >> 24) & 255);
|
||||
}
|
||||
else if (l == L'k') noise = true;
|
||||
}
|
||||
else
|
||||
@@ -337,8 +350,8 @@ void Font::draw(const wstring &str, bool dropShadow)
|
||||
noise = false;
|
||||
if (colorN < 0 || colorN > 15) colorN = 15;
|
||||
if (dropShadow) colorN += 16;
|
||||
int color = colors[colorN];
|
||||
glColor3f((color >> 16) / 255.0F, ((color >> 8) & 255) / 255.0F, (color & 255) / 255.0F);
|
||||
currentColor = (initialColor & 0xff000000) | colors[colorN];
|
||||
t->color(currentColor & 0x00ffffff, (currentColor >> 24) & 255);
|
||||
}
|
||||
i += 1;
|
||||
continue;
|
||||
@@ -371,11 +384,11 @@ void Font::draw(const wstring& str, int x, int y, int color, bool dropShadow)
|
||||
if (dropShadow) // divide RGB by 4, preserve alpha
|
||||
color = (color & 0xfcfcfc) >> 2 | (color & (-1 << 24));
|
||||
|
||||
glColor4f((color >> 16 & 255) / 255.0F, (color >> 8 & 255) / 255.0F, (color & 255) / 255.0F, (color >> 24 & 255) / 255.0F);
|
||||
glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
xPos = x;
|
||||
yPos = y;
|
||||
draw(str, dropShadow);
|
||||
draw(str, dropShadow, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ public:
|
||||
private:
|
||||
void renderCharacter(wchar_t c); // 4J added
|
||||
void addCharacterQuad(wchar_t c);
|
||||
void addSolidQuad(float x0, float y0, float x1, float y1);
|
||||
void emitCharacterGeometry(wchar_t c);
|
||||
void renderStyleLine(float x0, float y0, float x1, float y1); // solid line for underline/strikethrough
|
||||
|
||||
public:
|
||||
@@ -65,7 +67,7 @@ public:
|
||||
private:
|
||||
wstring reorderBidi(const wstring &str);
|
||||
|
||||
void draw(const wstring &str, bool dropShadow);
|
||||
void draw(const wstring &str, bool dropShadow, int baseColor);
|
||||
void draw(const wstring& str, int x, int y, int color, bool dropShadow);
|
||||
void drawLiteral(const wstring& str, int x, int y, int color); // no § parsing
|
||||
int MapCharacter(wchar_t c); // 4J added
|
||||
|
||||
Reference in New Issue
Block a user