Font rendering
- implemented rest of CText interface excluding some minor featuresdev-ui
parent
61bfb22f27
commit
f7e78b21e9
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -150,118 +150,254 @@ 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;
|
||||
}
|
||||
|
||||
int Gfx::CText::Detect(const std::string &text, const std::vector<FontMetaChar> &format,
|
||||
float size, float offset)
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Gfx::CText::Detect(const std::string &text, Gfx::FontType font, float size, float offset)
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Gfx::CText::DrawString(const std::string &text, const std::vector<FontMetaChar> &format,
|
||||
float size, Math::Point pos, float width, int eol)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true);
|
||||
m_device->SetBlendFunc(Gfx::BLEND_SRC_ALPHA, Gfx::BLEND_INV_SRC_ALPHA);
|
||||
assert(font != Gfx::FONT_BUTTON);
|
||||
|
||||
float pos = 0.0f;
|
||||
int cut = 0;
|
||||
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 +409,231 @@ void Gfx::CText::DrawString(const std::string &text, Gfx::FontType font,
|
|||
|
||||
index += len;
|
||||
|
||||
DrawChar(ch, font, size, screenPos);
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
assert(font != Gfx::FONT_BUTTON);
|
||||
|
||||
m_engine->SetState(Gfx::ENG_RSTATE_TEXT);
|
||||
|
||||
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;
|
||||
|
||||
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];
|
||||
|
||||
int icon = -1;
|
||||
switch (color)
|
||||
// TODO: switch to alpha factors
|
||||
|
||||
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;
|
||||
break;
|
||||
case Gfx::FONT_COLOR_TYPE:
|
||||
icon = 5;
|
||||
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_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;
|
||||
|
||||
if ( color == COLOR_LINK )
|
||||
{
|
||||
m_engine->SetState(D3DSTATENORMAL);
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, false);
|
||||
|
||||
dp = 0.5f/256.0f;
|
||||
u1 += dp;
|
||||
v1 += dp;
|
||||
u2 -= dp;
|
||||
v2 -= dp;
|
||||
|
||||
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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue