diff options
Diffstat (limited to 'Minecraft.Client/Font.cpp')
| -rw-r--r-- | Minecraft.Client/Font.cpp | 162 |
1 files changed, 123 insertions, 39 deletions
diff --git a/Minecraft.Client/Font.cpp b/Minecraft.Client/Font.cpp index 8a90711b..51b50ca1 100644 --- a/Minecraft.Client/Font.cpp +++ b/Minecraft.Client/Font.cpp @@ -21,6 +21,10 @@ Font::Font(Options *options, const wstring& name, Textures* textures, bool enfor enforceUnicodeSheet = false; bidirectional = false; xPos = yPos = 0.0f; + m_bold = false; + m_italic = false; + m_underline = false; + m_strikethrough = false; // Set up member variables m_cols = cols; @@ -126,6 +130,22 @@ Font::~Font() } #endif +void Font::renderStyleLine(float x0, float y0, float x1, float y1) +{ + Tesselator* t = Tesselator::getInstance(); + float u = 0.0f, v = 0.0f; + t->begin(); + t->tex(u, v); + t->vertex(x0, y1, 0.0f); + t->tex(u, v); + t->vertex(x1, y1, 0.0f); + t->tex(u, v); + t->vertex(x1, y0, 0.0f); + t->tex(u, v); + t->vertex(x0, y0, 0.0f); + t->end(); +} + void Font::renderCharacter(wchar_t c) { float xOff = c % m_cols * m_charWidth; @@ -137,37 +157,47 @@ void Font::renderCharacter(wchar_t c) float fontWidth = m_cols * m_charWidth; float fontHeight = m_rows * m_charHeight; - Tesselator *t = Tesselator::getInstance(); - // 4J Stu - Changed to a quad so that we can use within a command buffer -#if 1 + 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(xPos, yPos + height, 0.0f); - + t->vertex(x0, y1, 0.0f); t->tex((xOff + width) / fontWidth, (yOff + 7.99f) / fontHeight); - t->vertex(xPos + width, yPos + height, 0.0f); - + t->vertex(x1, y1, 0.0f); t->tex((xOff + width) / fontWidth, yOff / fontHeight); - t->vertex(xPos + width, yPos, 0.0f); - + t->vertex(x1, y0, 0.0f); t->tex(xOff / fontWidth, yOff / fontHeight); - t->vertex(xPos, yPos, 0.0f); - + t->vertex(x0, y0, 0.0f); t->end(); -#else - t->begin(GL_TRIANGLE_STRIP); - t->tex(xOff / 128.0F, yOff / 128.0F); - t->vertex(xPos, yPos, 0.0f); - t->tex(xOff / 128.0F, (yOff + 7.99f) / 128.0F); - t->vertex(xPos, yPos + 7.99f, 0.0f); - t->tex((xOff + width) / 128.0F, yOff / 128.0F); - t->vertex(xPos + width, yPos, 0.0f); - t->tex((xOff + width) / 128.0F, (yOff + 7.99f) / 128.0F); - t->vertex(xPos + width, yPos + 7.99f, 0.0f); - t->end(); -#endif - xPos += (float) charWidths[c]; + 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); + 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); + t->end(); + } + + if (m_underline) + renderStyleLine(x0, y1 - 1.0f, xPos + static_cast<float>(charWidths[c]), y1); + + if (m_strikethrough) + { + float mid = y0 + height * 0.5f; + renderStyleLine(x0, mid - 0.5f, xPos + static_cast<float>(charWidths[c]), mid + 0.5f); + } + + xPos += static_cast<float>(charWidths[c]); } void Font::drawShadow(const wstring& str, int x, int y, int color) @@ -176,6 +206,26 @@ void Font::drawShadow(const wstring& str, int x, int y, int color) draw(str, x, y, color, false); } +void Font::drawShadowLiteral(const wstring& str, int x, int y, int color) +{ + int shadowColor = (color & 0xFCFCFC) >> 2 | (color & 0xFF000000); + drawLiteral(str, x + 1, y + 1, shadowColor); + drawLiteral(str, x, y, color); +} + +void Font::drawLiteral(const wstring& str, int x, int y, int color) +{ + if (str.empty()) return; + if ((color & 0xFC000000) == 0) color |= 0xFF000000; + textures->bindTexture(m_textureLocation); + glColor4f((color >> 16 & 255) / 255.0F, (color >> 8 & 255) / 255.0F, (color & 255) / 255.0F, (color >> 24 & 255) / 255.0F); + xPos = static_cast<float>(x); + yPos = static_cast<float>(y); + wstring cleanStr = sanitize(str); + for (size_t i = 0; i < cleanStr.length(); ++i) + renderCharacter(cleanStr.at(i)); +} + void Font::drawShadowWordWrap(const wstring &str, int x, int y, int w, int color, int h) { drawWordWrapInternal(str, x + 1, y + 1, w, color, true, h); @@ -193,24 +243,38 @@ wstring Font::reorderBidi(const wstring &str) return str; } +static bool isSectionFormatCode(wchar_t ca) +{ + if ((ca >= L'0' && ca <= L'9') || (ca >= L'a' && ca <= L'f') || (ca >= L'A' && ca <= L'F')) + return true; + wchar_t l = static_cast<wchar_t>(ca | 32); + 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) { // Bind the texture textures->bindTexture(m_textureLocation); bool noise = false; + m_bold = m_italic = m_underline = m_strikethrough = false; wstring cleanStr = sanitize(str); - for (int i = 0; i < (int)cleanStr.length(); ++i) + for (int i = 0; i < static_cast<int>(cleanStr.length()); ++i) { // Map character wchar_t c = cleanStr.at(i); if (c == 167 && i + 1 < cleanStr.length()) { - // 4J - following block was: - // int colorN = L"0123456789abcdefk".indexOf(str.toLowerCase().charAt(i + 1)); wchar_t ca = cleanStr[i+1]; + if (!isSectionFormatCode(ca)) + { + renderCharacter(167); + renderCharacter(ca); + i += 1; + continue; + } int colorN = 16; if(( ca >= L'0' ) && (ca <= L'9')) colorN = ca - L'0'; else if(( ca >= L'a' ) && (ca <= L'f')) colorN = (ca - L'a') + 10; @@ -218,7 +282,13 @@ void Font::draw(const wstring &str, bool dropShadow) if (colorN == 16) { - noise = true; + wchar_t l = static_cast<wchar_t>(ca | 32); + if (l == L'l') m_bold = true; + 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'k') noise = true; } else { @@ -280,20 +350,34 @@ int Font::width(const wstring& str) { wchar_t c = cleanStr.at(i); - if(c == 167) + if (c == 167) { - // Ignore the character used to define coloured text - ++i; + if (i + 1 < cleanStr.length() && isSectionFormatCode(cleanStr[i+1])) + ++i; + else + { + len += charWidths[167]; + if (i + 1 < cleanStr.length()) + len += charWidths[static_cast<unsigned>(cleanStr[++i])]; + } } else - { len += charWidths[c]; - } } return len; } +int Font::widthLiteral(const wstring& str) +{ + wstring cleanStr = sanitize(str); + if (cleanStr == L"") return 0; + int len = 0; + for (size_t i = 0; i < cleanStr.length(); ++i) + len += charWidths[static_cast<unsigned>(cleanStr.at(i))]; + return len; +} + wstring Font::sanitize(const wstring& str) { wstring sb = str; @@ -467,7 +551,7 @@ void Font::setBidirectional(bool bidirectional) bool Font::AllCharactersValid(const wstring &str) { - for (int i = 0; i < (int)str.length(); ++i) + for (int i = 0; i < static_cast<int>(str.length()); ++i) { wchar_t c = str.at(i); @@ -512,15 +596,15 @@ void Font::renderFakeCB(IntBuffer *ib) float uo = (0.0f) / 128.0f; float vo = (0.0f) / 128.0f; - t->vertexUV((float)(0), (float)( 0 + s), (float)( 0), (float)( ix / 128.0f + uo), (float)( (iy + s) / 128.0f + vo)); - t->vertexUV((float)(0 + s), (float)( 0 + s), (float)( 0), (float)( (ix + s) / 128.0f + uo), (float)( (iy + s) / 128.0f + vo)); - t->vertexUV((float)(0 + s), (float)( 0), (float)( 0), (float)( (ix + s) / 128.0f + uo), (float)( iy / 128.0f + vo)); - t->vertexUV((float)(0), (float)( 0), (float)( 0), (float)( ix / 128.0f + uo), (float)( iy / 128.0f + vo)); + t->vertexUV(static_cast<float>(0), static_cast<float>(0 + s), static_cast<float>(0), static_cast<float>(ix / 128.0f + uo), static_cast<float>((iy + s) / 128.0f + vo)); + t->vertexUV(static_cast<float>(0 + s), static_cast<float>(0 + s), static_cast<float>(0), static_cast<float>((ix + s) / 128.0f + uo), static_cast<float>((iy + s) / 128.0f + vo)); + t->vertexUV(static_cast<float>(0 + s), static_cast<float>(0), static_cast<float>(0), static_cast<float>((ix + s) / 128.0f + uo), static_cast<float>(iy / 128.0f + vo)); + t->vertexUV(static_cast<float>(0), static_cast<float>(0), static_cast<float>(0), static_cast<float>(ix / 128.0f + uo), static_cast<float>(iy / 128.0f + vo)); // target.colorBlit(texture, x + xo, y, color, ix, iy, // charWidths[chars[i]], 8); t->end(); - glTranslatef((float)charWidths[i], 0, 0); + glTranslatef(static_cast<float>(charWidths[i]), 0, 0); } else { |
