summaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorEkdohibs <nathanael.courant@laposte.net>2016-05-31 17:30:11 +0200
committerEkdohibs <nathanael.courant@laposte.net>2016-05-31 17:34:29 +0200
commit14ef2b445adcec770defe1abf83af9d22ccf39d8 (patch)
treebe434ea35d6134f4e7b90a74283a21815ed079ee /src/util
parent1d40385d4aacf0cbea4b19ff06940e8c9bebaf47 (diff)
downloadminetest-14ef2b445adcec770defe1abf83af9d22ccf39d8.tar.gz
minetest-14ef2b445adcec770defe1abf83af9d22ccf39d8.tar.bz2
minetest-14ef2b445adcec770defe1abf83af9d22ccf39d8.zip
Add colored text (not only colored chat).
Add documentation, move files to a proper place and avoid memory leaks. Make it work with most kind of texts, and allow backgrounds too.
Diffstat (limited to 'src/util')
-rw-r--r--src/util/CMakeLists.txt11
-rw-r--r--src/util/coloredstring.cpp68
-rw-r--r--src/util/coloredstring.h44
-rw-r--r--src/util/enriched_string.cpp166
-rw-r--r--src/util/enriched_string.h91
-rw-r--r--src/util/statictext.cpp654
-rw-r--r--src/util/statictext.h150
-rw-r--r--src/util/string.h32
8 files changed, 290 insertions, 926 deletions
diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt
index e028a0435..f571ab22c 100644
--- a/src/util/CMakeLists.txt
+++ b/src/util/CMakeLists.txt
@@ -1,17 +1,9 @@
-if(USE_FREETYPE)
- set(UTIL_FREETYPEDEP_SRCS
- ${CMAKE_CURRENT_SOURCE_DIR}/statictext.cpp
- )
-else()
- set(UTIL_FREETYPEDEP_SRCS )
-endif(USE_FREETYPE)
-
set(UTIL_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/areastore.cpp
${CMAKE_CURRENT_SOURCE_DIR}/auth.cpp
${CMAKE_CURRENT_SOURCE_DIR}/base64.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/coloredstring.cpp
${CMAKE_CURRENT_SOURCE_DIR}/directiontables.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/enriched_string.cpp
${CMAKE_CURRENT_SOURCE_DIR}/numeric.cpp
${CMAKE_CURRENT_SOURCE_DIR}/pointedthing.cpp
${CMAKE_CURRENT_SOURCE_DIR}/serialize.cpp
@@ -20,6 +12,5 @@ set(UTIL_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/string.cpp
${CMAKE_CURRENT_SOURCE_DIR}/srp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/timetaker.cpp
- ${UTIL_FREETYPEDEP_SRCS}
PARENT_SCOPE)
diff --git a/src/util/coloredstring.cpp b/src/util/coloredstring.cpp
deleted file mode 100644
index 7db586550..000000000
--- a/src/util/coloredstring.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-Copyright (C) 2013 xyz, Ilya Zhuravlev <whatever@xyz.is>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "coloredstring.h"
-#include "util/string.h"
-
-ColoredString::ColoredString()
-{}
-
-ColoredString::ColoredString(const std::wstring &string, const std::vector<SColor> &colors):
- m_string(string),
- m_colors(colors)
-{}
-
-ColoredString::ColoredString(const std::wstring &s) {
- m_string = colorizeText(s, m_colors, SColor(255, 255, 255, 255));
-}
-
-void ColoredString::operator=(const wchar_t *str) {
- m_string = colorizeText(str, m_colors, SColor(255, 255, 255, 255));
-}
-
-size_t ColoredString::size() const {
- return m_string.size();
-}
-
-ColoredString ColoredString::substr(size_t pos, size_t len) const {
- if (pos == m_string.length())
- return ColoredString();
- if (len == std::string::npos || pos + len > m_string.length()) {
- return ColoredString(
- m_string.substr(pos, std::string::npos),
- std::vector<SColor>(m_colors.begin() + pos, m_colors.end())
- );
- } else {
- return ColoredString(
- m_string.substr(pos, len),
- std::vector<SColor>(m_colors.begin() + pos, m_colors.begin() + pos + len)
- );
- }
-}
-
-const wchar_t *ColoredString::c_str() const {
- return m_string.c_str();
-}
-
-const std::vector<SColor> &ColoredString::getColors() const {
- return m_colors;
-}
-
-const std::wstring &ColoredString::getString() const {
- return m_string;
-}
diff --git a/src/util/coloredstring.h b/src/util/coloredstring.h
deleted file mode 100644
index a6d98db30..000000000
--- a/src/util/coloredstring.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-Copyright (C) 2013 xyz, Ilya Zhuravlev <whatever@xyz.is>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef COLOREDSTRING_HEADER
-#define COLOREDSTRING_HEADER
-
-#include <string>
-#include <vector>
-#include <SColor.h>
-
-using namespace irr::video;
-
-class ColoredString {
-public:
- ColoredString();
- ColoredString(const std::wstring &s);
- ColoredString(const std::wstring &string, const std::vector<SColor> &colors);
- void operator=(const wchar_t *str);
- size_t size() const;
- ColoredString substr(size_t pos = 0, size_t len = std::string::npos) const;
- const wchar_t *c_str() const;
- const std::vector<SColor> &getColors() const;
- const std::wstring &getString() const;
-private:
- std::wstring m_string;
- std::vector<SColor> m_colors;
-};
-
-#endif
diff --git a/src/util/enriched_string.cpp b/src/util/enriched_string.cpp
new file mode 100644
index 000000000..a7fc3a828
--- /dev/null
+++ b/src/util/enriched_string.cpp
@@ -0,0 +1,166 @@
+/*
+Copyright (C) 2013 xyz, Ilya Zhuravlev <whatever@xyz.is>
+Copyright (C) 2016 Nore, Nathanaƫl Courant <nore@mesecons.net>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "enriched_string.h"
+#include "util/string.h"
+#include "log.h"
+using namespace irr::video;
+
+EnrichedString::EnrichedString()
+{
+ clear();
+}
+
+EnrichedString::EnrichedString(const std::wstring &string,
+ const std::vector<SColor> &colors):
+ m_string(string),
+ m_colors(colors),
+ m_has_background(false)
+{}
+
+EnrichedString::EnrichedString(const std::wstring &s, const SColor &color)
+{
+ clear();
+ addAtEnd(s, color);
+}
+
+EnrichedString::EnrichedString(const wchar_t *str, const SColor &color)
+{
+ clear();
+ addAtEnd(std::wstring(str), color);
+}
+
+void EnrichedString::operator=(const wchar_t *str)
+{
+ clear();
+ addAtEnd(std::wstring(str), SColor(255, 255, 255, 255));
+}
+
+void EnrichedString::addAtEnd(const std::wstring &s, const SColor &initial_color)
+{
+ SColor color(initial_color);
+ size_t i = 0;
+ while (i < s.length()) {
+ if (s[i] != L'\x1b') {
+ m_string += s[i];
+ m_colors.push_back(color);
+ ++i;
+ continue;
+ }
+ ++i;
+ size_t start_index = i;
+ size_t length;
+ if (i == s.length()) {
+ break;
+ }
+ if (s[i] == L'(') {
+ ++i;
+ ++start_index;
+ while (i < s.length() && s[i] != L')') {
+ if (s[i] == L'\\') {
+ ++i;
+ }
+ ++i;
+ }
+ length = i - start_index;
+ ++i;
+ } else {
+ ++i;
+ length = 1;
+ }
+ std::wstring escape_sequence(s, start_index, length);
+ std::vector<std::wstring> parts = split(escape_sequence, L'@');
+ if (parts[0] == L"c") {
+ if (parts.size() < 2) {
+ continue;
+ }
+ parseColorString(wide_to_utf8(parts[1]), color, true);
+ } else if (parts[0] == L"b") {
+ if (parts.size() < 2) {
+ continue;
+ }
+ parseColorString(wide_to_utf8(parts[1]), m_background, true);
+ m_has_background = true;
+ }
+ continue;
+ }
+}
+
+void EnrichedString::addChar(const EnrichedString &source, size_t i)
+{
+ m_string += source.m_string[i];
+ m_colors.push_back(source.m_colors[i]);
+}
+
+void EnrichedString::addCharNoColor(wchar_t c)
+{
+ m_string += c;
+ if (m_colors.empty()) {
+ m_colors.push_back(SColor(255, 255, 255, 255));
+ } else {
+ m_colors.push_back(m_colors[m_colors.size() - 1]);
+ }
+}
+
+EnrichedString EnrichedString::operator+(const EnrichedString &other) const
+{
+ std::vector<SColor> result;
+ result.insert(result.end(), m_colors.begin(), m_colors.end());
+ result.insert(result.end(), other.m_colors.begin(), other.m_colors.end());
+ return EnrichedString(m_string + other.m_string, result);
+}
+
+void EnrichedString::operator+=(const EnrichedString &other)
+{
+ m_string += other.m_string;
+ m_colors.insert(m_colors.end(), other.m_colors.begin(), other.m_colors.end());
+}
+
+EnrichedString EnrichedString::substr(size_t pos, size_t len) const
+{
+ if (pos == m_string.length()) {
+ return EnrichedString();
+ }
+ if (len == std::string::npos || pos + len > m_string.length()) {
+ return EnrichedString(
+ m_string.substr(pos, std::string::npos),
+ std::vector<SColor>(m_colors.begin() + pos, m_colors.end())
+ );
+ } else {
+ return EnrichedString(
+ m_string.substr(pos, len),
+ std::vector<SColor>(m_colors.begin() + pos, m_colors.begin() + pos + len)
+ );
+ }
+}
+
+const wchar_t *EnrichedString::c_str() const
+{
+ return m_string.c_str();
+}
+
+const std::vector<SColor> &EnrichedString::getColors() const
+{
+ return m_colors;
+}
+
+const std::wstring &EnrichedString::getString() const
+{
+ return m_string;
+}
diff --git a/src/util/enriched_string.h b/src/util/enriched_string.h
new file mode 100644
index 000000000..1aca8948a
--- /dev/null
+++ b/src/util/enriched_string.h
@@ -0,0 +1,91 @@
+/*
+Copyright (C) 2013 xyz, Ilya Zhuravlev <whatever@xyz.is>
+Copyright (C) 2016 Nore, Nathanaƫl Courant <nore@mesecons.net>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef ENRICHEDSTRING_HEADER
+#define ENRICHEDSTRING_HEADER
+
+#include <string>
+#include <vector>
+#include <SColor.h>
+
+class EnrichedString {
+public:
+ EnrichedString();
+ EnrichedString(const std::wstring &s,
+ const irr::video::SColor &color = irr::video::SColor(255, 255, 255, 255));
+ EnrichedString(const wchar_t *str,
+ const irr::video::SColor &color = irr::video::SColor(255, 255, 255, 255));
+ EnrichedString(const std::wstring &string,
+ const std::vector<irr::video::SColor> &colors);
+ void operator=(const wchar_t *str);
+ void addAtEnd(const std::wstring &s, const irr::video::SColor &color);
+
+ // Adds the character source[i] at the end.
+ // An EnrichedString should always be able to be copied
+ // to the end of an existing EnrichedString that way.
+ void addChar(const EnrichedString &source, size_t i);
+
+ // Adds a single character at the end, without specifying its
+ // color. The color used will be the one from the last character.
+ void addCharNoColor(wchar_t c);
+
+ EnrichedString substr(size_t pos = 0, size_t len = std::string::npos) const;
+ EnrichedString operator+(const EnrichedString &other) const;
+ void operator+=(const EnrichedString &other);
+ const wchar_t *c_str() const;
+ const std::vector<irr::video::SColor> &getColors() const;
+ const std::wstring &getString() const;
+ inline bool operator==(const EnrichedString &other) const
+ {
+ return (m_string == other.m_string && m_colors == other.m_colors);
+ }
+ inline bool operator!=(const EnrichedString &other) const
+ {
+ return !(*this == other);
+ }
+ inline void clear()
+ {
+ m_string.clear();
+ m_colors.clear();
+ m_has_background = false;
+ }
+ inline bool empty() const
+ {
+ return m_string.empty();
+ }
+ inline size_t size() const
+ {
+ return m_string.size();
+ }
+ inline bool hasBackground() const
+ {
+ return m_has_background;
+ }
+ inline irr::video::SColor getBackground() const
+ {
+ return m_background;
+ }
+private:
+ std::wstring m_string;
+ std::vector<irr::video::SColor> m_colors;
+ bool m_has_background;
+ irr::video::SColor m_background;
+};
+
+#endif
diff --git a/src/util/statictext.cpp b/src/util/statictext.cpp
deleted file mode 100644
index b534b560e..000000000
--- a/src/util/statictext.cpp
+++ /dev/null
@@ -1,654 +0,0 @@
-// Copyright (C) 2002-2012 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine".
-// For conditions of distribution and use, see copyright notice in irrlicht.h
-
-#include "statictext.h"
-#ifdef _IRR_COMPILE_WITH_GUI_
-
-//Only compile this if freetype is enabled.
-
-#include <vector>
-#include <string>
-#include <iostream>
-#include <IGUISkin.h>
-#include <IGUIEnvironment.h>
-#include <IGUIFont.h>
-#include <IVideoDriver.h>
-#include <rect.h>
-#include <SColor.h>
-
-#include "cguittfont/xCGUITTFont.h"
-#include "util/string.h"
-
-namespace irr
-{
-namespace gui
-{
-//! constructor
-StaticText::StaticText(const wchar_t* text, bool border,
- IGUIEnvironment* environment, IGUIElement* parent,
- s32 id, const core::rect<s32>& rectangle,
- bool background)
-: IGUIStaticText(environment, parent, id, rectangle),
- HAlign(EGUIA_UPPERLEFT), VAlign(EGUIA_UPPERLEFT),
- Border(border), OverrideColorEnabled(false), OverrideBGColorEnabled(false), WordWrap(false), Background(background),
- RestrainTextInside(true), RightToLeft(false),
- OverrideColor(video::SColor(101,255,255,255)), BGColor(video::SColor(101,210,210,210)),
- OverrideFont(0), LastBreakFont(0)
-{
- #ifdef _DEBUG
- setDebugName("StaticText");
- #endif
-
- Text = text;
- if (environment && environment->getSkin())
- {
- BGColor = environment->getSkin()->getColor(gui::EGDC_3D_FACE);
- }
-}
-
-
-//! destructor
-StaticText::~StaticText()
-{
- if (OverrideFont)
- OverrideFont->drop();
-}
-
-
-//! draws the element and its children
-void StaticText::draw()
-{
- if (!IsVisible)
- return;
-
- IGUISkin* skin = Environment->getSkin();
- if (!skin)
- return;
- video::IVideoDriver* driver = Environment->getVideoDriver();
-
- core::rect<s32> frameRect(AbsoluteRect);
-
- // draw background
-
- if (Background)
- {
- if ( !OverrideBGColorEnabled ) // skin-colors can change
- BGColor = skin->getColor(gui::EGDC_3D_FACE);
-
- driver->draw2DRectangle(BGColor, frameRect, &AbsoluteClippingRect);
- }
-
- // draw the border
-
- if (Border)
- {
- skin->draw3DSunkenPane(this, 0, true, false, frameRect, &AbsoluteClippingRect);
- frameRect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X);
- }
-
- // draw the text
- if (Text.size())
- {
- IGUIFont* font = getActiveFont();
-
- if (font)
- {
- if (!WordWrap)
- {
- // TODO: add colors here
- if (VAlign == EGUIA_LOWERRIGHT)
- {
- frameRect.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y -
- font->getDimension(L"A").Height - font->getKerningHeight();
- }
- if (HAlign == EGUIA_LOWERRIGHT)
- {
- frameRect.UpperLeftCorner.X = frameRect.LowerRightCorner.X -
- font->getDimension(Text.c_str()).Width;
- }
-
- font->draw(Text.c_str(), frameRect,
- OverrideColorEnabled ? OverrideColor : skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT),
- HAlign == EGUIA_CENTER, VAlign == EGUIA_CENTER, (RestrainTextInside ? &AbsoluteClippingRect : NULL));
- }
- else
- {
- if (font != LastBreakFont)
- breakText();
-
- core::rect<s32> r = frameRect;
- s32 height = font->getDimension(L"A").Height + font->getKerningHeight();
- s32 totalHeight = height * BrokenText.size();
- if (VAlign == EGUIA_CENTER)
- {
- r.UpperLeftCorner.Y = r.getCenter().Y - (totalHeight / 2);
- }
- else if (VAlign == EGUIA_LOWERRIGHT)
- {
- r.UpperLeftCorner.Y = r.LowerRightCorner.Y - totalHeight;
- }
-
- irr::video::SColor previous_color(255, 255, 255, 255);
- for (u32 i=0; i<BrokenText.size(); ++i)
- {
- if (HAlign == EGUIA_LOWERRIGHT)
- {
- r.UpperLeftCorner.X = frameRect.LowerRightCorner.X -
- font->getDimension(BrokenText[i].c_str()).Width;
- }
-
- std::vector<irr::video::SColor> colors;
- std::wstring str;
-
- str = colorizeText(BrokenText[i].c_str(), colors, previous_color);
- if (!colors.empty())
- previous_color = colors[colors.size() - 1];
-
- irr::gui::CGUITTFont *tmp = static_cast<irr::gui::CGUITTFont*>(font);
- tmp->draw(str.c_str(), r,
- colors,
- HAlign == EGUIA_CENTER, false, (RestrainTextInside ? &AbsoluteClippingRect : NULL));
-
- r.LowerRightCorner.Y += height;
- r.UpperLeftCorner.Y += height;
- }
- }
- }
- }
-
- IGUIElement::draw();
-}
-
-
-//! Sets another skin independent font.
-void StaticText::setOverrideFont(IGUIFont* font)
-{
- if (OverrideFont == font)
- return;
-
- if (OverrideFont)
- OverrideFont->drop();
-
- OverrideFont = font;
-
- if (OverrideFont)
- OverrideFont->grab();
-
- breakText();
-}
-
-//! Gets the override font (if any)
-IGUIFont * StaticText::getOverrideFont() const
-{
- return OverrideFont;
-}
-
-//! Get the font which is used right now for drawing
-IGUIFont* StaticText::getActiveFont() const
-{
- if ( OverrideFont )
- return OverrideFont;
- IGUISkin* skin = Environment->getSkin();
- if (skin)
- return skin->getFont();
- return 0;
-}
-
-//! Sets another color for the text.
-void StaticText::setOverrideColor(video::SColor color)
-{
- OverrideColor = color;
- OverrideColorEnabled = true;
-}
-
-
-//! Sets another color for the text.
-void StaticText::setBackgroundColor(video::SColor color)
-{
- BGColor = color;
- OverrideBGColorEnabled = true;
- Background = true;
-}
-
-
-//! Sets whether to draw the background
-void StaticText::setDrawBackground(bool draw)
-{
- Background = draw;
-}
-
-
-//! Gets the background color
-video::SColor StaticText::getBackgroundColor() const
-{
- return BGColor;
-}
-
-
-//! Checks if background drawing is enabled
-bool StaticText::isDrawBackgroundEnabled() const
-{
- _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
- return Background;
-}
-
-
-//! Sets whether to draw the border
-void StaticText::setDrawBorder(bool draw)
-{
- Border = draw;
-}
-
-
-//! Checks if border drawing is enabled
-bool StaticText::isDrawBorderEnabled() const
-{
- _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
- return Border;
-}
-
-
-void StaticText::setTextRestrainedInside(bool restrainTextInside)
-{
- RestrainTextInside = restrainTextInside;
-}
-
-
-bool StaticText::isTextRestrainedInside() const
-{
- return RestrainTextInside;
-}
-
-
-void StaticText::setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical)
-{
- HAlign = horizontal;
- VAlign = vertical;
-}
-
-
-#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR <= 7
-const video::SColor& StaticText::getOverrideColor() const
-#else
-video::SColor StaticText::getOverrideColor() const
-#endif
-{
- return OverrideColor;
-}
-
-
-//! Sets if the static text should use the overide color or the
-//! color in the gui skin.
-void StaticText::enableOverrideColor(bool enable)
-{
- OverrideColorEnabled = enable;
-}
-
-
-bool StaticText::isOverrideColorEnabled() const
-{
- _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
- return OverrideColorEnabled;
-}
-
-
-//! Enables or disables word wrap for using the static text as
-//! multiline text control.
-void StaticText::setWordWrap(bool enable)
-{
- WordWrap = enable;
- breakText();
-}
-
-
-bool StaticText::isWordWrapEnabled() const
-{
- _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
- return WordWrap;
-}
-
-
-void StaticText::setRightToLeft(bool rtl)
-{
- if (RightToLeft != rtl)
- {
- RightToLeft = rtl;
- breakText();
- }
-}
-
-
-bool StaticText::isRightToLeft() const
-{
- return RightToLeft;
-}
-
-
-//! Breaks the single text line.
-void StaticText::breakText()
-{
- if (!WordWrap)
- return;
-
- BrokenText.clear();
-
- IGUISkin* skin = Environment->getSkin();
- IGUIFont* font = getActiveFont();
- if (!font)
- return;
-
- LastBreakFont = font;
-
- core::stringw line;
- core::stringw word;
- core::stringw whitespace;
- s32 size = Text.size();
- s32 length = 0;
- s32 elWidth = RelativeRect.getWidth();
- if (Border)
- elWidth -= 2*skin->getSize(EGDS_TEXT_DISTANCE_X);
- wchar_t c;
-
- std::vector<irr::video::SColor> colors;
-
- // We have to deal with right-to-left and left-to-right differently
- // However, most parts of the following code is the same, it's just
- // some order and boundaries which change.
- if (!RightToLeft)
- {
- // regular (left-to-right)
- for (s32 i=0; i<size; ++i)
- {
- c = Text[i];
- bool lineBreak = false;
-
- if (c == L'\r') // Mac or Windows breaks
- {
- lineBreak = true;
- if (Text[i+1] == L'\n') // Windows breaks
- {
- Text.erase(i+1);
- --size;
- }
- c = '\0';
- }
- else if (c == L'\n') // Unix breaks
- {
- lineBreak = true;
- c = '\0';
- }
-
- bool isWhitespace = (c == L' ' || c == 0);
- if ( !isWhitespace )
- {
- // part of a word
- word += c;
- }
-
- if ( isWhitespace || i == (size-1))
- {
- if (word.size())
- {
- // here comes the next whitespace, look if
- // we must break the last word to the next line.
- const s32 whitelgth = font->getDimension(whitespace.c_str()).Width;
- const std::wstring sanitized = removeEscapes(word.c_str());
- const s32 wordlgth = font->getDimension(sanitized.c_str()).Width;
-
- if (wordlgth > elWidth)
- {
- // This word is too long to fit in the available space, look for
- // the Unicode Soft HYphen (SHY / 00AD) character for a place to
- // break the word at
- int where = word.findFirst( wchar_t(0x00AD) );
- if (where != -1)
- {
- core::stringw first = word.subString(0, where);
- core::stringw second = word.subString(where, word.size() - where);
- BrokenText.push_back(line + first + L"-");
- const s32 secondLength = font->getDimension(second.c_str()).Width;
-
- length = secondLength;
- line = second;
- }
- else
- {
- // No soft hyphen found, so there's nothing more we can do
- // break to next line
- if (length)
- BrokenText.push_back(line);
- length = wordlgth;
- line = word;
- }
- }
- else if (length && (length + wordlgth + whitelgth > elWidth))
- {
- // break to next line
- BrokenText.push_back(line);
- length = wordlgth;
- line = word;
- }
- else
- {
- // add word to line
- line += whitespace;
- line += word;
- length += whitelgth + wordlgth;
- }
-
- word = L"";
- whitespace = L"";
- }
-
- if ( isWhitespace )
- {
- whitespace += c;
- }
-
- // compute line break
- if (lineBreak)
- {
- line += whitespace;
- line += word;
- BrokenText.push_back(line);
- line = L"";
- word = L"";
- whitespace = L"";
- length = 0;
- }
- }
- }
-
- line += whitespace;
- line += word;
- BrokenText.push_back(line);
- }
- else
- {
- // right-to-left
- for (s32 i=size; i>=0; --i)
- {
- c = Text[i];
- bool lineBreak = false;
-
- if (c == L'\r') // Mac or Windows breaks
- {
- lineBreak = true;
- if ((i>0) && Text[i-1] == L'\n') // Windows breaks
- {
- Text.erase(i-1);
- --size;
- }
- c = '\0';
- }
- else if (c == L'\n') // Unix breaks
- {
- lineBreak = true;
- c = '\0';
- }
-
- if (c==L' ' || c==0 || i==0)
- {
- if (word.size())
- {
- // here comes the next whitespace, look if
- // we must break the last word to the next line.
- const s32 whitelgth = font->getDimension(whitespace.c_str()).Width;
- const s32 wordlgth = font->getDimension(word.c_str()).Width;
-
- if (length && (length + wordlgth + whitelgth > elWidth))
- {
- // break to next line
- BrokenText.push_back(line);
- length = wordlgth;
- line = word;
- }
- else
- {
- // add word to line
- line = whitespace + line;
- line = word + line;
- length += whitelgth + wordlgth;
- }
-
- word = L"";
- whitespace = L"";
- }
-
- if (c != 0)
- whitespace = core::stringw(&c, 1) + whitespace;
-
- // compute line break
- if (lineBreak)
- {
- line = whitespace + line;
- line = word + line;
- BrokenText.push_back(line);
- line = L"";
- word = L"";
- whitespace = L"";
- length = 0;
- }
- }
- else
- {
- // yippee this is a word..
- word = core::stringw(&c, 1) + word;
- }
- }
-
- line = whitespace + line;
- line = word + line;
- BrokenText.push_back(line);
- }
-}
-
-
-//! Sets the new caption of this element.
-void StaticText::setText(const wchar_t* text)
-{
- IGUIElement::setText(text);
- breakText();
-}
-
-
-void StaticText::updateAbsolutePosition()
-{
- IGUIElement::updateAbsolutePosition();
- breakText();
-}
-
-
-//! Returns the height of the text in pixels when it is drawn.
-s32 StaticText::getTextHeight() const
-{
- IGUIFont* font = getActiveFont();
- if (!font)
- return 0;
-
- s32 height = font->getDimension(L"A").Height + font->getKerningHeight();
-
- if (WordWrap)
- height *= BrokenText.size();
-
- return height;
-}
-
-
-s32 StaticText::getTextWidth() const
-{
- IGUIFont * font = getActiveFont();
- if(!font)
- return 0;
-
- if(WordWrap)
- {
- s32 widest = 0;
-
- for(u32 line = 0; line < BrokenText.size(); ++line)
- {
- s32 width = font->getDimension(BrokenText[line].c_str()).Width;
-
- if(width > widest)
- widest = width;
- }
-
- return widest;
- }
- else
- {
- return font->getDimension(Text.c_str()).Width;
- }
-}
-
-
-//! Writes attributes of the element.
-//! Implement this to expose the attributes of your element for
-//! scripting languages, editors, debuggers or xml serialization purposes.
-void StaticText::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const
-{
- IGUIStaticText::serializeAttributes(out,options);
-
- out->addBool ("Border", Border);
- out->addBool ("OverrideColorEnabled",OverrideColorEnabled);
- out->addBool ("OverrideBGColorEnabled",OverrideBGColorEnabled);
- out->addBool ("WordWrap", WordWrap);
- out->addBool ("Background", Background);
- out->addBool ("RightToLeft", RightToLeft);
- out->addBool ("RestrainTextInside", RestrainTextInside);
- out->addColor ("OverrideColor", OverrideColor);
- out->addColor ("BGColor", BGColor);
- out->addEnum ("HTextAlign", HAlign, GUIAlignmentNames);
- out->addEnum ("VTextAlign", VAlign, GUIAlignmentNames);
-
- // out->addFont ("OverrideFont", OverrideFont);
-}
-
-
-//! Reads attributes of the element
-void StaticText::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)
-{
- IGUIStaticText::deserializeAttributes(in,options);
-
- Border = in->getAttributeAsBool("Border");
- enableOverrideColor(in->getAttributeAsBool("OverrideColorEnabled"));
- OverrideBGColorEnabled = in->getAttributeAsBool("OverrideBGColorEnabled");
- setWordWrap(in->getAttributeAsBool("WordWrap"));
- Background = in->getAttributeAsBool("Background");
- RightToLeft = in->getAttributeAsBool("RightToLeft");
- RestrainTextInside = in->getAttributeAsBool("RestrainTextInside");
- OverrideColor = in->getAttributeAsColor("OverrideColor");
- BGColor = in->getAttributeAsColor("BGColor");
-
- setTextAlignment( (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("HTextAlign", GUIAlignmentNames),
- (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("VTextAlign", GUIAlignmentNames));
-
- // OverrideFont = in->getAttributeAsFont("OverrideFont");
-}
-
-} // end namespace gui
-} // end namespace irr
-
-
-#endif // _IRR_COMPILE_WITH_GUI_
diff --git a/src/util/statictext.h b/src/util/statictext.h
deleted file mode 100644
index 8d2f879e7..000000000
--- a/src/util/statictext.h
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright (C) 2002-2012 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine".
-// For conditions of distribution and use, see copyright notice in irrlicht.h
-
-#ifndef __C_GUI_STATIC_TEXT_H_INCLUDED__
-#define __C_GUI_STATIC_TEXT_H_INCLUDED__
-
-#include "IrrCompileConfig.h"
-#ifdef _IRR_COMPILE_WITH_GUI_
-
-#include "IGUIStaticText.h"
-#include "irrArray.h"
-
-#include <vector>
-
-namespace irr
-{
-namespace gui
-{
- class StaticText : public IGUIStaticText
- {
- public:
-
- //! constructor
- StaticText(const wchar_t* text, bool border, IGUIEnvironment* environment,
- IGUIElement* parent, s32 id, const core::rect<s32>& rectangle,
- bool background = false);
-
- //! destructor
- virtual ~StaticText();
-
- //! draws the element and its children
- virtual void draw();
-
- //! Sets another skin independent font.
- virtual void setOverrideFont(IGUIFont* font=0);
-
- //! Gets the override font (if any)
- virtual IGUIFont* getOverrideFont() const;
-
- //! Get the font which is used right now for drawing
- virtual IGUIFont* getActiveFont() const;
-
- //! Sets another color for the text.
- virtual void setOverrideColor(video::SColor color);
-
- //! Sets another color for the background.
- virtual void setBackgroundColor(video::SColor color);
-
- //! Sets whether to draw the background
- virtual void setDrawBackground(bool draw);
-
- //! Gets the background color
- virtual video::SColor getBackgroundColor() const;
-
- //! Checks if background drawing is enabled
- virtual bool isDrawBackgroundEnabled() const;
-
- //! Sets whether to draw the border
- virtual void setDrawBorder(bool draw);
-
- //! Checks if border drawing is enabled
- virtual bool isDrawBorderEnabled() const;
-
- //! Sets alignment mode for text
- virtual void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical);
-
- //! Gets the override color
- #if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR <= 7
- virtual const video::SColor& getOverrideColor() const;
- #else
- virtual video::SColor getOverrideColor() const;
- #endif
-
- //! Sets if the static text should use the overide color or the
- //! color in the gui skin.
- virtual void enableOverrideColor(bool enable);
-
- //! Checks if an override color is enabled
- virtual bool isOverrideColorEnabled() const;
-
- //! Set whether the text in this label should be clipped if it goes outside bounds
- virtual void setTextRestrainedInside(bool restrainedInside);
-
- //! Checks if the text in this label should be clipped if it goes outside bounds
- virtual bool isTextRestrainedInside() const;
-
- //! Enables or disables word wrap for using the static text as
- //! multiline text control.
- virtual void setWordWrap(bool enable);
-
- //! Checks if word wrap is enabled
- virtual bool isWordWrapEnabled() const;
-
- //! Sets the new caption of this element.
- virtual void setText(const wchar_t* text);
-
- //! Returns the height of the text in pixels when it is drawn.
- virtual s32 getTextHeight() const;
-
- //! Returns the width of the current text, in the current font
- virtual s32 getTextWidth() const;
-
- //! Updates the absolute position, splits text if word wrap is enabled
- virtual void updateAbsolutePosition();
-
- //! Set whether the string should be interpreted as right-to-left (RTL) text
- /** \note This component does not implement the Unicode bidi standard, the
- text of the component should be already RTL if you call this. The
- main difference when RTL is enabled is that the linebreaks for multiline
- elements are performed starting from the end.
- */
- virtual void setRightToLeft(bool rtl);
-
- //! Checks if the text should be interpreted as right-to-left text
- virtual bool isRightToLeft() const;
-
- //! Writes attributes of the element.
- virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const;
-
- //! Reads attributes of the element
- virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options);
-
- private:
-
- //! Breaks the single text line.
- void breakText();
-
- EGUI_ALIGNMENT HAlign, VAlign;
- bool Border;
- bool OverrideColorEnabled;
- bool OverrideBGColorEnabled;
- bool WordWrap;
- bool Background;
- bool RestrainTextInside;
- bool RightToLeft;
-
- video::SColor OverrideColor, BGColor;
- gui::IGUIFont* OverrideFont;
- gui::IGUIFont* LastBreakFont; // stored because: if skin changes, line break must be recalculated.
-
- core::array< core::stringw > BrokenText;
- };
-
-} // end namespace gui
-} // end namespace irr
-
-#endif // _IRR_COMPILE_WITH_GUI_
-
-#endif // C_GUI_STATIC_TEXT_H_INCLUDED
diff --git a/src/util/string.h b/src/util/string.h
index 40ef3e4d3..c77c5a6f9 100644
--- a/src/util/string.h
+++ b/src/util/string.h
@@ -519,6 +519,38 @@ std::basic_string<T> unescape_enriched(const std::basic_string<T> &s)
return output;
}
+template <typename T>
+std::vector<std::basic_string<T> > split(const std::basic_string<T> &s, T delim)
+{
+ std::vector<std::basic_string<T> > tokens;
+
+ std::basic_string<T> current;
+ bool last_was_escape = false;
+ for (size_t i = 0; i < s.length(); i++) {
+ T si = s[i];
+ if (last_was_escape) {
+ current += '\\';
+ current += si;
+ last_was_escape = false;
+ } else {
+ if (si == delim) {
+ tokens.push_back(current);
+ current = std::basic_string<T>();
+ last_was_escape = false;
+ } else if (si == '\\') {
+ last_was_escape = true;
+ } else {
+ current += si;
+ last_was_escape = false;
+ }
+ }
+ }
+ //push last element
+ tokens.push_back(current);
+
+ return tokens;
+}
+
/**
* Checks that all characters in \p to_check are a decimal digits.
*