diff options
author | Miroslav Remák | 2018-07-17 11:22:25 +0200 |
---|---|---|
committer | Eugene Sandulenko | 2018-08-25 23:12:01 +0200 |
commit | f94ff7aa8ec510de8dc353c9c2e079db5e05d5da (patch) | |
tree | 56a636e1fc16b7176c043d7579ecb38844e053e6 /engines | |
parent | f70eb01061d3e5dd74ed8065d0435a4273d973dc (diff) | |
download | scummvm-rg350-f94ff7aa8ec510de8dc353c9c2e079db5e05d5da.tar.gz scummvm-rg350-f94ff7aa8ec510de8dc353c9c2e079db5e05d5da.tar.bz2 scummvm-rg350-f94ff7aa8ec510de8dc353c9c2e079db5e05d5da.zip |
MUTATIONOFJB: Implement word wrapping for subtitles.
Diffstat (limited to 'engines')
-rw-r--r-- | engines/mutationofjb/font.cpp | 58 | ||||
-rw-r--r-- | engines/mutationofjb/font.h | 13 | ||||
-rw-r--r-- | engines/mutationofjb/tasks/saytask.cpp | 39 | ||||
-rw-r--r-- | engines/mutationofjb/tasks/saytask.h | 4 |
4 files changed, 98 insertions, 16 deletions
diff --git a/engines/mutationofjb/font.cpp b/engines/mutationofjb/font.cpp index 235c60a39e..4350b19850 100644 --- a/engines/mutationofjb/font.cpp +++ b/engines/mutationofjb/font.cpp @@ -27,9 +27,9 @@ namespace MutationOfJB { -Font::Font(const Common::String &fileName, int horizSpacing, int vertSpacing) : +Font::Font(const Common::String &fileName, int horizSpacing, int lineHeight) : _horizSpacing(horizSpacing), - _vertSpacing(vertSpacing) { + _lineHeight(lineHeight) { load(fileName); } @@ -67,15 +67,14 @@ bool Font::load(const Common::String &fileName) { } } - if (_vertSpacing == -1) { - _vertSpacing = maxHeight; + if (_lineHeight == -1) { + _lineHeight = maxHeight; } return true; } - -void Font::drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf) { +void Font::drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf) const { GlyphMap::iterator it = _glyphs.find(glyph); if (it == _glyphs.end()) { warning("Glyph %d not found", glyph); @@ -99,13 +98,54 @@ void Font::drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics: x += glyphSurface.w + _horizSpacing; } -void Font::drawString(const Common::String &str, uint8 baseColor, int16 x, int16 y, Graphics::ManagedSurface &surf) { +int16 Font::getWidth(const Common::String &str) const { + int16 width = 0; + for (uint i = 0; i < str.size(); ++i) { + GlyphMap::iterator it = _glyphs.find(str[i]); + if (it == _glyphs.end()) { + continue; + } + + width += it->_value.w + _horizSpacing; + } + return width; +} + +int Font::getLineHeight() const { + return _lineHeight; +} + +void Font::drawString(const Common::String &str, uint8 baseColor, int16 x, int16 y, Graphics::ManagedSurface &surf) const { for (uint i = 0; i < str.size(); ++i) { drawGlyph(str[i], baseColor, x, y, surf); // "x" is updated. } } -uint8 Font::transformColor(uint8 baseColor, uint8 glyphColor) { +void Font::wordWrap(const Common::String &str, int16 maxLineWidth, Common::Array<Common::String> &lines) const { + lines.push_back(""); + + for (Common::String::const_iterator it = str.begin(); it != str.end();) { + Common::String::const_iterator partStart = it; + it = Common::find(partStart, str.end(), ' '); + if (it != str.end()) { + while (*it == ' ' && it != str.end()) { + ++it; + } + } + + Common::String part(partStart, it); // Word + following whitespace + Common::String line = lines.back() + part; + if (getWidth(line) <= maxLineWidth) { + // The part fits in the current line + lines.back() = line; + } else { + // The part must go to the next line + lines.push_back(part); + } + } +} + +uint8 Font::transformColor(uint8 baseColor, uint8 glyphColor) const { return baseColor + glyphColor - 0x10; } @@ -113,7 +153,7 @@ SystemFont::SystemFont() : Font("sysfnt.aft", 1, 7) {} SpeechFont::SpeechFont() : Font("font1.aft", -1, -1) {} -uint8 SpeechFont::transformColor(uint8 baseColor, uint8 glyphColor) { +uint8 SpeechFont::transformColor(uint8 baseColor, uint8 glyphColor) const { // Hack in original game. if (glyphColor == 0x11) { return 0xC0; diff --git a/engines/mutationofjb/font.h b/engines/mutationofjb/font.h index 5aa6a4fb78..a27303eb0d 100644 --- a/engines/mutationofjb/font.h +++ b/engines/mutationofjb/font.h @@ -37,17 +37,20 @@ class Font { public: Font(const Common::String &fileName, int horizSpacing, int vertSpacing); virtual ~Font() {} - void drawString(const Common::String &str, uint8 baseColor, int16 x, int16 y, Graphics::ManagedSurface &surf); + int getLineHeight() const; + int16 getWidth(const Common::String &text) const; + void drawString(const Common::String &str, uint8 baseColor, int16 x, int16 y, Graphics::ManagedSurface &surf) const; + void wordWrap(const Common::String &str, int16 maxLineWidth, Common::Array<Common::String> &lines) const; protected: - virtual uint8 transformColor(uint8 baseColor, uint8 glyphColor); + virtual uint8 transformColor(uint8 baseColor, uint8 glyphColor) const; private: - void drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf); + void drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf) const; bool load(const Common::String &fileName); int _horizSpacing; - int _vertSpacing; + int _lineHeight; typedef Common::HashMap<uint8, Graphics::ManagedSurface> GlyphMap; GlyphMap _glyphs; }; @@ -62,7 +65,7 @@ public: SpeechFont(); protected: - virtual uint8 transformColor(uint8 baseColor, uint8 glyphColor) override; + virtual uint8 transformColor(uint8 baseColor, uint8 glyphColor) const override; }; } diff --git a/engines/mutationofjb/tasks/saytask.cpp b/engines/mutationofjb/tasks/saytask.cpp index 2ef4cdf5df..fcef6c3211 100644 --- a/engines/mutationofjb/tasks/saytask.cpp +++ b/engines/mutationofjb/tasks/saytask.cpp @@ -27,6 +27,7 @@ #include "mutationofjb/game.h" #include "mutationofjb/gamedata.h" #include "mutationofjb/room.h" +#include "mutationofjb/util.h" #include "graphics/managed_surface.h" #include "graphics/screen.h" @@ -36,8 +37,7 @@ namespace MutationOfJB { SayTask::SayTask(const Common::String &toSay, uint8 color) : _toSay(toSay), _color(color), _timer(1000) {} void SayTask::start() { - - getTaskManager()->getGame().getAssets().getSpeechFont().drawString(_toSay, _color, 0, 0, getTaskManager()->getGame().getScreen()); + drawSubtitle(_toSay, 160, 0, _color); // TODO: Respect PTALK and LTALK commands. _timer.start(); setState(RUNNING); } @@ -52,4 +52,39 @@ void SayTask::update() { } } +void SayTask::drawSubtitle(const Common::String &text, int16 talkX, int16 talkY, uint8 color) { + const int MAX_LINE_WIDTH = 250; + + const Font &font = getTaskManager()->getGame().getAssets().getSpeechFont(); + + Common::Array<Common::String> lines; + font.wordWrap(text, MAX_LINE_WIDTH, lines); + + int16 x = talkX; + int16 y = talkY - (lines.size() - 1) * font.getLineHeight() - 15; // Get the top y + + // Clamp to screen edges + y = MAX<int16>(y, 3); + int16 maxWidth = 0; + for (uint i = 0; i < lines.size(); i++) { + int16 lineWidth = font.getWidth(lines[i]); + if (lineWidth > maxWidth) { + maxWidth = lineWidth; + } + x = MAX<int16>(x, 3 + lineWidth / 2); + x = MIN<int16>(x, 317 - lineWidth / 2); + } + + // Draw lines + for (uint i = 0; i < lines.size(); i++) { + font.drawString(lines[i], color, x - font.getWidth(lines[i]) / 2, y + i * font.getLineHeight(), getTaskManager()->getGame().getScreen()); + } + + // Remember the area occupied by the text + _boundingBox.top = x - maxWidth / 2; + _boundingBox.left = y; + _boundingBox.setWidth(maxWidth); + _boundingBox.setHeight(lines.size() * font.getLineHeight()); +} + } diff --git a/engines/mutationofjb/tasks/saytask.h b/engines/mutationofjb/tasks/saytask.h index a7ac96d875..ef66f5beb4 100644 --- a/engines/mutationofjb/tasks/saytask.h +++ b/engines/mutationofjb/tasks/saytask.h @@ -24,6 +24,7 @@ #include "mutationofjb/timer.h" +#include "common/rect.h" #include "common/str.h" namespace MutationOfJB { @@ -36,9 +37,12 @@ public: virtual void update() override; private: + void drawSubtitle(const Common::String &text, int16 talkX, int16 talkY, uint8 color); + Common::String _toSay; uint8 _color; Timer _timer; + Common::Rect _boundingBox; }; } |