summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2012-02-06 21:26:24 +0100
committerThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2012-02-07 21:11:34 +0100
commit812fc04430cfd3863f5bce2319deef26e5d3c316 (patch)
treeef44383ce06cf3b47ced36f9c6238e892659be07
parent04a3cdd669726389b3b10c5d2da5440262e3765d (diff)
downloadmana-812fc04430cfd3863f5bce2319deef26e5d3c316.tar.gz
mana-812fc04430cfd3863f5bce2319deef26e5d3c316.tar.bz2
mana-812fc04430cfd3863f5bce2319deef26e5d3c316.tar.xz
mana-812fc04430cfd3863f5bce2319deef26e5d3c316.zip
Made BrowserBox use the recommended line skip for its font
SDL_ttf provides a separate function for getting the recommended line skip, or the spacing between two lines of text. When rendering multiple lines of text this should be used rather than the visual height of the font. Since the information is only available for TrueTypeFont, a dynamic_cast was used with a fallback on gcn::Font::getHeight. Also made some small tweaks but nothing that really affects performance. Reviewed-by: Yohann Ferreira
-rw-r--r--src/gui/truetypefont.cpp5
-rw-r--r--src/gui/truetypefont.h7
-rw-r--r--src/gui/widgets/browserbox.cpp103
-rw-r--r--src/gui/widgets/browserbox.h6
4 files changed, 73 insertions, 48 deletions
diff --git a/src/gui/truetypefont.cpp b/src/gui/truetypefont.cpp
index ee1db8b3..5f85ea68 100644
--- a/src/gui/truetypefont.cpp
+++ b/src/gui/truetypefont.cpp
@@ -189,3 +189,8 @@ int TrueTypeFont::getHeight() const
{
return TTF_FontHeight(mFont);
}
+
+int TrueTypeFont::getLineHeight() const
+{
+ return TTF_FontLineSkip(mFont);
+}
diff --git a/src/gui/truetypefont.h b/src/gui/truetypefont.h
index 7974a953..97fd7f08 100644
--- a/src/gui/truetypefont.h
+++ b/src/gui/truetypefont.h
@@ -63,6 +63,13 @@ class TrueTypeFont : public gcn::Font
virtual int getHeight() const;
/**
+ * Returns the height of a line of text. This is not the visual height
+ * as returned by getHeight() but the recommended spacing between lines
+ * of text.
+ */
+ int getLineHeight() const;
+
+ /**
* @see Font::drawString
*/
void drawString(gcn::Graphics *graphics,
diff --git a/src/gui/widgets/browserbox.cpp b/src/gui/widgets/browserbox.cpp
index e76e0823..29847639 100644
--- a/src/gui/widgets/browserbox.cpp
+++ b/src/gui/widgets/browserbox.cpp
@@ -24,6 +24,7 @@
#include "client.h"
+#include "gui/truetypefont.h"
#include "gui/widgets/linkhandler.h"
#include "resources/theme.h"
@@ -79,15 +80,21 @@ void BrowserBox::disableLinksAndUserColors()
void BrowserBox::addRow(const std::string &row)
{
- std::string tmp = row;
std::string newRow;
- std::string::size_type idx1, idx2, idx3;
+
gcn::Font *font = getFont();
+ const int fontHeight = font->getHeight();
+
+ int lineHeight = fontHeight;
+ if (TrueTypeFont *ttf = dynamic_cast<TrueTypeFont*>(font))
+ lineHeight = ttf->getLineHeight();
// Use links and user defined colors
if (mUseLinksAndUserColors)
{
- BROWSER_LINK bLink;
+ BrowserLink bLink;
+ std::string tmp = row;
+ std::string::size_type idx1, idx2, idx3;
// Check for links in format "@@link|Caption@@"
idx1 = tmp.find("@@");
@@ -100,8 +107,8 @@ void BrowserBox::addRow(const std::string &row)
break;
bLink.link = tmp.substr(idx1 + 2, idx2 - (idx1 + 2));
bLink.caption = tmp.substr(idx2 + 1, idx3 - (idx2 + 1));
- bLink.y1 = static_cast<int>(mTextRows.size()) * font->getHeight();
- bLink.y2 = bLink.y1 + font->getHeight();
+ bLink.y1 = static_cast<int>(mTextRows.size()) * lineHeight;
+ bLink.y2 = bLink.y1 + fontHeight;
newRow += tmp.substr(0, idx1);
@@ -145,8 +152,8 @@ void BrowserBox::addRow(const std::string &row)
mTextRows.pop_front();
for (unsigned int i = 0; i < mLinks.size(); i++)
{
- mLinks[i].y1 -= font->getHeight();
- mLinks[i].y2 -= font->getHeight();
+ mLinks[i].y1 -= lineHeight;
+ mLinks[i].y2 -= lineHeight;
if (mLinks[i].y1 < 0)
mLinks.erase(mLinks.begin() + i);
@@ -158,8 +165,9 @@ void BrowserBox::addRow(const std::string &row)
if (mMode == AUTO_SIZE)
{
std::string plain = newRow;
- while ((idx1 = plain.find("##")) != std::string::npos)
- plain.erase(idx1, 3);
+ std::string::size_type index;
+ while ((index = plain.find("##")) != std::string::npos)
+ plain.erase(index, 3);
// Adjust the BrowserBox size
int w = font->getWidth(plain);
@@ -167,25 +175,27 @@ void BrowserBox::addRow(const std::string &row)
setWidth(w);
}
+ // TODO: Optimize! There's no point in wrapping all text rows again, just
+ // do the one that was just added (but take into account discarded rows?).
if (mMode == AUTO_WRAP)
{
- unsigned int y = 0;
+ unsigned int wrapCount = 0;
unsigned int nextChar;
- const char *hyphen = "~";
- int hyphenWidth = font->getWidth(hyphen);
+ const char *tilde = "~";
+ int tildeWidth = font->getWidth(tilde);
int x = 0;
for (TextRowIterator i = mTextRows.begin(); i != mTextRows.end(); i++)
{
std::string row = *i;
- for (unsigned int j = 0; j < row.size(); j++)
+ for (unsigned int j = 0; j < row.size(); ++j)
{
std::string character = row.substr(j, 1);
x += font->getWidth(character);
nextChar = j + 1;
// Wraping between words (at blank spaces)
- if ((nextChar < row.size()) && (row.at(nextChar) == ' '))
+ if (nextChar < row.size() && row.at(nextChar) == ' ')
{
int nextSpacePos = static_cast<int>(
row.find(" ", (nextChar + 1)));
@@ -196,28 +206,28 @@ void BrowserBox::addRow(const std::string &row)
row.substr(nextChar,
(nextSpacePos - nextChar)));
- if ((x + nextWordWidth + 10) > getWidth())
+ if (x + nextWordWidth + 10 > getWidth())
{
- x = 15; // Ident in new line
- y += 1;
- j++;
+ x = 15; // Indent in new line
+ ++wrapCount;
+ ++j;
}
}
// Wrapping looong lines (brutal force)
- else if ((x + 2 * hyphenWidth) > getWidth())
+ else if (x + 2 * tildeWidth > getWidth())
{
x = 15; // Ident in new line
- y += 1;
+ ++wrapCount;
}
}
}
- setHeight(font->getHeight() * (static_cast<int>(
- mTextRows.size()) + y));
+ setHeight(lineHeight * (mTextRows.size() + wrapCount - 1)
+ + fontHeight);
}
else
{
- setHeight(font->getHeight() * static_cast<int>(mTextRows.size()));
+ setHeight(lineHeight * (mTextRows.size() - 1) + fontHeight);
}
mUpdateTime = 0;
updateHeight();
@@ -238,7 +248,7 @@ struct MouseOverLink
MouseOverLink(int x, int y) : mX(x), mY(y)
{ }
- bool operator() (BROWSER_LINK &link)
+ bool operator() (BrowserLink &link) const
{
return (mX >= link.x1 && mX < link.x2 &&
mY >= link.y1 && mY < link.y2);
@@ -362,13 +372,16 @@ int BrowserBox::calcHeight()
unsigned link = 0;
gcn::Font *font = getFont();
- int fontHeight = font->getHeight();
- int fontWidthMinus = font->getWidth("-");
- char const *hyphen = "~";
- int hyphenWidth = font->getWidth(hyphen);
+ const int fontHeight = font->getHeight();
+ const int minusWidth = font->getWidth("-");
+ const int tildeWidth = font->getWidth("~");
+
+ int lineHeight = fontHeight;
+ if (TrueTypeFont *ttf = dynamic_cast<TrueTypeFont*>(font))
+ lineHeight = ttf->getLineHeight();
gcn::Color selColor = Theme::getThemeColor(Theme::TEXT);
- const gcn::Color textColor = Theme::getThemeColor(Theme::TEXT);
+ const gcn::Color &textColor = Theme::getThemeColor(Theme::TEXT);
mLineParts.clear();
@@ -381,14 +394,13 @@ int BrowserBox::calcHeight()
// Check for separator lines
if (row.find("---", 0) == 0)
{
- const int dashWidth = fontWidthMinus;
for (x = 0; x < getWidth(); x++)
{
mLineParts.push_back(LinePart(x, y, selColor, "-"));
- x += dashWidth - 2;
+ x += minusWidth - 2;
}
- y += fontHeight;
+ y += lineHeight;
continue;
}
@@ -403,7 +415,7 @@ int BrowserBox::calcHeight()
// Wrapped line continuation shall be indented
if (wrapped)
{
- y += fontHeight;
+ y += lineHeight;
x = 15;
wrapped = false;
}
@@ -474,12 +486,12 @@ int BrowserBox::calcHeight()
}
}
- std::string::size_type len =
- end == std::string::npos ? end : end - start;
-
if (start >= row.length())
break;
+ std::string::size_type len =
+ end == std::string::npos ? end : end - start;
+
std::string part = row.substr(start, len);
// Auto wrap mode
@@ -503,7 +515,7 @@ int BrowserBox::calcHeight()
{
forced = true;
end = row.size();
- x += hyphenWidth; // Account for the wrap-notifier
+ x += tildeWidth; // Account for the wrap-notifier
continue;
}
@@ -519,9 +531,9 @@ int BrowserBox::calcHeight()
if (forced)
{
- x -= hyphenWidth; // Remove the wrap-notifier accounting
- mLineParts.push_back(LinePart(getWidth() - hyphenWidth,
- y, selColor, hyphen));
+ x -= tildeWidth; // Remove the wrap-notifier accounting
+ mLineParts.push_back(LinePart(getWidth() - tildeWidth,
+ y, selColor, "~"));
end++; // Skip to the next character
}
else
@@ -533,16 +545,17 @@ int BrowserBox::calcHeight()
wrappedLines++;
}
- mLineParts.push_back(LinePart(x, y, selColor, part.c_str()));
+ mLineParts.push_back(LinePart(x, y, selColor, part));
- if (mMode == AUTO_WRAP && font->getWidth(part) == 0)
+ const int partWidth = font->getWidth(part);
+ if (mMode == AUTO_WRAP && partWidth == 0)
break;
- x += font->getWidth(part);
+ x += partWidth;
}
- y += fontHeight;
+ y += lineHeight;
}
- return (static_cast<int>(mTextRows.size()) + wrappedLines) * fontHeight;
+ return (mTextRows.size() + wrappedLines - 1) * lineHeight + fontHeight;
}
void BrowserBox::updateHeight()
diff --git a/src/gui/widgets/browserbox.h b/src/gui/widgets/browserbox.h
index 877442d6..ecdf8ca7 100644
--- a/src/gui/widgets/browserbox.h
+++ b/src/gui/widgets/browserbox.h
@@ -31,7 +31,7 @@
class LinkHandler;
-struct BROWSER_LINK
+struct BrowserLink
{
int x1, x2, y1, y2; /**< Where link is placed */
std::string link;
@@ -104,7 +104,7 @@ class BrowserBox : public gcn::Widget,
/**
* Sets the maximum numbers of rows in the browser box. 0 = no limit.
*/
- void setMaxRow(unsigned max) {mMaxRows = max; };
+ void setMaxRow(unsigned max) {mMaxRows = max; }
/**
* Disable links & user defined colors to be used in chat input.
@@ -200,7 +200,7 @@ class BrowserBox : public gcn::Widget,
typedef LinePartList::iterator LinePartIterator;
LinePartList mLineParts;
- typedef std::vector<BROWSER_LINK> Links;
+ typedef std::vector<BrowserLink> Links;
typedef Links::iterator LinkIterator;
Links mLinks;