New text width ops
This commit is contained in:
parent
7a459e8021
commit
e1d230f814
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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")]]
|
||||
|
@ -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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user