Added proper text alignment to the Font class.

Multiline text is now centered/right-aligned correctly.
This commit is contained in:
Aloshi 2014-05-12 20:03:02 -05:00
parent 4cf206d3eb
commit 5d0df7acf8
4 changed files with 62 additions and 51 deletions

View file

@ -82,22 +82,7 @@ void TextComponent::render(const Eigen::Affine3f& parentTrans)
if(mTextCache)
{
const Eigen::Vector2f& textSize = mTextCache->metrics.size;
Eigen::Vector3f off(0, 0, 0);
switch(mAlignment)
{
case ALIGN_LEFT:
off << 0, (getSize().y() - textSize.y()) / 2, 0;
break;
case ALIGN_CENTER:
off << (getSize().x() - textSize.x()) / 2, (getSize().y() - textSize.y()) / 2, 0;
break;
case ALIGN_RIGHT:
off << (getSize().x() - textSize.x()), (getSize().y() - textSize.y()) / 2, 0;
break;
}
Eigen::Vector3f off(0, (getSize().y() - textSize.y()) / 2.0f, 0);
if(Settings::getInstance()->getBool("DebugText"))
{
@ -112,7 +97,20 @@ void TextComponent::render(const Eigen::Affine3f& parentTrans)
// draw the text area, where the text actually is going
if(Settings::getInstance()->getBool("DebugText"))
Renderer::drawRect(0.0f, 0.0f, mTextCache->metrics.size.x(), mTextCache->metrics.size.y(), 0x00000033);
{
switch(mAlignment)
{
case ALIGN_LEFT:
Renderer::drawRect(0.0f, 0.0f, mTextCache->metrics.size.x(), mTextCache->metrics.size.y(), 0x00000033);
break;
case ALIGN_CENTER:
Renderer::drawRect((mSize.x() - mTextCache->metrics.size.x()) / 2.0f, 0.0f, mTextCache->metrics.size.x(), mTextCache->metrics.size.y(), 0x00000033);
break;
case ALIGN_RIGHT:
Renderer::drawRect(mSize.x() - mTextCache->metrics.size.x(), 0.0f, mTextCache->metrics.size.x(), mTextCache->metrics.size.y(), 0x00000033);
break;
}
}
mFont->renderTextCache(mTextCache.get());
}
@ -140,7 +138,7 @@ void TextComponent::onTextChanged()
std::string text = mUppercase ? strToUpper(mText) : mText;
std::shared_ptr<Font> f = getFont();
const bool wrap = (mSize.y() == 0 || (int)mSize.y() > f->getHeight());
const bool wrap = (mSize.y() == 0 || mSize.y() > f->getHeight()*1.2f);
Eigen::Vector2f size = f->sizeText(text);
if(!wrap && mSize.x() && text.size() && size.x() > mSize.x())
{
@ -156,9 +154,9 @@ void TextComponent::onTextChanged()
text.append(abbrev);
mTextCache = std::shared_ptr<TextCache>(f->buildTextCache(text, 0, 0, (mColor >> 8 << 8) | mOpacity));
mTextCache = std::shared_ptr<TextCache>(f->buildTextCache(text, Eigen::Vector2f(0, 0), (mColor >> 8 << 8) | mOpacity, mSize.x(), mAlignment));
}else{
mTextCache = std::shared_ptr<TextCache>(f->buildTextCache(f->wrapText(text, mSize.x()), 0, 0, (mColor >> 8 << 8) | mOpacity));
mTextCache = std::shared_ptr<TextCache>(f->buildTextCache(f->wrapText(text, mSize.x()), Eigen::Vector2f(0, 0), (mColor >> 8 << 8) | mOpacity, mSize.x(), mAlignment));
}
}

View file

@ -386,6 +386,27 @@ Eigen::Vector2f Font::getWrappedTextCursorOffset(std::string text, float xLen, i
//TextCache
//=============================================================================================================
float Font::getNewlineStartOffset(const std::string& text, const unsigned int& charStart, const float& xLen, const Alignment& alignment)
{
switch(alignment)
{
case ALIGN_LEFT:
return 0;
case ALIGN_CENTER:
{
unsigned int endChar = text.find('\n', charStart);
return (xLen - sizeText(text.substr(charStart, endChar != std::string::npos ? endChar - charStart : endChar)).x()) / 2.0f;
}
case ALIGN_RIGHT:
{
unsigned int endChar = text.find('\n', charStart);
return xLen - (sizeText(text.substr(charStart, endChar != std::string::npos ? endChar - charStart : endChar)).x());
}
default:
return 0;
}
}
TextCache* Font::buildTextCache(const std::string& text, Eigen::Vector2f offset, unsigned int color, float xLen, Alignment alignment, float lineSpacing)
{
if(!mTextureID)
@ -394,50 +415,28 @@ TextCache* Font::buildTextCache(const std::string& text, Eigen::Vector2f offset,
return NULL;
}
// todo
return NULL;
}
TextCache* Font::buildTextCache(const std::string& text, float offsetX, float offsetY, unsigned int color)
{
if(!mTextureID)
{
LOG(LogError) << "Error - tried to build TextCache with Font that has no texture loaded!";
return NULL;
}
const int triCount = text.length() * 2;
const int vertCount = triCount * 3;
const unsigned int vertCount = text.length() * 2 * 3; // 2 triangles of 3 vertices per character
TextCache::Vertex* vert = new TextCache::Vertex[vertCount];
GLubyte* colors = new GLubyte[vertCount * 4];
// all glyph sizes/texture offsets are in pixels,
// so the only rounding we have to worry about is the offset
offsetX = round(offsetX);
offsetY = round(offsetY);
//texture atlas width/height
float tw = (float)mTextureWidth;
float th = (float)mTextureHeight;
float x = offsetX;
float x = offset[0] + (xLen != 0 ? getNewlineStartOffset(text, 0, xLen, alignment) : 0);
float yTop = mCharData['S'].bearingY * mFontScale;
float yBot = getHeight();
float y = offsetY + (yBot + yTop)/2.0f;
float yBot = getHeight(lineSpacing);
float y = offset[1] + (yBot + yTop)/2.0f;
int charNum = 0;
for(int i = 0; i < vertCount; i += 6, charNum++)
for(unsigned int i = 0, charNum = 0; i < vertCount; i += 6, charNum++)
{
unsigned char letter = text[charNum];
if(letter == '\n')
{
y += (float)getHeight();
x = offsetX;
y += getHeight(lineSpacing);
x = offset[0] + (xLen != 0 ? getNewlineStartOffset(text, charNum+1, xLen, alignment) : 0);
memset(&vert[i], 0, 6 * sizeof(TextCache::Vertex));
continue;
}
@ -470,6 +469,13 @@ TextCache* Font::buildTextCache(const std::string& text, float offsetX, float of
vert[i + 5].tex[0] = vert[i + 1].tex.x();
vert[i + 5].tex[1] = vert[i + 0].tex.y();
// round to fix some weird "cut off" text bugs
for(unsigned int j = i; j < i + 6; j++)
{
vert[j].pos[0] = round(vert[j].pos[0]);
vert[j].pos[1] = round(vert[j].pos[1]);
}
x += mCharData[letter].advX * mFontScale;
}
@ -481,6 +487,11 @@ TextCache* Font::buildTextCache(const std::string& text, float offsetX, float of
return cache;
}
TextCache* Font::buildTextCache(const std::string& text, float offsetX, float offsetY, unsigned int color)
{
return buildTextCache(text, Eigen::Vector2f(offsetX, offsetY), color, 0.0f);
}
TextCache::TextCache(int verts, Vertex* v, GLubyte* c, const CacheMetrics& m) : vertCount(verts), verts(v), colors(c), metrics(m)
{
}

View file

@ -99,6 +99,8 @@ private:
int mSize;
const std::string mPath;
float getNewlineStartOffset(const std::string& text, const unsigned int& charStart, const float& xLen, const Alignment& alignment);
friend TextCache;
};

View file

@ -107,7 +107,7 @@ void DetailedGameListView::onThemeChanged(const std::shared_ptr<ThemeData>& them
mDescContainer.applyTheme(theme, getName(), "md_description", POSITION | ThemeFlags::SIZE);
mDescription.setSize(mDescContainer.getSize().x(), 0);
mDescription.applyTheme(theme, getName(), "md_description", FONT_PATH | FONT_SIZE | COLOR | FORCE_UPPERCASE);
mDescription.applyTheme(theme, getName(), "md_description", FONT_PATH | FONT_SIZE | COLOR | FORCE_UPPERCASE | ALIGNMENT);
}
void DetailedGameListView::initMDLabels()