1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-12-27 07:41:09 +02:00

Have Font::write return the width of the drawn text

This avoids having to do separate getTextWidth calls in several places.

More getTextWidth calls could be saved by splitting the rendering of
the font to an off-screen buffer from the final composition onto the
destination surface: the routines that draw text inside a box have to
compute the width before they can draw the box and currently the box
has to be drawn before the text.
This commit is contained in:
Maarten ter Huurne 2014-08-15 03:32:32 +02:00
parent 6895ac0b54
commit ab7a4c1cf7
3 changed files with 35 additions and 24 deletions

View File

@ -6,6 +6,7 @@
#include <SDL.h>
#include <SDL_ttf.h>
#include <algorithm>
#include <vector>
/* TODO: Let the theme choose the font and font size */
@ -197,38 +198,38 @@ int Font::getTextHeight(const string &text)
return nLines * getLineSpacing();
}
void Font::write(Surface& surface, const string &text,
int Font::write(Surface& surface, const string &text,
int x, int y, HAlign halign, VAlign valign)
{
if (!font) {
return;
return 0;
}
size_t pos = text.find('\n', 0);
if (pos == string::npos) {
writeLine(surface, text, x, y, halign, valign);
return writeLine(surface, text, x, y, halign, valign);
} else {
int maxWidth = 0;
size_t prev = 0;
do {
writeLine(surface, text.substr(prev, pos - prev),
x, y, halign, valign);
maxWidth = max(maxWidth,
writeLine(surface, text.substr(prev, pos - prev),
x, y, halign, valign));
y += lineSpacing;
prev = pos + 1;
pos = text.find('\n', prev);
} while (pos != string::npos);
writeLine(surface, text.substr(prev), x, y, halign, valign);
return max(maxWidth,
writeLine(surface, text.substr(prev), x, y, halign, valign));
}
}
void Font::writeLine(Surface& surface, std::string const& text,
int Font::writeLine(Surface& surface, std::string const& text,
int x, int y, HAlign halign, VAlign valign)
{
if (!font) {
return;
}
if (text.empty()) {
// SDL_ttf will return a nullptr when rendering the empty string.
return;
return 0;
}
switch (valign) {
@ -246,17 +247,18 @@ void Font::writeLine(Surface& surface, std::string const& text,
SDL_Surface *s = TTF_RenderUTF8_Blended(font, text.c_str(), color);
if (!s) {
ERROR("Font rendering failed for text \"%s\"\n", text.c_str());
return;
return 0;
}
const int width = s->w;
switch (halign) {
case HAlignLeft:
break;
case HAlignCenter:
x -= s->w / 2;
x -= width / 2;
break;
case HAlignRight:
x -= s->w;
x -= width;
break;
}
@ -287,8 +289,10 @@ void Font::writeLine(Surface& surface, std::string const& text,
s = TTF_RenderUTF8_Blended(font, text.c_str(), color);
if (!s) {
ERROR("Font rendering failed for text \"%s\"\n", text.c_str());
return;
return width;
}
SDL_BlitSurface(s, NULL, surface.raw, &rect);
SDL_FreeSurface(s);
return width;
}

View File

@ -38,7 +38,11 @@ public:
return lineSpacing;
}
void write(Surface& surface,
/**
* Draws a text on a surface in this font.
* @return The width of the text in pixels.
*/
int write(Surface& surface,
const std::string &text, int x, int y,
HAlign halign = HAlignLeft, VAlign valign = VAlignTop);
@ -48,7 +52,11 @@ private:
std::string wordWrapSingleLine(const std::string &text,
size_t start, size_t end, int width);
void writeLine(Surface& surface, std::string const& text,
/**
* Draws a single line of text on a surface in this font.
* @return The width of the text in pixels.
*/
int writeLine(Surface& surface, std::string const& text,
int x, int y, HAlign halign, VAlign valign);
TTF_Font *font;

View File

@ -321,10 +321,9 @@ void GMenu2X::initBG() {
if (sd) sd->blit(*bgmain, 3, bottomBarIconY);
}
string df = getDiskFree(getHome().c_str());
font->write(*bgmain, df, 22, bottomBarTextY, Font::HAlignLeft, Font::VAlignMiddle);
cpuX = 32 + font->write(*bgmain, getDiskFree(getHome().c_str()),
22, bottomBarTextY, Font::HAlignLeft, Font::VAlignMiddle);
cpuX = font->getTextWidth(df) + 32;
#ifdef ENABLE_CPUFREQ
{
auto cpu = OffscreenSurface::loadImage(
@ -1044,8 +1043,8 @@ int GMenu2X::drawButton(Surface& s, const string &btn, const string &text, int x
if (sc.skinRes("imgs/buttons/"+btn+".png") != NULL) {
sc["imgs/buttons/"+btn+".png"]->blit(s, x, y-7);
re.w = sc["imgs/buttons/"+btn+".png"]->width() + 3;
font->write(s, text, x+re.w, y, Font::HAlignLeft, Font::VAlignMiddle);
re.w += font->getTextWidth(text);
re.w += font->write(
s, text, x+re.w, y, Font::HAlignLeft, Font::VAlignMiddle);
}
return x+re.w+6;
}
@ -1056,8 +1055,8 @@ int GMenu2X::drawButtonRight(Surface& s, const string &btn, const string &text,
x -= 16;
sc["imgs/buttons/"+btn+".png"]->blit(s, x, y-7);
x -= 3;
font->write(s, text, x, y, Font::HAlignRight, Font::VAlignMiddle);
return x-6-font->getTextWidth(text);
return x-6 - font->write(
s, text, x, y, Font::HAlignRight, Font::VAlignMiddle);
}
return x-6;
}