diff --git a/Aquaria/DSQ.cpp b/Aquaria/DSQ.cpp index c89a7b4..dc18033 100644 --- a/Aquaria/DSQ.cpp +++ b/Aquaria/DSQ.cpp @@ -3562,7 +3562,7 @@ std::string DSQ::getUserInputString(std::string labelText, std::string t, bool a text.resize(text.size()-1); inputText->setText(text); } - if (inputText->getWidth() < 800-60) + if (inputText->getActualWidth() < 800-60) { doAlphabetInputKey(KEY_A, 'a', (char*)&map, &text, 'A'); doAlphabetInputKey(KEY_B, 'b', (char*)&map, &text, 'B'); diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index 824e8d2..b6847f4 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -10024,9 +10024,9 @@ const float helpTextScrollClickTime = -helpTextScrollSpeed; void Game::onHelpDown() { float to = helpText->offset.y - helpTextScrollClickAmount; - if (to < -helpText->getFullHeight() + core->getVirtualHeight()) + if (to < -helpText->getHeight() + core->getVirtualHeight()) { - to = -helpText->getFullHeight() + core->getVirtualHeight(); + to = -helpText->getHeight() + core->getVirtualHeight(); } helpText->offset.interpolateTo(Vector(0, to), helpTextScrollClickTime); } @@ -10052,9 +10052,9 @@ void Game::update(float dt) { helpText->offset.stop(); helpText->offset.y -= helpTextScrollSpeed * dt; - if (helpText->offset.y < -helpText->getFullHeight() + core->getVirtualHeight()) + if (helpText->offset.y < -helpText->getHeight() + core->getVirtualHeight()) { - helpText->offset.y = -helpText->getFullHeight() + core->getVirtualHeight(); + helpText->offset.y = -helpText->getHeight() + core->getVirtualHeight(); } } if (isActing(ACTION_SWIMUP)) diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index 6dad38c..de1cd06 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -9195,7 +9195,7 @@ luaFunc(text_setFontSize) { BaseText *txt = getText(L); if (txt) - txt->setFontSize(lua_tointeger(L, 2)); + txt->setFontSize(lua_tonumber(L, 2)); luaReturnNil(); } @@ -9203,7 +9203,7 @@ luaFunc(text_setWidth) { BaseText *txt = getText(L); if (txt) - txt->setWidth(lua_tointeger(L, 2)); + txt->setWidth(lua_tonumber(L, 2)); luaReturnNil(); } @@ -9227,6 +9227,12 @@ luaFunc(text_getStringWidth) luaReturnNum(txt ? txt->getStringWidth(getString(L, 2)) : 0.0f); } +luaFunc(text_getActualWidth) +{ + BaseText *txt = getText(L); + luaReturnNum(txt ? txt->getActualWidth() : 0.0f); +} + luaFunc(loadShader) { int handle = 0; @@ -10333,6 +10339,7 @@ static const struct { luaRegister(text_setAlign), luaRegister(text_getHeight), luaRegister(text_getStringWidth), + luaRegister(text_getActualWidth), luaRegister(loadShader), luaRegister(createShader), diff --git a/Aquaria/WorldMapRender.cpp b/Aquaria/WorldMapRender.cpp index 2103d8b..37363c2 100644 --- a/Aquaria/WorldMapRender.cpp +++ b/Aquaria/WorldMapRender.cpp @@ -323,7 +323,7 @@ public: text->setAlign(ALIGN_CENTER); textBG = new RoundedRect(); - textBG->setWidthHeight(text->getWidth() + 20, 25, 10); // 30 + textBG->setWidthHeight(text->getActualWidth() + 20, 25, 10); // 30 textBG->alpha = 0; textBG->followCamera = 1; game->addRenderObject(textBG, LR_WORLDMAPHUD); diff --git a/BBGE/BaseText.h b/BBGE/BaseText.h index ec84314..75716f5 100644 --- a/BBGE/BaseText.h +++ b/BBGE/BaseText.h @@ -10,12 +10,12 @@ public: BaseText() { addType(SCO_TEXT); } virtual ~BaseText() {} virtual void setText(const std::string& text) = 0; - virtual void setWidth(int width) = 0; - virtual void setFontSize(int sz) = 0; + virtual void setWidth(float width) = 0; + virtual void setFontSize(float sz) = 0; virtual void setAlign(Align a) = 0; - virtual float getHeight() = 0; - virtual float getStringWidth(const std::string& text) = 0; - + virtual float getHeight() = 0; // total height + virtual float getStringWidth(const std::string& text) = 0; // width of string when not auto-wrapped + virtual float getActualWidth() = 0; // width of text after wrapping }; #endif diff --git a/BBGE/BitmapFont.cpp b/BBGE/BitmapFont.cpp index 277656d..7c646b8 100644 --- a/BBGE/BitmapFont.cpp +++ b/BBGE/BitmapFont.cpp @@ -132,12 +132,12 @@ void BitmapText::setText(const std::string &text) formatText(); } -void BitmapText::setWidth(int width) +void BitmapText::setWidth(float width) { textWidth = width; } -int BitmapText::getSetWidth() +float BitmapText::getSetWidth() { return textWidth; } @@ -155,8 +155,9 @@ void BitmapText::formatText() lines.clear(); std::string currentLine; int lastSpace = -1; - int currentWidth = 0; + float currentWidth = 0; alignWidth = 0; + maxW = 0; for (int i = 0; i < text.size(); i++) { //currentWidth += spacingMap[text[i]]*fontDrawSize; @@ -174,6 +175,7 @@ void BitmapText::formatText() text = text.substr(lastSpace+1, tsz); i = 0; alignWidth = currentWidth; + maxW = std::max(currentWidth, maxW); currentWidth = 0; lastSpace = 0; continue; @@ -182,8 +184,9 @@ void BitmapText::formatText() if (text[i] == ' ') { lastSpace = i; - } + } } + maxW = std::max(currentWidth, maxW); if (alignWidth == 0) alignWidth = currentWidth; if (!text.empty() && (text.size() > 1 || text[0] != ' ')) @@ -248,7 +251,7 @@ void BitmapText::scrollText(const std::string &text, float scrollSpeed) currentScrollChar = 0; } -void BitmapText::setFontSize(int sz) +void BitmapText::setFontSize(float sz) { this->fontDrawSize = sz; } diff --git a/BBGE/BitmapFont.h b/BBGE/BitmapFont.h index 188d4c1..eb293a2 100644 --- a/BBGE/BitmapFont.h +++ b/BBGE/BitmapFont.h @@ -56,10 +56,10 @@ class BitmapText : public BaseText public: BitmapText(BmpFont *bmpFont); void setText(const std::string &text); - void setWidth(int width); - int getSetWidth(); // get the width that was set + void setWidth(float width); + float getSetWidth(); // get the width that was set void scrollText(const std::string &text, float scrollSpeed); - void setFontSize(int sz); + void setFontSize(float sz); bool isScrollingText(); void stopScrollingText(); bool isEmpty(); @@ -75,7 +75,8 @@ public: virtual float getHeight(); void unloadDevice(); void reloadDevice(); - virtual float getStringWidth(const std::string& text); + float getStringWidth(const std::string& text); + float getActualWidth() { return maxW; } int getNumLines(); protected: @@ -89,18 +90,19 @@ protected: int currentScrollLine; int currentScrollChar; Align align; - int alignWidth; + float alignWidth; typedef std::map SpacingMap; SpacingMap spacingMap; void formatText(); - int fontDrawSize; + float fontDrawSize; void onRender(); typedef std::vector Lines; Lines lines; typedef std::vector ColorIndices; std::vector colorIndices; std::string text; - int textWidth; + float textWidth; + float maxW; }; #endif diff --git a/BBGE/DebugFont.cpp b/BBGE/DebugFont.cpp index 0e253d8..abcf507 100644 --- a/BBGE/DebugFont.cpp +++ b/BBGE/DebugFont.cpp @@ -26,6 +26,7 @@ DebugFont::DebugFont(int initSz, const std::string &initText) followCamera = 1; fontDrawSize = 5; textWidth = 800; + maxW = 0; if (initSz) { setFontSize(initSz); @@ -37,12 +38,12 @@ DebugFont::DebugFont(int initSz, const std::string &initText) } } -void DebugFont::setWidth(int width) +void DebugFont::setWidth(float width) { textWidth = width; } -void DebugFont::setFontSize(int sz) +void DebugFont::setFontSize(float sz) { fontDrawSize = sz; } @@ -67,7 +68,12 @@ float DebugFont::getStringWidth(const std::string& text) ++c; } maxchars = std::max(maxchars, c); - return float(fontDrawSize * maxchars); + return fontDrawSize * maxchars * (1.4f * 0.75f); +} + +float DebugFont::getActualWidth() +{ + return maxW * (1.4f * 0.75f); // numbers taken from onRender() } void DebugFont::formatText() @@ -77,8 +83,8 @@ void DebugFont::formatText() lines.clear(); std::string currentLine; int lastSpace = -1; - int currentWidth = 0; - int alignWidth = 0; + float currentWidth = 0; + maxW = 0; for (int i = 0; i < text.size(); i++) { currentWidth += fontDrawSize; @@ -93,7 +99,7 @@ void DebugFont::formatText() int tsz = text.size(); text = text.substr(lastSpace+1, tsz); i = 0; - alignWidth = currentWidth; + maxW = std::max(maxW, currentWidth); currentWidth = 0; lastSpace = 0; continue; @@ -104,8 +110,7 @@ void DebugFont::formatText() lastSpace = i; } } - if (alignWidth == 0) - alignWidth = currentWidth; + maxW = std::max(maxW, currentWidth); if (!text.empty() && (text.size() > 1 || text[0] != ' ')) { lines.push_back(text); diff --git a/BBGE/DebugFont.h b/BBGE/DebugFont.h index d68d3e9..7258a77 100644 --- a/BBGE/DebugFont.h +++ b/BBGE/DebugFont.h @@ -29,19 +29,21 @@ class DebugFont : public BaseText public: DebugFont(int initFontSize=0, const std::string &initText=""); void setText(const std::string &text); - void setWidth(int width); - void setFontSize(int sz); + void setWidth(float width); + void setFontSize(float sz); int getNumLines() { return lines.size(); } virtual void setAlign(Align align); virtual float getHeight(); virtual float getStringWidth(const std::string& text); + virtual float getActualWidth(); protected: - int fontDrawSize, textWidth; + float fontDrawSize, textWidth; void formatText(); void onRender(); std::string text; std::vector lines; Align align; + float maxW; }; class Quad; diff --git a/BBGE/TTFFont.cpp b/BBGE/TTFFont.cpp index 906dbbd..e7cdc27 100644 --- a/BBGE/TTFFont.cpp +++ b/BBGE/TTFFont.cpp @@ -63,6 +63,7 @@ TTFText::TTFText(TTFFont *f) : font(f) h = 0; width = 0; shadow = false; + maxW = 0; } void TTFText::setText(const std::string &txt) @@ -95,36 +96,41 @@ void TTFText::updateAlign() } } -float TTFText::getWidth() -{ - return getStringWidth(originalText); -} float TTFText::getHeight() { - float llx, lly, llz, urx, ury, urz; - font->font->BBox(originalText.c_str(), llx, lly, llz, urx, ury, urz); - return ury - lly; + return text.size()*lineHeight; } float TTFText::getStringWidth(const std::string& s) { + float w = 0; + std::string cp = s; float llx, lly, llz, urx, ury, urz; - font->font->BBox(s.c_str(), llx, lly, llz, urx, ury, urz); - return urx - llx; + const char *start = cp.c_str(); + size_t begin = 0; + for(size_t i = 0; i < cp.length(); ++i) + { + const char c = cp[i]; + if(c == '\n') + { + cp[i] = 0; + const char *p = start + begin; + font->font->BBox(p, llx, lly, llz, urx, ury, urz); + w = std::max(w, urx - llx); + cp[i] = c; + begin = i + 1; + } + } + if(begin < cp.length()) + { + font->font->BBox(start + begin, llx, lly, llz, urx, ury, urz); + w = std::max(w, urx - llx); + } + return w; } -float TTFText::getFullHeight() -{ - /* - float llx, lly, llz, urx, ury, urz; - font->font->BBox(originalText.c_str(), llx, lly, llz, urx, ury, urz); - float diff = ury - lly; - */ - return text.size()*lineHeight; -} - -void TTFText::setWidth(int width) +void TTFText::setWidth(float width) { this->width = width; @@ -132,7 +138,7 @@ void TTFText::setWidth(int width) updateFormatting(); } -void TTFText::setFontSize(int) +void TTFText::setFontSize(float) { } @@ -142,12 +148,18 @@ void TTFText::updateFormatting() text.clear(); int i=0; int sz = originalText.size(); + maxW = 0; for (i = 0; i < sz; i++) { if (originalText[i] == '\n') { - text.push_back(originalText.substr(start, i-start)); + std::string part = originalText.substr(start, i-start); + text.push_back(part); start = i+1; + float llx, lly, llz, urx, ury, urz; + font->font->BBox(part.c_str(), llx, lly, llz, urx, ury, urz); + float w = urx - llx; + maxW = std::max(maxW, w); } else { @@ -156,25 +168,39 @@ void TTFText::updateFormatting() lastSpace = i; } float llx, lly, llz, urx, ury, urz; - font->font->BBox(originalText.substr(start, i-start).c_str(), llx, lly, llz, urx, ury, urz); - int w = urx - llx; + std::string part = originalText.substr(start, i-start); + font->font->BBox(part.c_str(), llx, lly, llz, urx, ury, urz); + float w = urx - llx; + if (width != 0 && w >= width) { - if (lastSpace != -1) { - text.push_back(originalText.substr(start, lastSpace-start)); + if (lastSpace != -1) + { + part = originalText.substr(start, lastSpace-start); i = lastSpace+1; lastSpace = -1; start = i; } - else { - text.push_back(originalText.substr(start, i-start)); - } + else + part = originalText.substr(start, i-start); + + text.push_back(part); + // recalc width of remaining text after linebreak + font->font->BBox(part.c_str(), llx, lly, llz, urx, ury, urz); + w = urx - llx; } + + maxW = std::max(maxW, w); } } if (i == sz) { - text.push_back(originalText.substr(start, i-start)); + std::string part = originalText.substr(start, i-start); + text.push_back(part); + float llx, lly, llz, urx, ury, urz; + font->font->BBox(part.c_str(), llx, lly, llz, urx, ury, urz); + float w = urx - llx; + maxW = std::max(maxW, w); } lineHeight = font->font->LineHeight(); } @@ -184,7 +210,7 @@ void TTFText::onUpdate(float dt) RenderObject::onUpdate(dt); } -int TTFText::getLineHeight() +float TTFText::getLineHeight() { return lineHeight; } diff --git a/BBGE/TTFFont.h b/BBGE/TTFFont.h index b23438a..d675117 100644 --- a/BBGE/TTFFont.h +++ b/BBGE/TTFFont.h @@ -53,17 +53,16 @@ public: TTFText(TTFFont *font); void setText(const std::string &txt); void setAlign(Align align); - void setWidth(int width); - float getWidth(); + void setWidth(float width); float getHeight(); - float getFullHeight(); - void setFontSize(int); // dummy + float getActualWidth() { return maxW; } + void setFontSize(float); // dummy float getStringWidth(const std::string& s); bool shadow; int findLine(const std::string &label); - int getLineHeight(); + float getLineHeight(); protected: - int width; + float width; float lineHeight; void updateAlign(); Align align; @@ -75,6 +74,7 @@ protected: std::vector text; TTFFont *font; int hw,h; + float maxW; }; #endif