aboutsummaryrefslogtreecommitdiff
path: root/graphics/macgui
diff options
context:
space:
mode:
authorEugene Sandulenko2017-01-31 23:14:03 +0100
committerEugene Sandulenko2017-01-31 23:14:37 +0100
commitd4e4a20cc53b28db31a66af3fd5d4b7569fad3c8 (patch)
tree997432834a67f94be116c99c7c91bdeb605c897e /graphics/macgui
parentc15e063bbd549261e6be020cdd046e7368d22769 (diff)
downloadscummvm-rg350-d4e4a20cc53b28db31a66af3fd5d4b7569fad3c8.tar.gz
scummvm-rg350-d4e4a20cc53b28db31a66af3fd5d4b7569fad3c8.tar.bz2
scummvm-rg350-d4e4a20cc53b28db31a66af3fd5d4b7569fad3c8.zip
GRAPHICS: Implement rendering of rich MacText
Diffstat (limited to 'graphics/macgui')
-rw-r--r--graphics/macgui/mactext.cpp98
-rw-r--r--graphics/macgui/mactext.h7
2 files changed, 79 insertions, 26 deletions
diff --git a/graphics/macgui/mactext.cpp b/graphics/macgui/mactext.cpp
index 426fc296b2..e4119039b0 100644
--- a/graphics/macgui/mactext.cpp
+++ b/graphics/macgui/mactext.cpp
@@ -45,19 +45,22 @@ MacText::MacText(Common::String s, MacWindowManager *wm, const Font *font, int f
_bgcolor = bgcolor;
_maxWidth = maxWidth;
_textMaxWidth = 0;
+ _textMaxHeight = 0;
_surface = nullptr;
_textAlignment = textAlignment;
_interLinear = 0; // 0 pixels between the lines by default
- splitString(_str);
-
- _fullRefresh = true;
-
_defaultFormatting.font = font;
_defaultFormatting.wm = wm;
_currentFormatting = _defaultFormatting;
+
+ splitString(_str);
+
+ recalcDims();
+
+ _fullRefresh = true;
}
void MacText::splitString(Common::String &str) {
@@ -118,7 +121,7 @@ void MacText::splitString(Common::String &str) {
if (*s == '\r' || *s == '\n' || nextChunk) {
Common::Array<Common::String> text;
- _textMaxWidth = MAX(_font->wordWrapText(tmp, _maxWidth, text), _textMaxWidth);
+ _font->wordWrapText(tmp, _maxWidth, text);
tmp.clear();
if (text.size()) {
@@ -163,7 +166,7 @@ void MacText::splitString(Common::String &str) {
if (tmp.size()) {
Common::Array<Common::String> text;
- _textMaxWidth = MAX(_font->wordWrapText(tmp, _maxWidth, text), _textMaxWidth);
+ _font->wordWrapText(tmp, _maxWidth, text);
_textLines[curLine].chunks[curChunk].text = text[0];
@@ -183,22 +186,19 @@ void MacText::splitString(Common::String &str) {
}
void MacText::reallocSurface() {
- int lineH = _font->getFontHeight() + _interLinear;
// round to closest 10
//TODO: work out why this rounding doesn't correctly fill the entire width
//int requiredH = (_text.size() + (_text.size() * 10 + 9) / 10) * lineH
- int requiredH = _text.size() * lineH;
- int surfW = _textMaxWidth;
if (!_surface) {
- _surface = new ManagedSurface(surfW, requiredH);
+ _surface = new ManagedSurface(_textMaxWidth, _textMaxHeight);
return;
}
- if (_surface->h < requiredH) {
+ if (_surface->h < _textMaxWidth) {
// realloc surface and copy old content
- ManagedSurface *n = new ManagedSurface(surfW, requiredH);
+ ManagedSurface *n = new ManagedSurface(_textMaxWidth, _textMaxHeight);
n->blitFrom(*_surface, Common::Point(0, 0));
delete _surface;
@@ -208,7 +208,7 @@ void MacText::reallocSurface() {
void MacText::render() {
if (_fullRefresh) {
- render(0, _text.size());
+ render(0, _textLines.size());
_fullRefresh = false;
}
@@ -218,25 +218,23 @@ void MacText::render(int from, int to) {
reallocSurface();
from = MAX<int>(0, from);
- to = MIN<int>(to, _text.size());
-
- int lineH = _font->getFontHeight() + _interLinear;
- int y = from * lineH;
+ to = MIN<int>(to, _textLines.size() - 1);
// Clear the screen
- _surface->fillRect(Common::Rect(0, y, _surface->w, to * lineH), _bgcolor);
+ _surface->fillRect(Common::Rect(0, _textLines[from].y, _surface->w, _textLines[to].y + getLineHeight(to)), _bgcolor);
- for (int i = from; i < to; i++) {
+ for (int i = from; i <= to; i++) {
int xOffset = 0;
if (_textAlignment == kTextAlignRight)
- xOffset = _textMaxWidth - _font->getStringWidth(_text[i]);
+ xOffset = _textMaxWidth - getLineWidth(i);
else if (_textAlignment == kTextAlignCenter)
- xOffset = (_textMaxWidth / 2) - (_font->getStringWidth(_text[i]) / 2);
-
- //TODO: _textMaxWidth, when -1, was not rendering ANY text.
- _font->drawString(_surface, _text[i], xOffset, y, _maxWidth, _fgcolor);
+ xOffset = (_textMaxWidth / 2) - (getLineWidth(i) / 2);
- y += _font->getFontHeight() + _interLinear;
+ // TODO: _textMaxWidth, when -1, was not rendering ANY text.
+ for (uint j = 0; j < _textLines[i].chunks.size(); j++) {
+ _textLines[i].chunks[j].getFont()->drawString(_surface, _textLines[i].chunks[j].text, xOffset, _textLines[i].y, _maxWidth, _fgcolor);
+ xOffset += _textLines[i].chunks[j].getFont()->getStringWidth(_textLines[i].chunks[j].text);
+ }
}
for (uint i = 0; i < _textLines.size(); i++) {
@@ -249,6 +247,50 @@ void MacText::render(int from, int to) {
}
}
+int MacText::getLineWidth(int line) {
+ if (line >= _textLines.size())
+ return 0;
+
+ if (_textLines[line].width != -1)
+ return _textLines[line].width;
+
+ int width = 0;
+ int height = 0;
+
+ for (uint i = 0; i < _textLines[line].chunks.size(); i++) {
+ width += _textLines[line].chunks[i].getFont()->getStringWidth(_textLines[line].chunks[i].text);
+ height = MAX(height, _textLines[line].chunks[i].getFont()->getFontHeight());
+ }
+
+ _textLines[line].width = width;
+ _textLines[line].height = height;
+
+ return width;
+}
+
+int MacText::getLineHeight(int line) {
+ if (line >= _textLines.size())
+ return 0;
+
+ getLineWidth(line); // This calculates height also
+
+ return _textLines[line].height;
+}
+
+void MacText::recalcDims() {
+ int y = 0;
+ _textMaxWidth = 0;
+
+ for (uint i = 0; i < _textLines.size(); i++) {
+ _textLines[i].y = y;
+
+ y += getLineHeight(i) + _interLinear;
+ _textMaxWidth = MAX(_textMaxWidth, getLineWidth(i));
+ }
+
+ _textMaxHeight = y;
+}
+
void MacText::draw(ManagedSurface *g, int x, int y, int w, int h, int xoff, int yoff) {
render();
@@ -264,7 +306,10 @@ void MacText::draw(ManagedSurface *g, int x, int y, int w, int h, int xoff, int
void MacText::appendText(Common::String str) {
int oldLen = _text.size();
+ // TODO: Recalc length
+
splitString(str);
+ recalcDims();
render(oldLen + 1, _text.size());
}
@@ -272,10 +317,13 @@ void MacText::appendText(Common::String str) {
void MacText::replaceLastLine(Common::String str) {
int oldLen = MAX<int>(0, _text.size() - 1);
+ // TODO: Recalc length, adapt to _textLines
+
if (_text.size())
_text.pop_back();
splitString(str);
+ recalcDims();
render(oldLen, _text.size());
}
diff --git a/graphics/macgui/mactext.h b/graphics/macgui/mactext.h
index f94b2bc6ff..90f85e6b22 100644
--- a/graphics/macgui/mactext.h
+++ b/graphics/macgui/mactext.h
@@ -76,11 +76,13 @@ struct MacFontRun {
struct MacTextLine {
int width;
int height;
+ int y;
Common::Array<MacFontRun> chunks;
MacTextLine() {
width = height = -1;
+ y = 0;
}
};
@@ -101,8 +103,10 @@ public:
private:
void splitString(Common::String &s);
void render(int from, int to);
- void calcMaxWidth();
+ void recalcDims();
void reallocSurface();
+ int getLineWidth(int line);
+ int getLineHeight(int line);
private:
MacWindowManager *_wm;
@@ -117,6 +121,7 @@ private:
Common::Array<Common::String> _text;
int _textMaxWidth;
+ int _textMaxHeight;
Graphics::ManagedSurface *_surface;
bool _fullRefresh;