First blood
This commit is contained in:
1 parent
04f270f322
commit
5720f8322b
250 files changed
+33215
No files matched your search
@@ -0,0 +1,479 @@
|
||||
#include "include/FontManager/FontManager.h"
|
||||
#include "include/Engine.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
namespace SE
|
||||
{
|
||||
|
||||
const float CONST_HEIGHT_COEF = 1.0f;
|
||||
|
||||
const int CONST_MAX_FONT_STACK_SIZE = 10;
|
||||
|
||||
|
||||
|
||||
TFontManager::~TFontManager()
|
||||
{
|
||||
*Console<<"TFontManager deleting...";
|
||||
}
|
||||
|
||||
void TFontManager::Serialize(boost::property_tree::ptree& propertyTree)
|
||||
{
|
||||
BOOST_FOREACH(boost::property_tree::ptree::value_type &v, propertyTree.get_child("Fonts"))
|
||||
{
|
||||
|
||||
std::string fontName = v.second.get<std::string>("FontName");
|
||||
std::string bitmapFileName = v.second.get<std::string>("BitmapFileName");
|
||||
std::string charmapFileName = v.second.get<std::string>("CharmapFileName");
|
||||
|
||||
AddFont(fontName, bitmapFileName, charmapFileName);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TFontManager::AddFont(const std::string& fontName, const std::string& bitmapFile, const std::string& charmapFile)
|
||||
{
|
||||
if (FontMap.count(fontName) > 0)
|
||||
{
|
||||
throw ErrorToLog("Trying to add font twice or some font files not found!" + fontName);
|
||||
}
|
||||
|
||||
TFont& currentFont = FontMap[fontName];
|
||||
|
||||
std::string texName = GetFileName(bitmapFile);
|
||||
|
||||
currentFont.TexName = texName;
|
||||
|
||||
ResourceManager->TexList.AddTexture(bitmapFile);
|
||||
|
||||
currentFont.SheetWidth = ResourceManager->TexList.GetTextureWidth(texName);
|
||||
currentFont.SheetHeight = ResourceManager->TexList.GetTextureHeight(texName);
|
||||
|
||||
cardinal byteCount;
|
||||
|
||||
boost::shared_array<char> charmapFileArr = boost::shared_array<char>(CreateMemFromFile<char>(ResourceManager->PathToResources+charmapFile, byteCount));
|
||||
|
||||
//Need to rewrite this code :(
|
||||
|
||||
TFontParams fontParams;
|
||||
cardinal character;
|
||||
|
||||
std::stringstream charmapFileStream;
|
||||
charmapFileStream.write(&charmapFileArr[0], byteCount);
|
||||
|
||||
while(!charmapFileStream.eof())
|
||||
{
|
||||
|
||||
charmapFileStream>>character;
|
||||
charmapFileStream>>fontParams.ShiftX;
|
||||
charmapFileStream>>fontParams.ShiftY;
|
||||
charmapFileStream>>fontParams.InternalShiftX;
|
||||
charmapFileStream>>fontParams.InternalShiftY;
|
||||
charmapFileStream>>fontParams.BitmapWidth;
|
||||
charmapFileStream>>fontParams.BitmapHeight;
|
||||
charmapFileStream>>fontParams.Advance;
|
||||
|
||||
currentFont.CharMap[character] = fontParams;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TFontManager::PushFont(const std::string& fontName)
|
||||
{
|
||||
if (FontStack.size() >= CONST_MAX_FONT_STACK_SIZE)
|
||||
{
|
||||
throw ErrorToLog("Error: font stack overflow!");
|
||||
}
|
||||
FontStack.push(fontName);
|
||||
}
|
||||
|
||||
void TFontManager::PopFont()
|
||||
{
|
||||
if (FontStack.size() == 0)
|
||||
{
|
||||
throw ErrorToLog("Error: font stack underflow!");
|
||||
}
|
||||
|
||||
FontStack.pop();
|
||||
}
|
||||
|
||||
std::string TFontManager::GetCurrentFontName()
|
||||
{
|
||||
if (FontStack.size() == 0)
|
||||
{
|
||||
throw ErrorToLog("Error: font stack underflow!");
|
||||
}
|
||||
|
||||
return FontStack.top();
|
||||
}
|
||||
|
||||
std::string TFontManager::GetCurrentFontTextureName()
|
||||
{
|
||||
return FontMap[GetCurrentFontName()].TexName;
|
||||
}
|
||||
|
||||
|
||||
float TFontManager::DrawChar(vec2 pos, cardinal character)
|
||||
{
|
||||
//Also see DrawCharToVBO
|
||||
|
||||
std::string fontName = GetCurrentFontName();
|
||||
|
||||
if (FontMap.count(fontName) == 0)
|
||||
{
|
||||
throw ErrorToLog("Trying to use unknown font! " + fontName);
|
||||
}
|
||||
|
||||
TFont& currentFont = FontMap[fontName];
|
||||
|
||||
TFontParams& fontParams = currentFont.CharMap[character];
|
||||
|
||||
int scale_y = currentFont.SheetHeight;
|
||||
int scale_x = currentFont.SheetWidth;
|
||||
|
||||
float height = scale_y*fontParams.BitmapHeight;
|
||||
|
||||
float width = scale_x*fontParams.BitmapWidth;
|
||||
|
||||
vec2 p1 = pos + vec2(+ scale_x*fontParams.InternalShiftX, -height- scale_y*fontParams.InternalShiftY);
|
||||
vec2 p2 = pos + vec2(width + scale_x*fontParams.InternalShiftX, - scale_y* fontParams.InternalShiftY);
|
||||
|
||||
vec2 t1 = vec2(fontParams.ShiftX,
|
||||
1 - fontParams.ShiftY - fontParams.BitmapHeight - fontParams.InternalShiftY);
|
||||
vec2 t2 = vec2(fontParams.ShiftX + fontParams.BitmapWidth,
|
||||
1 - fontParams.ShiftY - fontParams.InternalShiftY);
|
||||
|
||||
Renderer->DrawRect(p1, p2, t1, t2);
|
||||
|
||||
return fontParams.Advance*scale_x;
|
||||
}
|
||||
|
||||
float TFontManager::DrawCharToVBO(vec2 pos, cardinal character, TTriangleList& triangleList)
|
||||
{
|
||||
//Also see DrawChar
|
||||
|
||||
std::string fontName = GetCurrentFontName();
|
||||
|
||||
if (FontMap.count(fontName) == 0)
|
||||
{
|
||||
throw ErrorToLog("Trying to use unknown font! " + fontName);
|
||||
}
|
||||
|
||||
TFont& currentFont = FontMap[fontName];
|
||||
|
||||
TFontParams& fontParams = currentFont.CharMap[character];
|
||||
|
||||
int scale_y = currentFont.SheetHeight;
|
||||
int scale_x = currentFont.SheetWidth;
|
||||
|
||||
float height = scale_y*fontParams.BitmapHeight;
|
||||
|
||||
float width = scale_x*fontParams.BitmapWidth;
|
||||
|
||||
vec2 p1 = pos + vec2(+ scale_x*fontParams.InternalShiftX, -height - scale_y*fontParams.InternalShiftY);
|
||||
vec2 p2 = pos + vec2(width + scale_x*fontParams.InternalShiftX, - scale_y* fontParams.InternalShiftY);
|
||||
|
||||
|
||||
vec2 t1 = vec2(fontParams.ShiftX,
|
||||
1 - fontParams.ShiftY - fontParams.BitmapHeight - fontParams.InternalShiftY);
|
||||
vec2 t2 = vec2(fontParams.ShiftX + fontParams.BitmapWidth,
|
||||
1 - fontParams.ShiftY - fontParams.InternalShiftY);
|
||||
|
||||
/*
|
||||
vec2 p12 = vec2(p1.v[0], p2.v[1]);
|
||||
vec2 p21 = vec2(p2.v[0], p1.v[1]);
|
||||
|
||||
vec2 t12 = vec2(t1.v[0], t2.v[1]);
|
||||
vec2 t21 = vec2(t2.v[0], t1.v[1]);
|
||||
|
||||
|
||||
triangleList.Data.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(vec3(p1, 0));
|
||||
triangleList.Data.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(vec3(p12, 0));
|
||||
triangleList.Data.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(vec3(p2, 0));
|
||||
|
||||
triangleList.Data.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(vec3(p2, 0));
|
||||
triangleList.Data.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(vec3(p21, 0));
|
||||
triangleList.Data.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(vec3(p1, 0));
|
||||
|
||||
triangleList.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t1);
|
||||
triangleList.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t12);
|
||||
triangleList.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t2);
|
||||
|
||||
triangleList.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t2);
|
||||
triangleList.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t21);
|
||||
triangleList.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t1);
|
||||
*/
|
||||
triangleList.Data += MakeDataTriangleList(p1, p2, t1, t2);
|
||||
|
||||
return fontParams.Advance*scale_x;
|
||||
}
|
||||
|
||||
vec2 TFontManager::FitStringToBox(vec2 posFrom, vec2 posTo, TTextBasicAreaParams params, std::string& str)
|
||||
{
|
||||
//Need to make this deprecated!
|
||||
|
||||
throw ErrorToLog("Call to deprecated TFontManager::FitStringToBox");
|
||||
|
||||
std::string fontName = GetCurrentFontName();
|
||||
|
||||
float intervalY = CONST_HEIGHT_COEF * params.Height;
|
||||
|
||||
size_t rows = 1;
|
||||
|
||||
float maxWidth = posTo.v[0] - posFrom.v[0];
|
||||
|
||||
cardinal p = 0;
|
||||
vec2 cursor;
|
||||
|
||||
while (p<str.size())
|
||||
{
|
||||
char c = str[p];
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
cursor.v[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor.v[0] += GetCharAdvance(c);
|
||||
}
|
||||
if (cursor.v[0] > maxWidth)
|
||||
{
|
||||
str.insert(p, 1, '\n');
|
||||
cursor.v[0] = 0;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
size_t found = str.find_first_of('\n');
|
||||
|
||||
while (found != std::string::npos)
|
||||
{
|
||||
rows++;
|
||||
found = str.find_first_of('\n', found + 1);
|
||||
}
|
||||
|
||||
return vec2(posFrom.v[0], posFrom.v[1] + intervalY*rows);
|
||||
|
||||
}
|
||||
|
||||
|
||||
vec2 TFontManager::FitStringToBoxWithWordWrap(vec2 posFrom, vec2 posTo, TTextBasicAreaParams params, std::string& str)
|
||||
{
|
||||
|
||||
std::string fontName = GetCurrentFontName();
|
||||
|
||||
float intervalY = CONST_HEIGHT_COEF * params.Height;
|
||||
|
||||
size_t rows = 1;
|
||||
|
||||
//Apply padding:
|
||||
|
||||
posFrom.v[0] += params.HorizontalPadding;
|
||||
posTo.v[0] -= params.HorizontalPadding;
|
||||
posFrom.v[1] += params.VerticalPadding;
|
||||
posTo.v[1] -= params.VerticalPadding;
|
||||
|
||||
|
||||
float maxWidth = posTo.v[0] - posFrom.v[0];
|
||||
|
||||
|
||||
//cardinal p = 0;
|
||||
vec2 cursor;
|
||||
|
||||
|
||||
std::vector<std::string> explodedByParagraph;
|
||||
|
||||
boost::split(explodedByParagraph, str, boost::is_any_of("\n"), boost::token_compress_on);
|
||||
|
||||
std::string result;
|
||||
|
||||
|
||||
for (size_t i=0; i<explodedByParagraph.size(); i++)
|
||||
{
|
||||
std::vector<std::string> explodedByWord;
|
||||
|
||||
boost::split(explodedByWord, explodedByParagraph[i], boost::is_space(), boost::token_compress_on);
|
||||
|
||||
for (size_t j=0; j< explodedByWord.size(); j++)
|
||||
{
|
||||
std::string s = explodedByWord[j];
|
||||
|
||||
float adv = GetTextAdvance(s);
|
||||
|
||||
if (adv + cursor.v[0] < maxWidth)
|
||||
{
|
||||
result += s + " ";
|
||||
cursor.v[0] += adv + GetCharAdvance(' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
if (adv < maxWidth)
|
||||
{
|
||||
result += "\n" + s + " ";
|
||||
cursor.v[0] = adv + GetCharAdvance(' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int k=0; k<s.size(); k++)
|
||||
{
|
||||
result += s[k];
|
||||
cursor.v[0] += GetCharAdvance(s[k]);
|
||||
if (cursor.v[0] > maxWidth)
|
||||
{
|
||||
cursor.v[0] = 0;
|
||||
result += "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result += "\n";
|
||||
cursor.v[0] = 0;
|
||||
|
||||
}
|
||||
|
||||
//Erase last symbol \n
|
||||
result.erase(result.end()-1, result.end());
|
||||
|
||||
|
||||
str = result;
|
||||
|
||||
size_t found = str.find_first_of('\n');
|
||||
|
||||
while (found != std::string::npos)
|
||||
{
|
||||
rows++;
|
||||
found = str.find_first_of('\n', found + 1);
|
||||
}
|
||||
|
||||
vec2 result_vec = vec2(posFrom.v[0], posFrom.v[1] + intervalY*rows);
|
||||
|
||||
if (params.TextHorizontalAlignment == THA_RIGHT)
|
||||
{
|
||||
result_vec.v[0] = posTo.v[0];
|
||||
}
|
||||
else if (params.TextHorizontalAlignment == THA_CENTER)
|
||||
{
|
||||
result_vec.v[0] = (posTo.v[0] + posFrom.v[0])*0.5f;
|
||||
}
|
||||
|
||||
if (params.TextVerticalAlignment == TVA_TOP)
|
||||
{
|
||||
result_vec.v[1] = posTo.v[1];
|
||||
}
|
||||
else if (params.TextVerticalAlignment == TVA_CENTER)
|
||||
{
|
||||
result_vec.v[1] = (posTo.v[1] + posFrom.v[1])*0.5f;
|
||||
}
|
||||
|
||||
return result_vec;
|
||||
|
||||
}
|
||||
|
||||
TTriangleList TFontManager::DrawStringToVBO(vec2 pos, TTextBasicAreaParams params, const std::string& str)
|
||||
{
|
||||
|
||||
std::wstring ws;
|
||||
utf8toWStr(ws, str);
|
||||
|
||||
std::string fontName = GetCurrentFontName();
|
||||
|
||||
float width;
|
||||
|
||||
TTriangleList triangleList;
|
||||
|
||||
std::vector<std::wstring> rowArr;
|
||||
|
||||
boost::split(rowArr, ws, boost::algorithm::is_any_of("\n"));
|
||||
|
||||
vec2 startPos = pos;
|
||||
|
||||
float rowsHeight = rowArr.size() * CONST_HEIGHT_COEF*params.Height;
|
||||
|
||||
|
||||
BOOST_FOREACH(auto& rowStr, rowArr)
|
||||
{
|
||||
|
||||
float rowWidth = GetTextAdvance(rowStr);
|
||||
|
||||
for (cardinal i=0; i<rowStr.size(); i++)
|
||||
{
|
||||
vec2 realPos = pos;
|
||||
if (params.TextHorizontalAlignment == THA_RIGHT)
|
||||
{
|
||||
realPos.v[0] = realPos.v[0] - rowWidth;
|
||||
}
|
||||
else if (params.TextHorizontalAlignment == THA_CENTER)
|
||||
{
|
||||
realPos.v[0] = realPos.v[0] - rowWidth*0.5f;
|
||||
realPos.v[0] = floorf(realPos.v[0]);
|
||||
}
|
||||
|
||||
if (params.TextVerticalAlignment == TVA_CENTER)
|
||||
{
|
||||
realPos.v[1] = realPos.v[1] + rowsHeight*0.5f;
|
||||
realPos.v[1] = floorf(realPos.v[1]);
|
||||
}
|
||||
|
||||
width = DrawCharToVBO(realPos, rowStr[i], triangleList);
|
||||
|
||||
pos += vec2(width, 0);
|
||||
}
|
||||
|
||||
pos.v[1] -= CONST_HEIGHT_COEF*params.Height;
|
||||
pos.v[0] = startPos.v[0];
|
||||
}
|
||||
|
||||
triangleList.RefreshBuffer();
|
||||
|
||||
return triangleList;
|
||||
}
|
||||
|
||||
|
||||
void TFontManager::DrawString(vec2 pos, TTextBasicAreaParams params, const std::string& str)
|
||||
{
|
||||
TTriangleList triangleList = DrawStringToVBO(pos, params, str);
|
||||
|
||||
Renderer->DrawTriangleList(triangleList);
|
||||
|
||||
}
|
||||
|
||||
void TFontManager::DrawTextInBox(vec2 posFrom, vec2 posTo, TTextBasicAreaParams params, std::string str, bool wordWrap)
|
||||
{
|
||||
vec2 realPosFrom;
|
||||
if (wordWrap)
|
||||
{
|
||||
realPosFrom = FitStringToBoxWithWordWrap(posFrom, posTo, params, str);
|
||||
}
|
||||
else
|
||||
{
|
||||
realPosFrom = FitStringToBox(posFrom, posTo, params, str);
|
||||
}
|
||||
|
||||
DrawString(realPosFrom, params, str);
|
||||
}
|
||||
|
||||
TTriangleList TFontManager::DrawTextInBoxToVBO(vec2 posFrom, vec2 posTo, TTextBasicAreaParams params, std::string str, bool wordWrap)
|
||||
{
|
||||
|
||||
vec2 realPosFrom;
|
||||
if (wordWrap)
|
||||
{
|
||||
realPosFrom = FitStringToBoxWithWordWrap(posFrom, posTo, params, str);
|
||||
}
|
||||
else
|
||||
{
|
||||
realPosFrom = FitStringToBox(posFrom, posTo, params, str);
|
||||
}
|
||||
return DrawStringToVBO(realPosFrom, params, str);
|
||||
}
|
||||
|
||||
} //namespace SE
|
||||
Reference in new issue
Block a user