26 , fontfile(
"skins/Vera.ttf.gz")
28 , wrapMode(NONE), wrapw(0.0), wraprelw(1.0)
39 static const char*
const vals[] = {
40 "-text",
"-font",
"-size",
"-wrap",
"-wrapw",
"-wraprelw",
43 result.insert(result.end(), std::begin(vals), std::end(vals));
49 if (name ==
"-text") {
57 }
else if (name ==
"-font") {
59 if (fontfile != val) {
67 }
else if (name ==
"-size") {
68 int size2 = value.
getInt();
73 }
else if (name ==
"-wrap") {
78 }
else if (val ==
"word") {
80 }
else if (val ==
"char") {
84 "expected one of 'none word char', but got '" +
87 if (wrapMode != wrapMode2) {
91 }
else if (name ==
"-wrapw") {
93 if (wrapw != wrapw2) {
97 }
else if (name ==
"-wraprelw") {
99 if (wraprelw != wraprelw2) {
100 wraprelw = wraprelw2;
103 }
else if (name ==
"-query-size") {
112 if (name ==
"-text") {
114 }
else if (name ==
"-font") {
116 }
else if (name ==
"-size") {
118 }
else if (name ==
"-wrap") {
121 case NONE: wrapString =
"none";
break;
122 case WORD: wrapString =
"word";
break;
123 case CHAR: wrapString =
"char";
break;
127 }
else if (name ==
"-wrapw") {
129 }
else if (name ==
"-wraprelw") {
131 }
else if (name ==
"-query-size") {
133 getRenderedSize(outX, outY);
141 void OSDText::invalidateLocal()
154 double& width,
double& height)
const
157 width =
image->getWidth();
158 height =
image->getHeight();
167 byte OSDText::getFadedAlpha()
const
172 template <
typename IMAGE> std::unique_ptr<BaseImage> OSDText::create(
173 OutputRectangle& output)
176 return make_unique<IMAGE>(0, 0, 0);
181 string file = SystemFileContext().resolve(fontfile);
182 int ptSize = size * scale;
183 font = TTFFont(file, ptSize);
184 }
catch (MSXException& e) {
185 throw MSXException(
"Couldn't open font: " + e.getMessage());
189 double pWidth, pHeight;
191 int maxWidth = int(wrapw * scale + wraprelw * pWidth + 0.5);
194 maxWidth = std::max(0, maxWidth);
199 if (wrapMode == NONE) {
201 }
else if (wrapMode == WORD) {
202 wrappedText = getWordWrappedText(text, maxWidth);
203 }
else if (wrapMode == CHAR) {
204 wrappedText = getCharWrappedText(text, maxWidth);
212 (rgba >> 24) & 0xff, (rgba >> 16) & 0xff, (rgba >> 8) & 0xff));
214 return make_unique<IMAGE>(std::move(surface));
216 return make_unique<IMAGE>(0, 0, 0);
218 }
catch (MSXException& e) {
219 throw MSXException(
"Couldn't render text: " + e.getMessage());
227 static size_t findCharSplitPoint(
const string& line,
size_t min,
size_t max)
229 auto pos = (min + max) / 2;
230 auto beginIt = line.data();
231 auto posIt = beginIt + pos;
234 auto maxIt = beginIt + max;
235 assert(fwdIt <= maxIt);
236 if (fwdIt != maxIt) {
237 return fwdIt - beginIt;
241 auto minIt = beginIt + min;
242 assert(minIt <= bwdIt); (void)minIt;
243 return bwdIt - beginIt;
251 static size_t findWordSplitPoint(
string_ref line,
size_t min,
size_t max)
253 static const char*
const delimiters =
" -/";
257 size_t pos = (min + max) / 2;
287 static size_t takeSingleChar(
const string& ,
unsigned )
292 template<
typename FindSplitPo
intFunc,
typename CantSplitFunc>
293 size_t OSDText::split(
const string& line,
unsigned maxWidth,
294 FindSplitPointFunc findSplitPoint,
295 CantSplitFunc cantSplit,
296 bool removeTrailingSpaces)
const
304 unsigned width, height;
305 font.
getSize(line, width, height);
306 if (width <= maxWidth) {
314 size_t max = line.size();
317 size_t cur = findSplitPoint(line, min, max);
321 return cantSplit(line, maxWidth);
326 string curStr = line.substr(0, cur);
327 if (removeTrailingSpaces) {
330 font.
getSize(curStr, width, height);
331 if (width <= maxWidth) {
333 size_t next = findSplitPoint(line, cur, max);
341 size_t next = findSplitPoint(line, min, cur);
346 return cantSplit(line, maxWidth);
356 size_t OSDText::splitAtChar(
const std::string& line,
unsigned maxWidth)
const
358 return split(line, maxWidth, findCharSplitPoint, takeSingleChar,
false);
364 return osdText.splitAtChar(line, maxWidth);
368 size_t OSDText::splitAtWord(
const std::string& line,
unsigned maxWidth)
const
370 return split(line, maxWidth, findWordSplitPoint,
SplitAtChar(*
this),
true);
373 string OSDText::getCharWrappedText(
const string& text,
unsigned maxWidth)
const
375 vector<string> wrappedLines;
378 auto pos = splitAtChar(line, maxWidth);
379 wrappedLines.push_back(line.substr(0, pos));
380 line = line.substr(pos);
381 }
while (!line.empty());
386 string OSDText::getWordWrappedText(
const string& text,
unsigned maxWidth)
const
388 vector<string> wrappedLines;
391 auto pos = splitAtWord(line, maxWidth);
394 wrappedLines.push_back(first.
str());
395 line = line.substr(pos);
397 }
while (!line.empty());
402 void OSDText::getRenderedSize(
double& outX,
double& outY)
const
404 SDL_Surface* surface = SDL_GetVideoSurface();
406 throw CommandException(
407 "Can't query size: no window visible");
409 DummyOutputRectangle output(surface->w, surface->h);
416 width =
image->getWidth();
417 height =
image->getHeight();
421 outX = width / scale;
422 outY = height / scale;
425 std::unique_ptr<BaseImage> OSDText::createSDL(OutputRectangle& output)
427 return create<SDLImage>(output);
430 std::unique_ptr<BaseImage> OSDText::createGL(OutputRectangle& output)
433 return create<GLImage>(output);