mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-03-06 14:27:43 +00:00
Added proper text alignment to the Font class.
Multiline text is now centered/right-aligned correctly.
This commit is contained in:
parent
4cf206d3eb
commit
5d0df7acf8
src
|
@ -82,22 +82,7 @@ void TextComponent::render(const Eigen::Affine3f& parentTrans)
|
||||||
if(mTextCache)
|
if(mTextCache)
|
||||||
{
|
{
|
||||||
const Eigen::Vector2f& textSize = mTextCache->metrics.size;
|
const Eigen::Vector2f& textSize = mTextCache->metrics.size;
|
||||||
Eigen::Vector3f off(0, 0, 0);
|
Eigen::Vector3f off(0, (getSize().y() - textSize.y()) / 2.0f, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Settings::getInstance()->getBool("DebugText"))
|
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
|
// draw the text area, where the text actually is going
|
||||||
if(Settings::getInstance()->getBool("DebugText"))
|
if(Settings::getInstance()->getBool("DebugText"))
|
||||||
|
{
|
||||||
|
switch(mAlignment)
|
||||||
|
{
|
||||||
|
case ALIGN_LEFT:
|
||||||
Renderer::drawRect(0.0f, 0.0f, mTextCache->metrics.size.x(), mTextCache->metrics.size.y(), 0x00000033);
|
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());
|
mFont->renderTextCache(mTextCache.get());
|
||||||
}
|
}
|
||||||
|
@ -140,7 +138,7 @@ void TextComponent::onTextChanged()
|
||||||
std::string text = mUppercase ? strToUpper(mText) : mText;
|
std::string text = mUppercase ? strToUpper(mText) : mText;
|
||||||
|
|
||||||
std::shared_ptr<Font> f = getFont();
|
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);
|
Eigen::Vector2f size = f->sizeText(text);
|
||||||
if(!wrap && mSize.x() && text.size() && size.x() > mSize.x())
|
if(!wrap && mSize.x() && text.size() && size.x() > mSize.x())
|
||||||
{
|
{
|
||||||
|
@ -156,9 +154,9 @@ void TextComponent::onTextChanged()
|
||||||
|
|
||||||
text.append(abbrev);
|
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{
|
}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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -386,6 +386,27 @@ Eigen::Vector2f Font::getWrappedTextCursorOffset(std::string text, float xLen, i
|
||||||
//TextCache
|
//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)
|
TextCache* Font::buildTextCache(const std::string& text, Eigen::Vector2f offset, unsigned int color, float xLen, Alignment alignment, float lineSpacing)
|
||||||
{
|
{
|
||||||
if(!mTextureID)
|
if(!mTextureID)
|
||||||
|
@ -394,50 +415,28 @@ TextCache* Font::buildTextCache(const std::string& text, Eigen::Vector2f offset,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo
|
const unsigned int vertCount = text.length() * 2 * 3; // 2 triangles of 3 vertices per character
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
TextCache::Vertex* vert = new TextCache::Vertex[vertCount];
|
TextCache::Vertex* vert = new TextCache::Vertex[vertCount];
|
||||||
GLubyte* colors = new GLubyte[vertCount * 4];
|
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
|
//texture atlas width/height
|
||||||
float tw = (float)mTextureWidth;
|
float tw = (float)mTextureWidth;
|
||||||
float th = (float)mTextureHeight;
|
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 yTop = mCharData['S'].bearingY * mFontScale;
|
||||||
float yBot = getHeight();
|
float yBot = getHeight(lineSpacing);
|
||||||
float y = offsetY + (yBot + yTop)/2.0f;
|
float y = offset[1] + (yBot + yTop)/2.0f;
|
||||||
|
|
||||||
int charNum = 0;
|
for(unsigned int i = 0, charNum = 0; i < vertCount; i += 6, charNum++)
|
||||||
for(int i = 0; i < vertCount; i += 6, charNum++)
|
|
||||||
{
|
{
|
||||||
unsigned char letter = text[charNum];
|
unsigned char letter = text[charNum];
|
||||||
|
|
||||||
if(letter == '\n')
|
if(letter == '\n')
|
||||||
{
|
{
|
||||||
y += (float)getHeight();
|
y += getHeight(lineSpacing);
|
||||||
x = offsetX;
|
x = offset[0] + (xLen != 0 ? getNewlineStartOffset(text, charNum+1, xLen, alignment) : 0);
|
||||||
memset(&vert[i], 0, 6 * sizeof(TextCache::Vertex));
|
memset(&vert[i], 0, 6 * sizeof(TextCache::Vertex));
|
||||||
continue;
|
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[0] = vert[i + 1].tex.x();
|
||||||
vert[i + 5].tex[1] = vert[i + 0].tex.y();
|
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;
|
x += mCharData[letter].advX * mFontScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,6 +487,11 @@ TextCache* Font::buildTextCache(const std::string& text, float offsetX, float of
|
||||||
return cache;
|
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)
|
TextCache::TextCache(int verts, Vertex* v, GLubyte* c, const CacheMetrics& m) : vertCount(verts), verts(v), colors(c), metrics(m)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,8 @@ private:
|
||||||
int mSize;
|
int mSize;
|
||||||
const std::string mPath;
|
const std::string mPath;
|
||||||
|
|
||||||
|
float getNewlineStartOffset(const std::string& text, const unsigned int& charStart, const float& xLen, const Alignment& alignment);
|
||||||
|
|
||||||
friend TextCache;
|
friend TextCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ void DetailedGameListView::onThemeChanged(const std::shared_ptr<ThemeData>& them
|
||||||
|
|
||||||
mDescContainer.applyTheme(theme, getName(), "md_description", POSITION | ThemeFlags::SIZE);
|
mDescContainer.applyTheme(theme, getName(), "md_description", POSITION | ThemeFlags::SIZE);
|
||||||
mDescription.setSize(mDescContainer.getSize().x(), 0);
|
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()
|
void DetailedGameListView::initMDLabels()
|
||||||
|
|
Loading…
Reference in a new issue