summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Dziwinski <piotrdz@gmail.com>2012-08-06 20:20:50 +0200
committerPiotr Dziwinski <piotrdz@gmail.com>2012-08-06 20:20:50 +0200
commitf7e78b21e9655604ba6fba1d068a9bf7f00b85a5 (patch)
tree51c54103d52ea420ea21608cdc9f9163959eb7bd
parent61bfb22f27f5216f989c023a5e39fad7e356d2d6 (diff)
downloadcolobot-f7e78b21e9655604ba6fba1d068a9bf7f00b85a5.tar.gz
colobot-f7e78b21e9655604ba6fba1d068a9bf7f00b85a5.tar.bz2
colobot-f7e78b21e9655604ba6fba1d068a9bf7f00b85a5.zip
Font rendering
- implemented rest of CText interface excluding some minor features
-rw-r--r--src/common/stringutils.cpp10
-rw-r--r--src/graphics/engine/engine.cpp37
-rw-r--r--src/graphics/engine/engine.h8
-rw-r--r--src/graphics/engine/text.cpp516
-rw-r--r--src/graphics/engine/text.h67
-rw-r--r--src/math/intpoint.h6
-rw-r--r--src/math/intsize.h6
7 files changed, 501 insertions, 149 deletions
diff --git a/src/common/stringutils.cpp b/src/common/stringutils.cpp
index 585bb46..12a3179 100644
--- a/src/common/stringutils.cpp
+++ b/src/common/stringutils.cpp
@@ -135,15 +135,11 @@ int StrUtils::Utf8CharSizeAt(const std::string &str, unsigned int pos)
size_t StrUtils::Utf8StringLength(const std::string &str)
{
size_t result = 0;
- for (unsigned int i = 0; i < str.size(); ++i)
+ unsigned int i = 0;
+ while (i < str.size())
{
- char ch = str[i];
- if ((ch & 0x80) == 0)
+ i += Utf8CharSizeAt(str, i);
++result;
- else if ((ch & 0xC0) == 0xC0)
- result += 2;
- else
- result += 3;
}
return result;
}
diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp
index 345a15c..c5d2a1d 100644
--- a/src/graphics/engine/engine.cpp
+++ b/src/graphics/engine/engine.cpp
@@ -447,6 +447,19 @@ void Gfx::CEngine::SetState(int state, Gfx::Color color)
m_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
m_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);*/
}
+ else if (state & Gfx::ENG_RSTATE_TEXT)
+ {
+ m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false);
+ m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false);
+ m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false);
+ m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true);
+ m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true);
+
+ m_device->SetTextureEnabled(0, true);
+ m_device->SetTextureStageParams(0, Gfx::TextureStageParams());
+
+ m_device->SetBlendFunc(Gfx::BLEND_SRC_ALPHA, Gfx::BLEND_INV_SRC_ALPHA);
+ }
else // normal ?
{
m_device->SetRenderState(Gfx::RENDER_STATE_FOG, true);
@@ -607,11 +620,33 @@ bool Gfx::CEngine::DrawInterface()
DrawMouse();
- m_text->DrawString("abcdefghijklmnopqrstuvwxyz ąęśćółńż", Gfx::FONT_COLOBOT, 15.0f, Math::Point(0.25f, 0.2f), 1.0f, 0);
+ std::vector<Gfx::FontMetaChar> format;
+ for (int i = 0; i < 10; ++i)
+ format.push_back(Gfx::FONT_COLOBOT_BOLD | Gfx::FONT_HIGHLIGHT_CONST);
+ for (int i = 0; i < 10; ++i)
+ format.push_back(Gfx::FONT_COLOBOT_ITALIC | Gfx::FONT_HIGHLIGHT_KEY);
+ for (int i = 0; i < 10; ++i)
+ format.push_back(Gfx::FONT_COURIER | Gfx::FONT_HIGHLIGHT_LINK);
+ for (int i = 0; i < 5; ++i)
+ format.push_back(Gfx::FONT_COURIER_BOLD | Gfx::FONT_HIGHLIGHT_REM);
+
+ m_text->DrawText("abcdefghijklmnopqrstuvwxyz ąęśćółńż", Gfx::FONT_COLOBOT, 15.0f, Math::Point(0.25f, 0.2f), 1.0f, Gfx::TEXT_ALIGN_LEFT, 0);
+ float h = m_text->GetHeight(Gfx::FONT_COLOBOT, 15.0f);
+ m_text->DrawText("abcdefghijklmnopqrstuvwxyz ąęśćółńż", format, 13.0f, Math::Point(0.25f, 0.2f - h), 1.0f, Gfx::TEXT_ALIGN_LEFT, 0);
return true;
}
+Math::IntSize Gfx::CEngine::GetWindowSize()
+{
+ return m_size;
+}
+
+Math::IntSize Gfx::CEngine::GetLastWindowSize()
+{
+ return m_lastSize;
+}
+
/** Conversion of the position of the mouse from window coords to interface coords:
- x: 0=left, 1=right
- y: 0=down, 1=up */
diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h
index 79844c6..3f7f4f2 100644
--- a/src/graphics/engine/engine.h
+++ b/src/graphics/engine/engine.h
@@ -408,7 +408,9 @@ enum EngineRenderState
//! The transparent color (black = no)
ENG_RSTATE_TCOLOR_BLACK = (1<<16),
//! The transparent color (white = no)
- ENG_RSTATE_TCOLOR_WHITE = (1<<17)
+ ENG_RSTATE_TCOLOR_WHITE = (1<<17),
+ //! Mode for rendering text
+ ENG_RSTATE_TEXT = (1<<18)
};
@@ -776,8 +778,8 @@ public:
Math::Vector GetLookatPt();
float GetEyeDirH();
float GetEyeDirV();
- Math::IntPoint GetViewportSize();
- Math::IntPoint GetLastViewportSize();
+ Math::IntSize GetWindowSize();
+ Math::IntSize GetLastWindowSize();
void UpdateMatProj();
void ApplyChange();
diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp
index eea9fdb..77515ad 100644
--- a/src/graphics/engine/text.cpp
+++ b/src/graphics/engine/text.cpp
@@ -150,118 +150,421 @@ void Gfx::CText::FlushCache()
}
void Gfx::CText::DrawText(const std::string &text, const std::vector<FontMetaChar> &format,
- Math::Point pos, float width, Gfx::JustifyType justify, float size,
- float stretch, int eol)
+ float size, Math::Point pos, float width, Gfx::TextAlign align,
+ int eol)
{
- // TODO
+ float sw = 0.0f;
+
+ if (align == Gfx::TEXT_ALIGN_CENTER)
+ {
+ sw = GetStringWidth(text, format, size);
+ if (sw > width) sw = width;
+ pos.x -= sw / 2.0f;
+ }
+ else if (align == Gfx::TEXT_ALIGN_RIGHT)
+ {
+ sw = GetStringWidth(text, format, size);
+ if (sw > width) sw = width;
+ pos.x -= sw;
+ }
+
+ DrawString(text, format, size, pos, width, eol);
}
void Gfx::CText::DrawText(const std::string &text, Gfx::FontType font,
- Math::Point pos, float width, Gfx::JustifyType justify, float size,
- float stretch, int eol)
+ float size, Math::Point pos, float width, Gfx::TextAlign align,
+ int eol)
{
- // TODO
+ float sw = 0.0f;
+
+ if (align == Gfx::TEXT_ALIGN_CENTER)
+ {
+ sw = GetStringWidth(text, font, size);
+ if (sw > width) sw = width;
+ pos.x -= sw / 2.0f;
+ }
+ else if (align == Gfx::TEXT_ALIGN_RIGHT)
+ {
+ sw = GetStringWidth(text, font, size);
+ if (sw > width) sw = width;
+ pos.x -= sw;
+ }
+
+ DrawString(text, font, size, pos, width, eol);
}
void Gfx::CText::SizeText(const std::string &text, const std::vector<FontMetaChar> &format,
- Math::Point pos, Gfx::JustifyType justify, float size,
+ float size, Math::Point pos, Gfx::TextAlign align,
Math::Point &start, Math::Point &end)
{
- // TODO
+ start = end = pos;
+
+ float sw = GetStringWidth(text, format, size);
+ end.x += sw;
+ if (align == Gfx::TEXT_ALIGN_CENTER)
+ {
+ start.x -= sw/2.0f;
+ end.x -= sw/2.0f;
+ }
+ else if (align == Gfx::TEXT_ALIGN_RIGHT)
+ {
+ start.x -= sw;
+ end.x -= sw;
+ }
+
+ start.y -= GetDescent(Gfx::FONT_COLOBOT, size);
+ end.y += GetAscent(Gfx::FONT_COLOBOT, size);
}
void Gfx::CText::SizeText(const std::string &text, Gfx::FontType font,
- Math::Point pos, Gfx::JustifyType justify, float size,
+ float size, Math::Point pos, Gfx::TextAlign align,
Math::Point &start, Math::Point &end)
{
- // TODO
+ start = end = pos;
+
+ float sw = GetStringWidth(text, font, size);
+ end.x += sw;
+ if (align == Gfx::TEXT_ALIGN_CENTER)
+ {
+ start.x -= sw/2.0f;
+ end.x -= sw/2.0f;
+ }
+ else if (align == Gfx::TEXT_ALIGN_RIGHT)
+ {
+ start.x -= sw;
+ end.x -= sw;
+ }
+
+ start.y -= GetDescent(font, size);
+ end.y += GetAscent(font, size);
}
float Gfx::CText::GetAscent(Gfx::FontType font, float size)
{
- // TODO
- return 0.0f;
+ assert(font != Gfx::FONT_BUTTON);
+
+ Gfx::CachedFont* cf = GetOrOpenFont(font, size);
+ assert(cf != nullptr);
+ Math::IntSize wndSize;
+ wndSize.h = TTF_FontAscent(cf->font);
+ Math::Size ifSize = m_engine->WindowToInterfaceSize(wndSize);
+ return ifSize.h;
}
float Gfx::CText::GetDescent(Gfx::FontType font, float size)
{
- // TODO
- return 0.0f;
+ assert(font != Gfx::FONT_BUTTON);
+
+ Gfx::CachedFont* cf = GetOrOpenFont(font, size);
+ assert(cf != nullptr);
+ Math::IntSize wndSize;
+ wndSize.h = TTF_FontDescent(cf->font);
+ Math::Size ifSize = m_engine->WindowToInterfaceSize(wndSize);
+ return ifSize.h;
}
float Gfx::CText::GetHeight(Gfx::FontType font, float size)
{
- // TODO
- return 0.0f;
+ assert(font != Gfx::FONT_BUTTON);
+
+ Gfx::CachedFont* cf = GetOrOpenFont(font, size);
+ assert(cf != nullptr);
+ Math::IntSize wndSize;
+ wndSize.h = TTF_FontHeight(cf->font);
+ Math::Size ifSize = m_engine->WindowToInterfaceSize(wndSize);
+ return ifSize.h;
}
float Gfx::CText::GetStringWidth(const std::string &text,
const std::vector<FontMetaChar> &format, float size)
{
- // TODO
- return 0.0f;
+ assert(StrUtils::Utf8StringLength(text) == format.size());
+
+ float width = 0.0f;
+ unsigned int index = 0;
+ unsigned int fmtIndex = 0;
+ while (index < text.length())
+ {
+ Gfx::FontType font = static_cast<Gfx::FontType>(format[fmtIndex] & Gfx::FONT_MASK_FONT);
+
+ Gfx::UTF8Char ch;
+
+ int len = StrUtils::Utf8CharSizeAt(text, index);
+ if (len >= 1)
+ ch.c1 = text[index];
+ if (len >= 2)
+ ch.c2 = text[index+1];
+ if (len >= 3)
+ ch.c3 = text[index+2];
+
+ width += GetCharWidth(ch, font, size, width);
+
+ index += len;
+ fmtIndex++;
+ }
+
+ return width;
}
float Gfx::CText::GetStringWidth(const std::string &text, Gfx::FontType font, float size)
{
- // TODO
- return 0.0f;
+ assert(font != Gfx::FONT_BUTTON);
+
+ // TODO: special chars?
+
+ Gfx::CachedFont* cf = GetOrOpenFont(font, size);
+ assert(cf != nullptr);
+ Math::IntSize wndSize;
+ TTF_SizeUTF8(cf->font, text.c_str(), &wndSize.w, &wndSize.h);
+ Math::Size ifSize = m_engine->WindowToInterfaceSize(wndSize);
+ return ifSize.w;
}
-float Gfx::CText::GetCharWidth(int character, Gfx::FontType font, float size, float offset)
+float Gfx::CText::GetCharWidth(Gfx::UTF8Char ch, Gfx::FontType font, float size, float offset)
{
- // TODO
- return 0.0f;
+ // TODO: if (font == Gfx::FONT_BUTTON)
+ if (font == Gfx::FONT_BUTTON) return 0.0f;
+
+ // TODO: special chars?
+ // TODO: tab sizing
+
+ Gfx::CachedFont* cf = GetOrOpenFont(font, size);
+ assert(cf != nullptr);
+
+ Gfx::CharTexture tex;
+ auto it = cf->cache.find(ch);
+ if (it != cf->cache.end())
+ tex = (*it).second;
+ else
+ tex = CreateCharTexture(ch, cf);
+
+ return tex.charSize.w;
}
int Gfx::CText::Justify(const std::string &text, const std::vector<FontMetaChar> &format,
float size, float width)
{
- // TODO
- return 0;
+ assert(StrUtils::Utf8StringLength(text) == format.size());
+
+ float pos = 0.0f;
+ int cut = 0;
+ unsigned int index = 0;
+ unsigned int fmtIndex = 0;
+ while (index < text.length())
+ {
+ Gfx::FontType font = static_cast<Gfx::FontType>(format[fmtIndex] & Gfx::FONT_MASK_FONT);
+
+ Gfx::UTF8Char ch;
+
+ int len = StrUtils::Utf8CharSizeAt(text, index);
+ if (len >= 1)
+ ch.c1 = text[index];
+ if (len >= 2)
+ ch.c2 = text[index+1];
+ if (len >= 3)
+ ch.c3 = text[index+2];
+
+ if (font != Gfx::FONT_BUTTON)
+ {
+ if (ch.c1 == '\n')
+ return index+1;
+ if (ch.c1 == ' ')
+ cut = index+1;
+ }
+
+ pos += GetCharWidth(ch, font, size, pos);
+ if (pos > width)
+ {
+ if (cut == 0) return index;
+ else return cut;
+ }
+
+ index += len;
+ fmtIndex++;
+ }
+
+ return index;
}
int Gfx::CText::Justify(const std::string &text, Gfx::FontType font, float size, float width)
{
- // TODO
- return 0;
+ assert(font != Gfx::FONT_BUTTON);
+
+ float pos = 0.0f;
+ int cut = 0;
+ unsigned int index = 0;
+ while (index < text.length())
+ {
+ Gfx::UTF8Char ch;
+
+ int len = StrUtils::Utf8CharSizeAt(text, index);
+ if (len >= 1)
+ ch.c1 = text[index];
+ if (len >= 2)
+ ch.c2 = text[index+1];
+ if (len >= 3)
+ ch.c3 = text[index+2];
+
+ index += len;
+
+ if (ch.c1 == '\n')
+ return index+1;
+
+ if (ch.c1 == ' ' )
+ cut = index+1;
+
+ pos += GetCharWidth(ch, font, size, pos);
+ if (pos > width)
+ {
+ if (cut == 0) return index;
+ else return cut;
+ }
+ }
+
+ return index;
}
int Gfx::CText::Detect(const std::string &text, const std::vector<FontMetaChar> &format,
float size, float offset)
{
- // TODO
- return 0;
+ assert(StrUtils::Utf8StringLength(text) == format.size());
+
+ float pos = 0.0f;
+ unsigned int index = 0;
+ unsigned int fmtIndex = 0;
+ while (index < text.length())
+ {
+ Gfx::FontType font = static_cast<Gfx::FontType>(format[fmtIndex] & Gfx::FONT_MASK_FONT);
+
+ // TODO: if (font == Gfx::FONT_BUTTON)
+ if (font == Gfx::FONT_BUTTON) continue;
+
+ Gfx::UTF8Char ch;
+
+ int len = StrUtils::Utf8CharSizeAt(text, index);
+ if (len >= 1)
+ ch.c1 = text[index];
+ if (len >= 2)
+ ch.c2 = text[index+1];
+ if (len >= 3)
+ ch.c3 = text[index+2];
+
+ if (ch.c1 == '\n')
+ return index;
+
+ float width = GetCharWidth(ch, font, size, pos);
+ if (offset <= pos + width/2.0f)
+ return index;
+
+ pos += width;
+ index += len;
+ fmtIndex++;
+ }
+
+ return index;
}
int Gfx::CText::Detect(const std::string &text, Gfx::FontType font, float size, float offset)
{
- // TODO
- return 0;
+ assert(font != Gfx::FONT_BUTTON);
+
+ float pos = 0.0f;
+ unsigned int index = 0;
+ while (index < text.length())
+ {
+ Gfx::UTF8Char ch;
+
+ int len = StrUtils::Utf8CharSizeAt(text, index);
+ if (len >= 1)
+ ch.c1 = text[index];
+ if (len >= 2)
+ ch.c2 = text[index+1];
+ if (len >= 3)
+ ch.c3 = text[index+2];
+
+ index += len;
+
+ if (ch.c1 == '\n')
+ return index;
+
+ float width = GetCharWidth(ch, font, size, pos);
+ if (offset <= pos + width/2.0f)
+ return index;
+
+ pos += width;
+ }
+
+ return index;
}
void Gfx::CText::DrawString(const std::string &text, const std::vector<FontMetaChar> &format,
float size, Math::Point pos, float width, int eol)
{
- // TODO
+ assert(StrUtils::Utf8StringLength(text) == format.size());
+
+ m_engine->SetState(Gfx::ENG_RSTATE_TEXT);
+
+ Gfx::FontType font = Gfx::FONT_COLOBOT;
+ float start = pos.x;
+
+ unsigned int index = 0;
+ unsigned int fmtIndex = 0;
+ while (index < text.length())
+ {
+ font = static_cast<Gfx::FontType>(format[fmtIndex] & Gfx::FONT_MASK_FONT);
+
+ // TODO: if (font == Gfx::FONT_BUTTON)
+ if (font == Gfx::FONT_BUTTON) continue;
+
+ Gfx::UTF8Char ch;
+
+ int len = StrUtils::Utf8CharSizeAt(text, index);
+ if (len >= 1)
+ ch.c1 = text[index];
+ if (len >= 2)
+ ch.c2 = text[index+1];
+ if (len >= 3)
+ ch.c3 = text[index+2];
+
+ float offset = pos.x - start;
+ float cw = GetCharWidth(ch, font, size, offset);
+ if (offset + cw > width) // exceeds the maximum width?
+ {
+ // TODO: special end-of-line char
+ break;
+ }
+
+ Gfx::FontHighlight hl = static_cast<Gfx::FontHighlight>(format[fmtIndex] & Gfx::FONT_MASK_HIGHLIGHT);
+ if (hl != Gfx::FONT_HIGHLIGHT_NONE)
+ {
+ Math::Size charSize;
+ charSize.w = GetCharWidth(ch, font, size, offset);
+ charSize.h = GetHeight(font, size);
+ DrawHighlight(hl, pos, charSize);
+ }
+
+ DrawChar(ch, font, size, pos);
+
+ index += len;
+ fmtIndex++;
+ }
+
+ // TODO: eol
}
void Gfx::CText::DrawString(const std::string &text, Gfx::FontType font,
float size, Math::Point pos, float width, int eol)
{
- m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true);
- m_device->SetTextureEnabled(0, true);
+ assert(font != Gfx::FONT_BUTTON);
- m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true);
- m_device->SetBlendFunc(Gfx::BLEND_SRC_ALPHA, Gfx::BLEND_INV_SRC_ALPHA);
+ m_engine->SetState(Gfx::ENG_RSTATE_TEXT);
unsigned int index = 0;
- Math::Point screenPos = pos;
while (index < text.length())
{
- UTF8Char ch;
+ Gfx::UTF8Char ch;
int len = StrUtils::Utf8CharSizeAt(text, index);
if (len >= 1)
@@ -273,56 +576,64 @@ void Gfx::CText::DrawString(const std::string &text, Gfx::FontType font,
index += len;
- DrawChar(ch, font, size, screenPos);
+ DrawChar(ch, font, size, pos);
}
}
-void Gfx::CText::DrawColor(int color, float size, Math::Point pos, float width)
+void Gfx::CText::DrawHighlight(Gfx::FontHighlight hl, Math::Point pos, Math::Size size)
{
- // TODO !!!
- /*
- float h, u1, u2, v1, v2, dp;
- int icon;
+ // Gradient colors
+ Gfx::Color grad[4];
+
+ // TODO: switch to alpha factors
- int icon = -1;
- switch (color)
+ switch (hl)
{
- case Gfx::FONT_COLOR_LINK:
- icon = 9;
+ case Gfx::FONT_HIGHLIGHT_LINK:
+ grad[0] = grad[1] = grad[2] = grad[3] = Gfx::Color(0.0f, 0.0f, 1.0f, 0.5f);
break;
- case Gfx::FONT_COLOR_TOKEN:
- icon = 4;
+
+ case Gfx::FONT_HIGHLIGHT_TOKEN:
+ grad[0] = grad[1] = Gfx::Color(248.0f / 256.0f, 248.0f / 256.0f, 248.0f / 256.0f, 0.5f);
+ grad[2] = grad[3] = Gfx::Color(248.0f / 256.0f, 220.0f / 256.0f, 188.0f / 256.0f, 0.5f);
break;
- case Gfx::FONT_COLOR_TYPE:
- icon = 5;
+
+ case Gfx::FONT_HIGHLIGHT_TYPE:
+ grad[0] = grad[1] = Gfx::Color(248.0f / 256.0f, 248.0f / 256.0f, 248.0f / 256.0f, 0.5f);
+ grad[2] = grad[3] = Gfx::Color(169.0f / 256.0f, 234.0f / 256.0f, 169.0f / 256.0f, 0.5f);
break;
- }
- icon = -1;
- if ( color == COLOR_LINK ) icon = 9; // blue
- if ( color == COLOR_TOKEN ) icon = 4; // orange
- if ( color == COLOR_TYPE ) icon = 5; // green
- if ( color == COLOR_CONST ) icon = 8; // red
- if ( color == COLOR_REM ) icon = 6; // magenta
- if ( color == COLOR_KEY ) icon = 10; // gray
- if ( icon == -1 ) return;
+ case Gfx::FONT_HIGHLIGHT_CONST:
+ grad[0] = grad[1] = Gfx::Color(248.0f / 256.0f, 248.0f / 256.0f, 248.0f / 256.0f, 0.5f);
+ grad[2] = grad[3] = Gfx::Color(248.0f / 256.0f, 176.0f / 256.0f, 169.0f / 256.0f, 0.5f);
+ break;
- if ( color == COLOR_LINK )
- {
- m_engine->SetState(D3DSTATENORMAL);
+ case Gfx::FONT_HIGHLIGHT_REM:
+ grad[0] = grad[1] = Gfx::Color(248.0f / 256.0f, 248.0f / 256.0f, 248.0f / 256.0f, 0.5f);
+ grad[2] = grad[3] = Gfx::Color(248.0f / 256.0f, 169.0f / 256.0f, 248.0f / 256.0f, 0.5f);
+ break;
+
+ case Gfx::FONT_HIGHLIGHT_KEY:
+ grad[0] = grad[1] = grad[2] = grad[3] =
+ Gfx::Color(192.0f / 256.0f, 192.0f / 256.0f, 192.0f / 256.0f, 0.5f);
+ break;
+
+ default:
+ return;
}
- Math::IntSize vsize = m_engine->GetViewportSize();
- if (vsize.h <= 768.0f) // 1024x768 or less?
- h = 1.01f / dim.y; // 1 pixel
- else // more than 1024x768?
- h = 2.0f / dim.y; // 2 pixels
+ Math::IntSize vsize = m_engine->GetWindowSize();
+ float h = 0.0f;
+ if (vsize.h <= 768.0f) // 1024x768 or less?
+ h = 1.01f / vsize.h; // 1 pixel
+ else // more than 1024x768?
+ h = 2.0f / vsize.h; // 2 pixels
Math::Point p1, p2;
p1.x = pos.x;
- p2.x = pos.x + width;
+ p2.x = pos.x + size.w;
- if (color == Gfx::FONT_COLOR_LINK)
+ if (hl == Gfx::FONT_HIGHLIGHT_LINK)
{
p1.y = pos.y;
p2.y = pos.y + h; // just emphasized
@@ -330,45 +641,38 @@ void Gfx::CText::DrawColor(int color, float size, Math::Point pos, float width)
else
{
p1.y = pos.y;
- p2.y = pos.y + (16.0f/256.0f)*(size/20.0f);
+ p2.y = pos.y + size.h;
}
- u1 = (16.0f/256.0f)*(icon%16);
- v1 = (240.0f/256.0f);
- u2 = (16.0f/256.0f)+u1;
- v2 = (16.0f/256.0f)+v1;
-
- dp = 0.5f/256.0f;
- u1 += dp;
- v1 += dp;
- u2 -= dp;
- v2 -= dp;
+ m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, false);
- Math::Vector n(0.0f, 0.0f, -1.0f); // normal
-
- Gfx::Vertex quad[] =
+ Gfx::VertexCol quad[] =
{
- Gfx::Vertex(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(u1, v2)),
- Gfx::Vertex(Math::Vector(p1.x, p2.y, 0.0f), n, Math::Point(u1, v1)),
- Gfx::Vertex(Math::Vector(p2.x, p1.y, 0.0f), n, Math::Point(u2, v2)),
- Gfx::Vertex(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(u2, v1)),
+ Gfx::VertexCol(Math::Vector(p1.x, p1.y, 0.0f), grad[3]),
+ Gfx::VertexCol(Math::Vector(p2.x, p1.y, 0.0f), grad[2]),
+ Gfx::VertexCol(Math::Vector(p1.x, p2.y, 0.0f), grad[0]),
+ Gfx::VertexCol(Math::Vector(p2.x, p2.y, 0.0f), grad[1])
};
m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4);
m_engine->AddStatisticTriangle(2);
- if (color == Gfx::FONT_COLOR_LINK)
- m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_WHITE);*/
+ m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true);
}
-void Gfx::CText::DrawChar(UTF8Char character, Gfx::FontType font, float size, Math::Point &pos)
+void Gfx::CText::DrawChar(Gfx::UTF8Char ch, Gfx::FontType font, float size, Math::Point &pos)
{
+ // TODO: if (font == Gfx::FONT_BUTTON)
+ if (font == Gfx::FONT_BUTTON) return;
+
+ // TODO: special chars?
+
CachedFont* cf = GetOrOpenFont(font, size);
if (cf == nullptr)
return;
- auto it = cf->cache.find(character);
+ auto it = cf->cache.find(ch);
CharTexture tex;
if (it != cf->cache.end())
{
@@ -376,31 +680,32 @@ void Gfx::CText::DrawChar(UTF8Char character, Gfx::FontType font, float size, Ma
}
else
{
- char str[] = { character.c1, character.c2, character.c3, '\0' };
- tex = CreateCharTexture(str, cf);
+ tex = CreateCharTexture(ch, cf);
if (tex.id == 0) // invalid
return;
- cf->cache[character] = tex;
+ cf->cache[ch] = tex;
}
+ m_device->SetRenderState(Gfx::RENDER_STATE_CULLING, false);
+
+ Math::Point p1(pos.x, pos.y + tex.charSize.h - tex.texSize.h);
+ Math::Point p2(pos.x + tex.texSize.w, pos.y + tex.charSize.h);
+
Math::Vector n(0.0f, 0.0f, -1.0f); // normal
Gfx::Vertex quad[4] =
{
- Gfx::Vertex(Math::Vector(pos.x, pos.y + tex.charSize.h, 0.0f),
- n, Math::Point(0.0f, 0.0f)),
- Gfx::Vertex(Math::Vector(pos.x, pos.y + tex.charSize.h - tex.texSize.h, 0.0f),
- n, Math::Point(0.0f, 1.0f)),
- Gfx::Vertex(Math::Vector(pos.x + tex.texSize.w, pos.y + tex.charSize.h, 0.0f),
- n, Math::Point(1.0f, 0.0f)),
- Gfx::Vertex(Math::Vector(pos.x + tex.texSize.w, pos.y + tex.charSize.h - tex.texSize.h, 0.0f),
- n, Math::Point(1.0f, 1.0f))
+ Gfx::Vertex(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(0.0f, 1.0f)),
+ Gfx::Vertex(Math::Vector(p2.x, p1.y, 0.0f), n, Math::Point(1.0f, 1.0f)),
+ Gfx::Vertex(Math::Vector(p1.x, p2.y, 0.0f), n, Math::Point(0.0f, 0.0f)),
+ Gfx::Vertex(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(1.0f, 0.0f))
};
m_device->SetTexture(0, tex.id);
m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4);
+ m_engine->AddStatisticTriangle(2);
pos.x += tex.charSize.w;
}
@@ -446,12 +751,13 @@ Gfx::CachedFont* Gfx::CText::GetOrOpenFont(Gfx::FontType font, float size)
return m_lastCachedFont;
}
-Gfx::CharTexture Gfx::CText::CreateCharTexture(const char* str, Gfx::CachedFont* font)
+Gfx::CharTexture Gfx::CText::CreateCharTexture(Gfx::UTF8Char ch, Gfx::CachedFont* font)
{
CharTexture texture;
SDL_Surface* textSurface = nullptr;
SDL_Color white = {255, 255, 255, 0};
+ char str[] = { ch.c1, ch.c2, ch.c3, '\0' };
textSurface = TTF_RenderUTF8_Blended(font->font, str, white);
if (textSurface == nullptr)
diff --git a/src/graphics/engine/text.h b/src/graphics/engine/text.h
index 19d9882..6209c39 100644
--- a/src/graphics/engine/text.h
+++ b/src/graphics/engine/text.h
@@ -38,9 +38,9 @@ const float FONT_SIZE_SMALL = 10.0f;
const float FONT_SIZE_BIG = 15.0f;
/**
- \enum TextAlignType
+ \enum TextAlign
\brief Type of text alignment */
-enum JustifyType
+enum TextAlign
{
TEXT_ALIGN_RIGHT,
TEXT_ALIGN_LEFT,
@@ -86,6 +86,8 @@ enum FontType
\enum FontTitle
\brief Size of font title
+ Used internally by CEdit
+
Bitmask in 2 bits left shifted 4 (mask 0x030) */
enum FontTitle
{
@@ -95,19 +97,20 @@ enum FontTitle
};
/**
- \enum FontColor
- \brief Font color type (?)
+ \enum FontHighlight
+ \brief Type of color highlight for text
Bitmask in 3 bits left shifted 6 (mask 0x1c0) */
-enum FontColor
+enum FontHighlight
{
- FONT_COLOR_LINK = 0x01 << 6,
- FONT_COLOR_TOKEN = 0x02 << 6,
- FONT_COLOR_TYPE = 0x03 << 6,
- FONT_COLOR_CONST = 0x04 << 6,
- FONT_COLOR_REM = 0x05 << 6,
- FONT_COLOR_KEY = 0x06 << 6,
- FONT_COLOR_TABLE = 0x07 << 6,
+ FONT_HIGHLIGHT_NONE = 0x00 << 6,
+ FONT_HIGHLIGHT_LINK = 0x01 << 6,
+ FONT_HIGHLIGHT_TOKEN = 0x02 << 6,
+ FONT_HIGHLIGHT_TYPE = 0x03 << 6,
+ FONT_HIGHLIGHT_CONST = 0x04 << 6,
+ FONT_HIGHLIGHT_REM = 0x05 << 6,
+ FONT_HIGHLIGHT_KEY = 0x06 << 6,
+ FONT_HIGHLIGHT_TABLE = 0x07 << 6,
};
/**
@@ -119,9 +122,9 @@ enum FontMask
FONT_MASK_FONT = 0x00f,
//! Mask for FontTitle
FONT_MASK_TITLE = 0x030,
- //! Mask for FontColor
- FONT_MASK_COLOR = 0x1c0,
- //! Mask for image bit
+ //! Mask for FontHighlight
+ FONT_MASK_HIGHLIGHT = 0x1c0,
+ //! Mask for image bit (TODO: not used?)
FONT_MASK_IMAGE = 0x200
};
@@ -190,7 +193,17 @@ struct MultisizeFont
\class CText
\brief Text rendering engine
- ... */
+ CText is responsible for drawing text in 2D interface. Font rendering is done using
+ textures generated by SDL_ttf from TTF font files.
+
+ All functions rendering text are divided into two types:
+ - single font - function takes a single Gfx::FontType argument that (along with size)
+ determines the font to be used for all characters,
+ - multi-font - function takes the text as one argument and a std::vector of FontMetaChar
+ with per-character formatting information (font, highlights and some other info used by CEdit)
+
+ All font rendering is done in UTF-8.
+*/
class CText
{
public:
@@ -213,20 +226,20 @@ public:
//! Draws text (multi-format)
void DrawText(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
- Math::Point pos, float width, Gfx::JustifyType justify, float size,
- float stretch, int eol);
+ float size, Math::Point pos, float width, Gfx::TextAlign align,
+ int eol);
//! Draws text (one font)
void DrawText(const std::string &text, Gfx::FontType font,
- Math::Point pos, float width, Gfx::JustifyType justify, float size,
- float stretch, int eol);
+ float size, Math::Point pos, float width, Gfx::TextAlign align,
+ int eol);
//! Calculates dimensions for text (multi-format)
void SizeText(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
- Math::Point pos, Gfx::JustifyType justify, float size,
+ float size, Math::Point pos, Gfx::TextAlign align,
Math::Point &start, Math::Point &end);
//! Calculates dimensions for text (one font)
void SizeText(const std::string &text, Gfx::FontType font,
- Math::Point pos, Gfx::JustifyType justify, float size,
+ float size, Math::Point pos, Gfx::TextAlign align,
Math::Point &start, Math::Point &end);
//! Returns the ascent font metric
@@ -242,7 +255,7 @@ public:
//! Returns width of string (single font)
float GetStringWidth(const std::string &text, Gfx::FontType font, float size);
//! Returns width of single character
- float GetCharWidth(int character, Gfx::FontType font, float size, float offset);
+ float GetCharWidth(Gfx::UTF8Char ch, Gfx::FontType font, float size, float offset);
//! Justifies a line of text (multi-format)
int Justify(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
@@ -256,16 +269,16 @@ public:
//! Returns the most suitable position to a given offset (one font)
int Detect(const std::string &text, Gfx::FontType font, float size, float offset);
-public: // for testing!
+protected:
Gfx::CachedFont* GetOrOpenFont(Gfx::FontType type, float size);
- Gfx::CharTexture CreateCharTexture(const char* utf8Char, Gfx::CachedFont* font);
+ Gfx::CharTexture CreateCharTexture(Gfx::UTF8Char ch, Gfx::CachedFont* font);
void DrawString(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
float size, Math::Point pos, float width, int eol);
void DrawString(const std::string &text, Gfx::FontType font,
float size, Math::Point pos, float width, int eol);
- void DrawColor(int color, float size, Math::Point pos, float width);
- void DrawChar(UTF8Char character, Gfx::FontType font, float size, Math::Point &pos);
+ void DrawHighlight(Gfx::FontHighlight hl, Math::Point pos, Math::Size size);
+ void DrawChar(Gfx::UTF8Char ch, Gfx::FontType font, float size, Math::Point &pos);
protected:
CInstanceManager* m_iMan;
diff --git a/src/math/intpoint.h b/src/math/intpoint.h
index a760bc2..476e67b 100644
--- a/src/math/intpoint.h
+++ b/src/math/intpoint.h
@@ -32,11 +32,11 @@ namespace Math {
struct IntPoint
{
//! X coord
- long x;
+ int x;
//! Y coord
- long y;
+ int y;
- IntPoint(long aX = 0, long aY = 0) : x(aX), y(aY) {}
+ IntPoint(int aX = 0, int aY = 0) : x(aX), y(aY) {}
};
/* @} */ // end of group
diff --git a/src/math/intsize.h b/src/math/intsize.h
index d53de85..c88f09b 100644
--- a/src/math/intsize.h
+++ b/src/math/intsize.h
@@ -34,9 +34,9 @@ namespace Math
struct IntSize
{
//! Width
- long w;
+ int w;
//! Height
- long h;
+ int h;
//! Constructs a zero size: (0,0)
inline IntSize()
@@ -45,7 +45,7 @@ struct IntSize
}
//! Constructs a size from given dimensions: (w,h)
- inline explicit IntSize(long w, long h)
+ inline explicit IntSize(int w, int h)
{
this->w = w;
this->h = h;