mirror of
git://projects.qi-hardware.com/gmenu2x.git
synced 2024-11-25 18:05:20 +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:
parent
6895ac0b54
commit
ab7a4c1cf7
32
src/font.cpp
32
src/font.cpp
@ -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 {
|
||||
maxWidth = max(maxWidth,
|
||||
writeLine(surface, text.substr(prev, pos - prev),
|
||||
x, y, halign, valign);
|
||||
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;
|
||||
}
|
||||
|
12
src/font.h
12
src/font.h
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user