20using std::string_view;
27 , fontFile(
"skins/Vera.ttf.gz")
34 if (propName ==
"-text") {
42 }
else if (propName ==
"-font") {
44 if (fontFile != val) {
52 }
else if (propName ==
"-size") {
53 int size2 = value.
getInt(interp);
58 }
else if (propName ==
"-wrap") {
60 WrapMode wrapMode2 = [&] {
63 }
else if (val ==
"word") {
65 }
else if (val ==
"char") {
69 "expected one of 'none word char', but got '",
73 if (wrapMode != wrapMode2) {
77 }
else if (propName ==
"-wrapw") {
78 float wrapw2 = value.
getFloat(interp);
79 if (wrapw != wrapw2) {
83 }
else if (propName ==
"-wraprelw") {
84 float wraprelw2 = value.
getFloat(interp);
85 if (wraprelw != wraprelw2) {
96 if (propName ==
"-text") {
98 }
else if (propName ==
"-font") {
100 }
else if (propName ==
"-size") {
102 }
else if (propName ==
"-wrap") {
105 case NONE: wrapString =
"none";
break;
106 case WORD: wrapString =
"word";
break;
107 case CHAR: wrapString =
"char";
break;
111 }
else if (propName ==
"-wrapw") {
113 }
else if (propName ==
"-wraprelw") {
120void OSDText::invalidateLocal()
143uint8_t OSDText::getFadedAlpha()
const
148std::unique_ptr<GLImage> OSDText::create(OutputSurface& output)
151 return std::make_unique<GLImage>(
ivec2(), 0);
158 }
catch (MSXException&
e) {
159 throw MSXException(
"Couldn't open font: ",
e.getMessage());
164 int maxWidth = narrow_cast<int>(lrintf(wrapw * narrow<float>(
scale) + wraprelw * pSize[0]));
170 unsigned textRgba =
getRGBA(0);
172 if (wrapMode == NONE) {
174 }
else if (wrapMode == WORD) {
175 wrappedText = getWordWrappedText(text, maxWidth);
176 }
else if (wrapMode == CHAR) {
177 wrappedText = getCharWrappedText(text, maxWidth);
185 narrow_cast<uint8_t>(textRgba >> 24),
186 narrow_cast<uint8_t>(textRgba >> 16),
187 narrow_cast<uint8_t>(textRgba >> 8)));
189 return std::make_unique<GLImage>(std::move(surface));
191 return std::make_unique<GLImage>(
ivec2(), 0);
193 }
catch (MSXException&
e) {
194 throw MSXException(
"Couldn't render text: ",
e.getMessage());
202static constexpr size_t findCharSplitPoint(string_view line,
size_t min,
size_t max)
204 auto pos = (
min +
max) / 2;
205 auto beginIt = line.data();
206 auto posIt = beginIt + pos;
209 auto maxIt = beginIt +
max;
210 assert(fwdIt <= maxIt);
211 if (fwdIt != maxIt) {
212 return fwdIt - beginIt;
216 auto minIt = beginIt +
min;
217 assert(minIt <= bwdIt); (void)minIt;
218 return bwdIt - beginIt;
226static constexpr size_t findWordSplitPoint(string_view line,
size_t min,
size_t max)
228 constexpr const char*
const delimiters =
" -/";
232 size_t pos = (
min +
max) / 2;
240 if (
auto pos2 = line.substr(
min, pos -
min).find_last_of(delimiters);
241 pos2 != string_view::npos) {
249 if (
auto pos2 = line.substr(pos,
max - pos).find_first_of(delimiters);
250 pos2 != string_view::npos) {
262static constexpr size_t takeSingleChar(string_view ,
unsigned )
267template<
typename FindSplitPo
intFunc,
typename CantSplitFunc>
268size_t OSDText::split(
const string& line,
unsigned maxWidth,
269 FindSplitPointFunc findSplitPoint,
270 CantSplitFunc cantSplit,
271 bool removeTrailingSpaces)
const
279 unsigned width = font.
getSize(line)[0];
280 if (width <= maxWidth) {
288 size_t max = line.size();
291 size_t cur = findSplitPoint(line,
min,
max);
295 return cantSplit(line, maxWidth);
300 string curStr = line.substr(0, cur);
301 if (removeTrailingSpaces) {
304 unsigned width2 = font.
getSize(curStr)[0];
305 if (width2 <= maxWidth) {
307 size_t next = findSplitPoint(line, cur,
max);
315 size_t next = findSplitPoint(line,
min, cur);
320 return cantSplit(line, maxWidth);
330size_t OSDText::splitAtChar(
const std::string& line,
unsigned maxWidth)
const
332 return split(line, maxWidth, findCharSplitPoint, takeSingleChar,
false);
338 return osdText.splitAtChar(line, maxWidth);
342size_t OSDText::splitAtWord(
const std::string& line,
unsigned maxWidth)
const
344 return split(line, maxWidth, findWordSplitPoint,
SplitAtChar(*
this),
true);
347string OSDText::getCharWrappedText(
const string& txt,
unsigned maxWidth)
const
349 std::vector<string_view> wrappedLines;
352 auto p = splitAtChar(
string(line), maxWidth);
353 wrappedLines.push_back(line.substr(0, p));
354 line = line.substr(p);
355 }
while (!line.empty());
357 return join(wrappedLines,
'\n');
360string OSDText::getWordWrappedText(
const string& txt,
unsigned maxWidth)
const
362 std::vector<string_view> wrappedLines;
365 auto p = splitAtWord(
string(line), maxWidth);
366 string_view first = line.substr(0, p);
368 wrappedLines.push_back(first);
369 line = line.substr(p);
371 }
while (!line.empty());
373 return join(wrappedLines,
'\n');
Wrapper around a SDL_Surface.
Represents the output window/screen of openMSX.
OSDText(Display &display, const TclObject &name)
friend struct SplitAtChar
void getProperty(std::string_view name, TclObject &result) const override
void setProperty(Interpreter &interp, std::string_view name, const TclObject &value) override
std::string_view getType() const override
A frame buffer where pixels can be written to.
bool empty() const
Is this an empty font? (a default constructed object).
SDLSurfacePtr render(std::string text, uint8_t r, uint8_t g, uint8_t b) const
Render the given text to a new SDL_Surface.
gl::ivec2 getSize(zstring_view text) const
Return the size in pixels of the text if it would be rendered.
float getFloat(Interpreter &interp) const
int getInt(Interpreter &interp) const
zstring_view getString() const
detail::Joiner< Collection, Separator > join(Collection &&col, Separator &&sep)
void trimRight(string &str, const char *chars)
void trimLeft(string &str, const char *chars)
auto split_view(std::string_view str, Separators separators)
constexpr vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
constexpr vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
constexpr mat4 scale(const vec3 &xyz)
bool isRegularFile(const Stat &st)
This file implemented 3 utility functions:
const FileContext & systemFileContext()
constexpr octet_iterator sync_backward(octet_iterator it)
constexpr octet_iterator sync_forward(octet_iterator it)
uint32_t next(octet_iterator &it, octet_iterator end)
SplitAtChar(const OSDText &osdText_)
size_t operator()(const string &line, unsigned maxWidth)