New text width ops

This commit is contained in:
mniip 2023-04-10 23:54:46 +02:00
parent 7a459e8021
commit e1d230f814
5 changed files with 101 additions and 94 deletions

View File

@ -101,16 +101,14 @@ void BlueScreen(String detailMessage)
String errorTitle = "ERROR";
String errorDetails = "Details: " + detailMessage;
String errorHelp = String("An unrecoverable fault has occurred, please report the error by visiting the website below\n") + SCHEME + SERVER;
int currentY = 0, width, height;
int errorWidth = 0;
Graphics::textsize(errorTitle, errorWidth, height);
engine.g->BlendText(engine.g->Size() / 2 - Vec2(errorWidth / 2, 100 - currentY), errorTitle, 0xFFFFFF_rgb .WithAlpha(0xFF));
currentY += height + 4;
Graphics::textsize(errorDetails, width, height);
engine.g->BlendText(engine.g->Size() / 2 - Vec2(errorWidth / 2, 100 - currentY), errorDetails, 0xFFFFFF_rgb .WithAlpha(0xFF));
currentY += height + 4;
Graphics::textsize(errorHelp, width, height);
engine.g->BlendText(engine.g->Size() / 2 - Vec2(errorWidth / 2, 100 - currentY), errorHelp, 0xFFFFFF_rgb .WithAlpha(0xFF));
// We use the width of errorHelp to center, but heights of the individual texts for vertical spacing
auto pos = engine.g->Size() / 2 - Vec2(Graphics::TextSize(errorHelp).X / 2, 100);
engine.g->BlendText(pos, errorTitle, 0xFFFFFF_rgb .WithAlpha(0xFF));
pos.Y += 4 + Graphics::TextSize(errorTitle).Y;
engine.g->BlendText(pos, errorDetails, 0xFFFFFF_rgb .WithAlpha(0xFF));
pos.Y += 4 + Graphics::TextSize(errorDetails).Y;
engine.g->BlendText(pos, errorHelp, 0xFFFFFF_rgb .WithAlpha(0xFF));
//Death loop
SDL_Event event;

View File

@ -169,97 +169,19 @@ Graphics::Graphics()
int Graphics::textwidth(const String &str)
{
int x = 0;
for (size_t i = 0; i < str.length(); i++)
{
if (str[i] == '\b')
{
if (str.length() <= i+1)
break;
i++;
continue;
}
else if (str[i] == '\x0F')
{
if (str.length() <= i+3)
break;
i += 3;
continue;
}
x += FontReader(str[i]).GetWidth();
}
return x-1;
}
int Graphics::CharWidth(String::value_type c)
{
return FontReader(c).GetWidth();
return TextSize(str).X;
}
int Graphics::textwidthx(const String &str, int w)
{
int x = 0,n = 0,cw = 0;
for (size_t i = 0; i < str.length(); i++)
{
if (str[i] == '\b')
{
if (str.length() <= i+1)
break;
i++;
continue;
} else if (str[i] == '\x0F') {
if (str.length() <= i+3)
break;
i += 3;
continue;
}
cw = FontReader(str[i]).GetWidth();
if (x+(cw/2) >= w)
break;
x += cw;
n++;
}
return n;
return TextFit(str, w) - str.begin();
}
void Graphics::textsize(const String &str, int & width, int & height)
{
if(!str.size())
{
width = 0;
height = FONT_H-2;
return;
}
int cHeight = FONT_H-2, cWidth = 0, lWidth = 0;
for (size_t i = 0; i < str.length(); i++)
{
if (str[i] == '\n')
{
cWidth = 0;
cHeight += FONT_H;
}
else if (str[i] == '\x0F')
{
if (str.length() <= i+3)
break;
i += 3;
}
else if (str[i] == '\b')
{
if (str.length() <= i+1)
break;
i++;
}
else
{
cWidth += FontReader(str[i]).GetWidth();
if(cWidth>lWidth)
lWidth = cWidth;
}
}
width = lWidth;
height = cHeight;
auto size = TextSize(str);
width = size.X;
height = size.Y;
}
void Graphics::draw_icon(int x, int y, Icon icon, unsigned char alpha, bool invert)

View File

@ -95,9 +95,11 @@ public:
static std::vector<pixel> Gradient(std::vector<GradientStop> stops, int resolution);
//Font/text metrics
static int CharWidth(String::value_type c);
[[deprecated("Use TextFit()")]]
static int textwidthx(const String &s, int w);
[[deprecated("Use TextSize().X")]]
static int textwidth(const String &s);
[[deprecated("Use TextSize()")]]
static void textsize(const String &s, int & width, int & height);
VideoBuffer DumpFrame();

View File

@ -50,6 +50,14 @@ struct RasterDrawMethods
Vec2<int> BlendTextOutline(Vec2<int>, String const &, RGBA<uint8_t>);
static int CharWidth(String::value_type);
// Considers the first line to be FONT_H-2 tall with successive lines adding
// FONT_H each
static Vec2<int> TextSize(String const &);
// Return iterator to the end of an initial portion of text that fits in
// the given width
static String::const_iterator TextFit(String const &, int width);
void Clear();
[[deprecated("Use BlendTextOutline")]]

View File

@ -324,6 +324,83 @@ void RasterDrawMethods<Derived>::Clear()
std::fill_n(video.data(), video.Size().X * video.Size().Y, 0x000000_rgb .Pack());
}
template<typename Derived>
int RasterDrawMethods<Derived>::CharWidth(String::value_type ch)
{
return FontReader(ch).GetWidth();
}
template<typename Derived>
Vec2<int> RasterDrawMethods<Derived>::TextSize(String const &str)
{
Vec2<int> size = Vec2(0, FONT_H - 2);
int curX = -1; // characters have 1px of spacing between them
for (size_t i = 0; i < str.length(); i++)
{
if (str[i] == '\n')
{
size.X = std::max(curX, size.X);
size.Y += FONT_H;
curX = 0;
}
else if (str[i] == '\x0F')
{
if (str.length() <= i + 3)
break;
i += 3;
}
else if (str[i] == '\x0E')
continue;
else if (str[i] == '\x01')
continue;
else if (str[i] == '\b')
{
if (str.length() <= i + 1)
break;
i++;
}
else
curX += CharWidth(str[i]);
}
size.X = std::max(curX, size.X);
return size;
}
template<typename Derived>
String::const_iterator RasterDrawMethods<Derived>::TextFit(String const &str, int width)
{
int curX = 0;
for (size_t i = 0; i < str.length(); i++)
{
if (str[i] == '\n')
curX = 0;
else if (str[i] == '\x0F')
{
if (str.length() <= i + 3)
break;
i += 3;
}
else if (str[i] == '\x0E')
continue;
else if (str[i] == '\x01')
continue;
else if (str[i] == '\b')
{
if (str.length() <= i + 1)
break;
i++;
}
else
{
int dx = CharWidth(str[i]);
if (curX + dx / 2 >= width)
return str.begin() + i;
curX += dx;
}
}
return str.end();
}
template<typename Derived>
int RasterDrawMethods<Derived>::drawtext_outline(int x, int y, const String &s, int r, int g, int b, int a)
{