Browse Source

Begin conversion to UTF8

Michael Ragazzon 6 years ago
parent
commit
f9975a0e8e

+ 4 - 4
Include/RmlUi/Core/ElementText.h

@@ -51,10 +51,10 @@ public:
 	/// Sets the raw string this text element contains. The actual rendered text may be different due to whitespace
 	/// Sets the raw string this text element contains. The actual rendered text may be different due to whitespace
 	/// formatting.
 	/// formatting.
 	/// @param[in] text The new string to set on this element.
 	/// @param[in] text The new string to set on this element.
-	virtual void SetText(const WString& text) = 0;
+	virtual void SetText(const String& text) = 0;
 	/// Returns the raw string this text element contains.
 	/// Returns the raw string this text element contains.
 	/// @return This element's raw text.
 	/// @return This element's raw text.
-	virtual const WString& GetText() const = 0;
+	virtual const String& GetText() const = 0;
 
 
 	/// Generates a token of text from this element, returning only the width.
 	/// Generates a token of text from this element, returning only the width.
 	/// @param[out] token_width The window (in pixels) of the token.
 	/// @param[out] token_width The window (in pixels) of the token.
@@ -70,14 +70,14 @@ public:
 	/// @param[in] right_spacing_width The width (in pixels) of the spacing (consisting of margins, padding, etc) that must be remaining on the right of the line if the last of the text is rendered onto this line.
 	/// @param[in] right_spacing_width The width (in pixels) of the spacing (consisting of margins, padding, etc) that must be remaining on the right of the line if the last of the text is rendered onto this line.
 	/// @param[in] trim_whitespace_prefix If we're collapsing whitespace, whether or not to remove all prefixing whitespace or collapse it down to a single space.
 	/// @param[in] trim_whitespace_prefix If we're collapsing whitespace, whether or not to remove all prefixing whitespace or collapse it down to a single space.
 	/// @return True if the line reached the end of the element's text, false if not.
 	/// @return True if the line reached the end of the element's text, false if not.
-	virtual bool GenerateLine(WString& line, int& line_length, float& line_width, int line_begin, float maximum_line_width, float right_spacing_width, bool trim_whitespace_prefix) = 0;
+	virtual bool GenerateLine(String& line, int& line_length, float& line_width, int line_begin, float maximum_line_width, float right_spacing_width, bool trim_whitespace_prefix) = 0;
 
 
 	/// Clears all lines of generated text and prepares the element for generating new lines.
 	/// Clears all lines of generated text and prepares the element for generating new lines.
 	virtual void ClearLines() = 0;
 	virtual void ClearLines() = 0;
 	/// Adds a new line into the text element.
 	/// Adds a new line into the text element.
 	/// @param[in] line_position The position of this line, as an offset from the first line.
 	/// @param[in] line_position The position of this line, as an offset from the first line.
 	/// @param[in] line The contents of the line.
 	/// @param[in] line The contents of the line.
-	virtual void AddLine(const Vector2f& line_position, const WString& line) = 0;
+	virtual void AddLine(const Vector2f& line_position, const String& line) = 0;
 
 
 	/// Prevents the element from dirtying its document's layout when its text is changed.
 	/// Prevents the element from dirtying its document's layout when its text is changed.
 	virtual void SuppressAutoLayout() = 0;
 	virtual void SuppressAutoLayout() = 0;

+ 1 - 1
Include/RmlUi/Core/ElementUtilities.h

@@ -90,7 +90,7 @@ public:
 	/// @param[in] element The element to measure the string from.
 	/// @param[in] element The element to measure the string from.
 	/// @param[in] string The string to measure.
 	/// @param[in] string The string to measure.
 	/// @return The string width, in pixels.
 	/// @return The string width, in pixels.
-	static int GetStringWidth(Element* element, const WString& string);
+	static int GetStringWidth(Element* element, const String& string);
 
 
 	/// Bind and instance all event attributes on the given element onto the element
 	/// Bind and instance all event attributes on the given element onto the element
 	/// @param element Element to bind events on
 	/// @param element Element to bind events on

+ 7 - 0
Include/RmlUi/Core/StringUtilities.h

@@ -81,11 +81,18 @@ namespace StringUtilities
 	/// Reports a warning if the conversion fails.
 	/// Reports a warning if the conversion fails.
 	RMLUICORE_API WString ToUCS2(const String& str);
 	RMLUICORE_API WString ToUCS2(const String& str);
 
 
+	/// Convert UTF8 string to UTF16.
+	RMLUICORE_API WString ToUTF16(const String& str);
+
 	/// Converts a wide string in UCS-2 encoding into a string in UTF-8 encoding. This
 	/// Converts a wide string in UCS-2 encoding into a string in UTF-8 encoding. This
 	/// function assumes the endianness of the input words to be the same as the host processor.
 	/// function assumes the endianness of the input words to be the same as the host processor.
 	/// Reports a warning if the conversion fails.
 	/// Reports a warning if the conversion fails.
+	/// TODO: Convert from UTF-16 instead.
 	RMLUICORE_API String ToUTF8(const WString& wstr);
 	RMLUICORE_API String ToUTF8(const WString& wstr);
 
 
+	/// Returns number of characters in UTF8 string.
+	RMLUICORE_API int LengthUTF8(const String& str);
+
 	/// Converts upper-case characters in string to lower-case.
 	/// Converts upper-case characters in string to lower-case.
 	RMLUICORE_API String ToLower(const String& string);
 	RMLUICORE_API String ToLower(const String& string);
 
 

+ 2 - 2
Include/RmlUi/Core/SystemInterface.h

@@ -86,11 +86,11 @@ public:
 
 
 	/// Set clipboard text.
 	/// Set clipboard text.
 	/// @param[in] text Text to apply to clipboard.
 	/// @param[in] text Text to apply to clipboard.
-	virtual void SetClipboardText(const WString& text);
+	virtual void SetClipboardText(const String& text);
 
 
 	/// Get clipboard text.
 	/// Get clipboard text.
 	/// @param[out] text Retrieved text from clipboard.
 	/// @param[out] text Retrieved text from clipboard.
-	virtual void GetClipboardText(WString& text);
+	virtual void GetClipboardText(String& text);
 
 
 	/// Activate keyboard (for touchscreen devices)
 	/// Activate keyboard (for touchscreen devices)
 	virtual void ActivateKeyboard();
 	virtual void ActivateKeyboard();

+ 2 - 2
Samples/shell/include/Shell.h

@@ -80,10 +80,10 @@ public:
 	static void SetMouseCursor(const Rml::Core::String& cursor_name);
 	static void SetMouseCursor(const Rml::Core::String& cursor_name);
 
 
 	/// Set clipboard text.
 	/// Set clipboard text.
-	static void SetClipboardText(const Rml::Core::WString& text);
+	static void SetClipboardText(const Rml::Core::String& text);
 
 
 	/// Get clipboard text.
 	/// Get clipboard text.
-	static void GetClipboardText(Rml::Core::WString& text);
+	static void GetClipboardText(Rml::Core::String& text);
 	
 	
 	/// Sets the context to send window resized events to.
 	/// Sets the context to send window resized events to.
 	/// @param[in] context The context to send  events to.
 	/// @param[in] context The context to send  events to.

+ 2 - 2
Samples/shell/include/ShellSystemInterface.h

@@ -49,11 +49,11 @@ public:
 
 
 	/// Set clipboard text.
 	/// Set clipboard text.
 	/// @param[in] text Text to apply to clipboard.
 	/// @param[in] text Text to apply to clipboard.
-	void SetClipboardText(const Rml::Core::WString& text) override;
+	void SetClipboardText(const Rml::Core::String& text) override;
 
 
 	/// Get clipboard text.
 	/// Get clipboard text.
 	/// @param[out] text Retrieved text from clipboard.
 	/// @param[out] text Retrieved text from clipboard.
-	void GetClipboardText(Rml::Core::WString& text) override;
+	void GetClipboardText(Rml::Core::String& text) override;
 };
 };
 
 
 #endif
 #endif

+ 2 - 2
Samples/shell/src/ShellSystemInterface.cpp

@@ -40,12 +40,12 @@ void ShellSystemInterface::SetMouseCursor(const Rml::Core::String& cursor_name)
 	Shell::SetMouseCursor(cursor_name);
 	Shell::SetMouseCursor(cursor_name);
 }
 }
 
 
-void ShellSystemInterface::SetClipboardText(const Rml::Core::WString& text)
+void ShellSystemInterface::SetClipboardText(const Rml::Core::String& text)
 {
 {
 	Shell::SetClipboardText(text);
 	Shell::SetClipboardText(text);
 }
 }
 
 
-void ShellSystemInterface::GetClipboardText(Rml::Core::WString& text)
+void ShellSystemInterface::GetClipboardText(Rml::Core::String& text)
 {
 {
 	Shell::GetClipboardText(text);
 	Shell::GetClipboardText(text);
 }
 }

+ 5 - 3
Samples/shell/src/win32/ShellWin32.cpp

@@ -294,7 +294,7 @@ void Shell::SetMouseCursor(const Rml::Core::String& cursor_name)
 	}
 	}
 }
 }
 
 
-void Shell::SetClipboardText(const Rml::Core::WString& text)
+void Shell::SetClipboardText(const Rml::Core::String& text_utf8)
 {
 {
 	if (window_handle)
 	if (window_handle)
 	{
 	{
@@ -303,6 +303,8 @@ void Shell::SetClipboardText(const Rml::Core::WString& text)
 
 
 		EmptyClipboard();
 		EmptyClipboard();
 
 
+		const Rml::Core::WString text = Rml::Core::StringUtilities::ToUTF16(text_utf8);
+
 		size_t size = sizeof(wchar_t) * (text.size() + 1);
 		size_t size = sizeof(wchar_t) * (text.size() + 1);
 
 
 		HGLOBAL clipboard_data = GlobalAlloc(GMEM_FIXED, size);
 		HGLOBAL clipboard_data = GlobalAlloc(GMEM_FIXED, size);
@@ -318,7 +320,7 @@ void Shell::SetClipboardText(const Rml::Core::WString& text)
 	}
 	}
 }
 }
 
 
-void Shell::GetClipboardText(Rml::Core::WString& text)
+void Shell::GetClipboardText(Rml::Core::String& text)
 {
 {
 	if (window_handle)
 	if (window_handle)
 	{
 	{
@@ -334,7 +336,7 @@ void Shell::GetClipboardText(Rml::Core::WString& text)
 
 
 		const wchar_t* clipboard_text = (const wchar_t*)GlobalLock(clipboard_data);
 		const wchar_t* clipboard_text = (const wchar_t*)GlobalLock(clipboard_data);
 		if (clipboard_text)
 		if (clipboard_text)
-			text = clipboard_text;
+			text = Rml::Core::StringUtilities::ToUTF8(clipboard_text);
 		GlobalUnlock(clipboard_data);
 		GlobalUnlock(clipboard_data);
 
 
 		CloseClipboard();
 		CloseClipboard();

+ 1 - 1
Source/Controls/ElementFormControlTextArea.cpp

@@ -122,7 +122,7 @@ bool ElementFormControlTextArea::GetWordWrap()
 // Returns the control's inherent size, based on the length of the input field and the current font size.
 // Returns the control's inherent size, based on the length of the input field and the current font size.
 bool ElementFormControlTextArea::GetIntrinsicDimensions(Rml::Core::Vector2f& dimensions)
 bool ElementFormControlTextArea::GetIntrinsicDimensions(Rml::Core::Vector2f& dimensions)
 {
 {
-	dimensions.x = (float) (GetNumColumns() * Core::ElementUtilities::GetStringWidth(this, L"m"));
+	dimensions.x = (float) (GetNumColumns() * Core::ElementUtilities::GetStringWidth(this, "m"));
 	dimensions.y = (float)GetNumRows() * GetLineHeight();
 	dimensions.y = (float)GetNumRows() * GetLineHeight();
 
 
 	return true;
 	return true;

+ 1 - 1
Source/Controls/InputTypeText.cpp

@@ -114,7 +114,7 @@ void InputTypeText::ProcessDefaultAction(Core::Event& RMLUI_UNUSED_PARAMETER(eve
 // Sizes the dimensions to the element's inherent size.
 // Sizes the dimensions to the element's inherent size.
 bool InputTypeText::GetIntrinsicDimensions(Rml::Core::Vector2f& dimensions)
 bool InputTypeText::GetIntrinsicDimensions(Rml::Core::Vector2f& dimensions)
 {
 {
-	dimensions.x = (float) (size * Core::ElementUtilities::GetStringWidth(element, L"m"));
+	dimensions.x = (float) (size * Core::ElementUtilities::GetStringWidth(element, "m"));
 	dimensions.y = element->GetLineHeight() + 2.0f;
 	dimensions.y = element->GetLineHeight() + 2.0f;
 
 
 	return true;
 	return true;

+ 10 - 11
Source/Controls/WidgetTextInput.cpp

@@ -114,7 +114,7 @@ WidgetTextInput::~WidgetTextInput()
 // Sets the value of the text field.
 // Sets the value of the text field.
 void WidgetTextInput::SetValue(const Core::String& value)
 void WidgetTextInput::SetValue(const Core::String& value)
 {
 {
-	text_element->SetText(Core::StringUtilities::ToUCS2(value));
+	text_element->SetText(value);
 	FormatElement();
 	FormatElement();
 
 
 	UpdateRelativeCursor();
 	UpdateRelativeCursor();
@@ -352,13 +352,12 @@ void WidgetTextInput::ProcessEvent(Core::Event& event)
 		{
 		{
 			if (ctrl)
 			if (ctrl)
 			{
 			{
-				Core::WString clipboard_text;
+				Core::String clipboard_text;
 				Core::GetSystemInterface()->GetClipboardText(clipboard_text);
 				Core::GetSystemInterface()->GetClipboardText(clipboard_text);
 
 
 				for (size_t i = 0; i < clipboard_text.size(); ++i)
 				for (size_t i = 0; i < clipboard_text.size(); ++i)
 				{
 				{
-					if (max_length > 0 &&
-						(int)Core::StringUtilities::ToUCS2(GetElement()->GetAttribute< Rml::Core::String >("value", "")).size() > max_length)
+					if (max_length > 0 && Core::StringUtilities::LengthUTF8(GetElement()->GetAttribute< Rml::Core::String >("value", "")) > max_length)
 						break;
 						break;
 
 
 					AddCharacter(clipboard_text[i]);
 					AddCharacter(clipboard_text[i]);
@@ -510,7 +509,7 @@ bool WidgetTextInput::DeleteCharacter(bool back)
 void WidgetTextInput::CopySelection()
 void WidgetTextInput::CopySelection()
 {
 {
 	const Core::String& value = GetElement()->GetAttribute< Rml::Core::String >("value", "");
 	const Core::String& value = GetElement()->GetAttribute< Rml::Core::String >("value", "");
-	const Core::WString snippet = Core::StringUtilities::ToUCS2(value.substr(selection_begin_index, selection_length));
+	const Core::String snippet = value.substr(selection_begin_index, selection_length);
 	Core::GetSystemInterface()->SetClipboardText(snippet);
 	Core::GetSystemInterface()->SetClipboardText(snippet);
 }
 }
 
 
@@ -786,8 +785,8 @@ Rml::Core::Vector2f WidgetTextInput::FormatText()
 		{
 		{
 			soft_return = true;
 			soft_return = true;
 
 
-			const Core::WString& text = text_element->GetText();
-			Core::WString orphan;
+			const Core::String& text = text_element->GetText();
+			Core::String orphan;
 			for (int i = 1; i >= 0; --i)
 			for (int i = 1; i >= 0; --i)
 			{
 			{
 				int index = line_begin + line.content_length + i;
 				int index = line_begin + line.content_length + i;
@@ -819,7 +818,7 @@ Rml::Core::Vector2f WidgetTextInput::FormatText()
 		// Now that we have the string of characters appearing on the new line, we split it into
 		// Now that we have the string of characters appearing on the new line, we split it into
 		// three parts; the unselected text appearing before any selected text on the line, the
 		// three parts; the unselected text appearing before any selected text on the line, the
 		// selected text on the line, and any unselected text after the selection.
 		// selected text on the line, and any unselected text after the selection.
-		Core::WString pre_selection, selection, post_selection;
+		Core::String pre_selection, selection, post_selection;
 		GetLineSelection(pre_selection, selection, post_selection, line.content, line_begin);
 		GetLineSelection(pre_selection, selection, post_selection, line.content, line_begin);
 
 
 		// The pre-selected text is placed, if there is any (if the selection starts on or before
 		// The pre-selected text is placed, if there is any (if the selection starts on or before
@@ -958,9 +957,9 @@ void WidgetTextInput::DeleteSelection()
 {
 {
 	if (selection_length > 0)
 	if (selection_length > 0)
 	{
 	{
-		const Core::WString& value = Core::StringUtilities::ToUCS2( GetElement()->GetAttribute< Rml::Core::String >("value", "") );
+		const Core::String& value = GetElement()->GetAttribute< Rml::Core::String >("value", "");
 
 
-		Rml::Core::String new_value = Core::StringUtilities::ToUTF8(Core::WString(value.substr(0, selection_begin_index) + value.substr(selection_begin_index + selection_length)));
+		Rml::Core::String new_value = value.substr(0, selection_begin_index) + value.substr(selection_begin_index + selection_length);
 		GetElement()->SetAttribute("value", new_value);
 		GetElement()->SetAttribute("value", new_value);
 
 
 		// Move the cursor to the beginning of the old selection.
 		// Move the cursor to the beginning of the old selection.
@@ -973,7 +972,7 @@ void WidgetTextInput::DeleteSelection()
 }
 }
 
 
 // Split one line of text into three parts, based on the current selection.
 // Split one line of text into three parts, based on the current selection.
-void WidgetTextInput::GetLineSelection(Core::WString& pre_selection, Core::WString& selection, Core::WString& post_selection, const Core::WString& line, int line_begin)
+void WidgetTextInput::GetLineSelection(Core::String& pre_selection, Core::String& selection, Core::String& post_selection, const Core::String& line, int line_begin)
 {
 {
 	// Check if we have any selection at all, and if so if the selection is on this line.
 	// Check if we have any selection at all, and if so if the selection is on this line.
 	if (selection_length <= 0 ||
 	if (selection_length <= 0 ||

+ 2 - 2
Source/Controls/WidgetTextInput.h

@@ -170,12 +170,12 @@ private:
 	/// @param[out] post_selection The section of unselected text after any selected text on the line. If there is no selection on the line, then this will be empty.
 	/// @param[out] post_selection The section of unselected text after any selected text on the line. If there is no selection on the line, then this will be empty.
 	/// @param[in] line The text making up the line.
 	/// @param[in] line The text making up the line.
 	/// @param[in] line_begin The absolute index at the beginning of the line.
 	/// @param[in] line_begin The absolute index at the beginning of the line.
-	void GetLineSelection(Core::WString& pre_selection, Core::WString& selection, Core::WString& post_selection, const Core::WString& line, int line_begin);
+	void GetLineSelection(Core::String& pre_selection, Core::String& selection, Core::String& post_selection, const Core::String& line, int line_begin);
 
 
 	struct Line
 	struct Line
 	{
 	{
 		// The contents of the line (including the trailing endline, if that terminated the line).
 		// The contents of the line (including the trailing endline, if that terminated the line).
-		Core::WString content;
+		Core::String content;
 		// The length of the editable characters on the line (excluding any trailing endline).
 		// The length of the editable characters on the line (excluding any trailing endline).
 		int content_length;
 		int content_length;
 
 

+ 1 - 1
Source/Core/ElementDocument.cpp

@@ -328,7 +328,7 @@ ElementPtr ElementDocument::CreateTextNode(const String& text)
 	}
 	}
 	
 	
 	// Set the text
 	// Set the text
-	element_text->SetText(StringUtilities::ToUCS2(text));
+	element_text->SetText(text);
 
 
 	return element;
 	return element;
 }
 }

+ 26 - 26
Source/Core/ElementTextDefault.cpp

@@ -40,8 +40,8 @@
 namespace Rml {
 namespace Rml {
 namespace Core {
 namespace Core {
 
 
-static bool BuildToken(WString& token, const word*& token_begin, const word* string_end, bool first_token, bool collapse_white_space, bool break_at_endline, Style::TextTransform text_transformation);
-static bool LastToken(const word* token_begin, const word* string_end, bool collapse_white_space, bool break_at_endline);
+static bool BuildToken(String& token, const char*& token_begin, const char* string_end, bool first_token, bool collapse_white_space, bool break_at_endline, Style::TextTransform text_transformation);
+static bool LastToken(const char* token_begin, const char* string_end, bool collapse_white_space, bool break_at_endline);
 
 
 ElementTextDefault::ElementTextDefault(const String& tag) : ElementText(tag), colour(255, 255, 255), decoration(this)
 ElementTextDefault::ElementTextDefault(const String& tag) : ElementText(tag), colour(255, 255, 255), decoration(this)
 {
 {
@@ -60,7 +60,7 @@ ElementTextDefault::~ElementTextDefault()
 {
 {
 }
 }
 
 
-void ElementTextDefault::SetText(const WString& _text)
+void ElementTextDefault::SetText(const String& _text)
 {
 {
 	if (text != _text)
 	if (text != _text)
 	{
 	{
@@ -71,7 +71,7 @@ void ElementTextDefault::SetText(const WString& _text)
 	}
 	}
 }
 }
 
 
-const WString& ElementTextDefault::GetText() const
+const String& ElementTextDefault::GetText() const
 {
 {
 	return text;
 	return text;
 }
 }
@@ -165,8 +165,8 @@ bool ElementTextDefault::GenerateToken(float& token_width, int line_begin)
 							white_space_property == WhiteSpace::Prewrap ||
 							white_space_property == WhiteSpace::Prewrap ||
 							white_space_property == WhiteSpace::Preline;
 							white_space_property == WhiteSpace::Preline;
 
 
-	const word* token_begin = text.c_str() + line_begin;
-	WString token;
+	const char* token_begin = text.c_str() + line_begin;
+	String token;
 
 
 	BuildToken(token, token_begin, text.c_str() + text.size(), true, collapse_white_space, break_at_endline, computed.text_transform);
 	BuildToken(token, token_begin, text.c_str() + text.size(), true, collapse_white_space, break_at_endline, computed.text_transform);
 	token_width = (float) font_face_handle->GetStringWidth(token, 0);
 	token_width = (float) font_face_handle->GetStringWidth(token, 0);
@@ -175,7 +175,7 @@ bool ElementTextDefault::GenerateToken(float& token_width, int line_begin)
 }
 }
 
 
 // Generates a line of text rendered from this element
 // Generates a line of text rendered from this element
-bool ElementTextDefault::GenerateLine(WString& line, int& line_length, float& line_width, int line_begin, float maximum_line_width, float right_spacing_width, bool trim_whitespace_prefix)
+bool ElementTextDefault::GenerateLine(String& line, int& line_length, float& line_width, int line_begin, float maximum_line_width, float right_spacing_width, bool trim_whitespace_prefix)
 {
 {
 	RMLUI_ZoneScoped;
 	RMLUI_ZoneScoped;
 
 
@@ -212,12 +212,12 @@ bool ElementTextDefault::GenerateLine(WString& line, int& line_length, float& li
 	// white-space parsing parameters. Each section is then appended to the line if it can fit. If not, or if an
 	// white-space parsing parameters. Each section is then appended to the line if it can fit. If not, or if an
 	// endline is found (and we're processing them), then the line is ended. kthxbai!
 	// endline is found (and we're processing them), then the line is ended. kthxbai!
 
 
-	const word* token_begin = text.c_str() + line_begin;
-	const word* string_end = text.c_str() + text.size();
+	const char* token_begin = text.c_str() + line_begin;
+	const char* string_end = text.c_str() + text.size();
 	while (token_begin != string_end)
 	while (token_begin != string_end)
 	{
 	{
-		WString token;
-		const word* next_token_begin = token_begin;
+		String token;
+		const char* next_token_begin = token_begin;
 
 
 		// Generate the next token and determine its pixel-length.
 		// Generate the next token and determine its pixel-length.
 		bool break_line = BuildToken(token, next_token_begin, string_end, line.empty() && trim_whitespace_prefix, collapse_white_space, break_at_endline, text_transform_property);
 		bool break_line = BuildToken(token, next_token_begin, string_end, line.empty() && trim_whitespace_prefix, collapse_white_space, break_at_endline, text_transform_property);
@@ -263,7 +263,7 @@ void ElementTextDefault::ClearLines()
 }
 }
 
 
 // Adds a new line into the text element.
 // Adds a new line into the text element.
-void ElementTextDefault::AddLine(const Vector2f& line_position, const WString& line)
+void ElementTextDefault::AddLine(const Vector2f& line_position, const String& line)
 {
 {
 	FontFaceHandle* font_face_handle = GetFontFaceHandle();
 	FontFaceHandle* font_face_handle = GetFontFaceHandle();
 
 
@@ -363,7 +363,7 @@ void ElementTextDefault::OnPropertyChange(const PropertyIdSet& changed_propertie
 // Returns the RML of this element
 // Returns the RML of this element
 void ElementTextDefault::GetRML(String& content)
 void ElementTextDefault::GetRML(String& content)
 {
 {
-	content += StringUtilities::ToUTF8(text);
+	content += text;
 }
 }
 
 
 // Updates the configuration this element uses for its font.
 // Updates the configuration this element uses for its font.
@@ -429,7 +429,7 @@ void ElementTextDefault::GenerateDecoration(const FontFaceHandle* font_face_hand
 	font_face_handle->GenerateLine(&decoration, line.position, line.width, decoration_property, colour);
 	font_face_handle->GenerateLine(&decoration, line.position, line.width, decoration_property, colour);
 }
 }
 
 
-static bool BuildToken(WString& token, const word*& token_begin, const word* string_end, bool first_token, bool collapse_white_space, bool break_at_endline, Style::TextTransform text_transformation)
+static bool BuildToken(String& token, const char*& token_begin, const char* string_end, bool first_token, bool collapse_white_space, bool break_at_endline, Style::TextTransform text_transformation)
 {
 {
 	RMLUI_ASSERT(token_begin != string_end);
 	RMLUI_ASSERT(token_begin != string_end);
 
 
@@ -446,9 +446,9 @@ static bool BuildToken(WString& token, const word*& token_begin, const word* str
 	while (token_begin != string_end)
 	while (token_begin != string_end)
 	{
 	{
 		bool force_non_whitespace = false;
 		bool force_non_whitespace = false;
-		word character = *token_begin;
+		char character = *token_begin;
 
 
-		const word* escape_begin = token_begin;
+		const char* escape_begin = token_begin;
 
 
 		// Check for an ampersand; if we find one, we've got an HTML escaped character.
 		// Check for an ampersand; if we find one, we've got an HTML escaped character.
 		if (character == '&')
 		if (character == '&')
@@ -468,17 +468,17 @@ static bool BuildToken(WString& token, const word*& token_begin, const word* str
 			// is not recognised, print the token like normal text.
 			// is not recognised, print the token like normal text.
 			else
 			else
 			{
 			{
-				WString ucs2_escape_code(escape_begin + 1, token_begin);
+				String ucs2_escape_code(escape_begin + 1, token_begin);
 
 
-				if (ucs2_escape_code == L"lt")
+				if (ucs2_escape_code == "lt")
 					character = '<';
 					character = '<';
-				else if (ucs2_escape_code == L"gt")
+				else if (ucs2_escape_code == "gt")
 					character = '>';
 					character = '>';
-				else if (ucs2_escape_code == L"amp")
+				else if (ucs2_escape_code == "amp")
 					character = '&';
 					character = '&';
-				else if (ucs2_escape_code == L"quot")
+				else if (ucs2_escape_code == "quot")
 					character = '"';
 					character = '"';
-				else if (ucs2_escape_code == L"nbsp")
+				else if (ucs2_escape_code == "nbsp")
 				{
 				{
 					character = ' ';
 					character = ' ';
 					force_non_whitespace = true;
 					force_non_whitespace = true;
@@ -544,12 +544,12 @@ static bool BuildToken(WString& token, const word*& token_begin, const word* str
 			if (text_transformation == Style::TextTransform::Uppercase)
 			if (text_transformation == Style::TextTransform::Uppercase)
 			{
 			{
 				if (character >= 'a' && character <= 'z')
 				if (character >= 'a' && character <= 'z')
-					character += (Rml::Core::word)('A' - 'a');
+					character += ('A' - 'a');
 			}
 			}
 			else if (text_transformation == Style::TextTransform::Lowercase)
 			else if (text_transformation == Style::TextTransform::Lowercase)
 			{
 			{
 				if (character >= 'A' && character <= 'Z')
 				if (character >= 'A' && character <= 'Z')
-					character -= (Rml::Core::word)('A' - 'a');
+					character -= ('A' - 'a');
 			}
 			}
 
 
 			token += character;
 			token += character;
@@ -561,14 +561,14 @@ static bool BuildToken(WString& token, const word*& token_begin, const word* str
 	return false;
 	return false;
 }
 }
 
 
-static bool LastToken(const word* token_begin, const word* string_end, bool collapse_white_space, bool break_at_endline)
+static bool LastToken(const char* token_begin, const char* string_end, bool collapse_white_space, bool break_at_endline)
 {
 {
 	bool last_token = (token_begin == string_end);
 	bool last_token = (token_begin == string_end);
 	if (collapse_white_space &&
 	if (collapse_white_space &&
 		!last_token)
 		!last_token)
 	{
 	{
 		last_token = true;
 		last_token = true;
-		const word* character = token_begin;
+		const char* character = token_begin;
 
 
 		while (character != string_end)
 		while (character != string_end)
 		{
 		{

+ 7 - 7
Source/Core/ElementTextDefault.h

@@ -46,8 +46,8 @@ public:
 	ElementTextDefault(const String& tag);
 	ElementTextDefault(const String& tag);
 	virtual ~ElementTextDefault();
 	virtual ~ElementTextDefault();
 
 
-	void SetText(const WString& text) override;
-	const WString& GetText() const override;
+	void SetText(const String& text) override;
+	const String& GetText() const override;
 
 
 	void OnRender() override;
 	void OnRender() override;
 
 
@@ -65,14 +65,14 @@ public:
 	/// @param[in] right_spacing_width The width (in pixels) of the spacing (consisting of margins, padding, etc) that must be remaining on the right of the line if the last of the text is rendered onto this line.
 	/// @param[in] right_spacing_width The width (in pixels) of the spacing (consisting of margins, padding, etc) that must be remaining on the right of the line if the last of the text is rendered onto this line.
 	/// @param[in] trim_whitespace_prefix If we're collapsing whitespace, whether or remove all prefixing whitespace or collapse it down to a single space.
 	/// @param[in] trim_whitespace_prefix If we're collapsing whitespace, whether or remove all prefixing whitespace or collapse it down to a single space.
 	/// @return True if the line reached the end of the element's text, false if not.
 	/// @return True if the line reached the end of the element's text, false if not.
-	bool GenerateLine(WString& line, int& line_length, float& line_width, int line_begin, float maximum_line_width, float right_spacing_width, bool trim_whitespace_prefix) override;
+	bool GenerateLine(String& line, int& line_length, float& line_width, int line_begin, float maximum_line_width, float right_spacing_width, bool trim_whitespace_prefix) override;
 
 
 	/// Clears all lines of generated text and prepares the element for generating new lines.
 	/// Clears all lines of generated text and prepares the element for generating new lines.
 	void ClearLines() override;
 	void ClearLines() override;
 	/// Adds a new line into the text element.
 	/// Adds a new line into the text element.
 	/// @param[in] line_position The position of this line, as an offset from the first line.
 	/// @param[in] line_position The position of this line, as an offset from the first line.
 	/// @param[in] line The contents of the line..
 	/// @param[in] line The contents of the line..
-	void AddLine(const Vector2f& line_position, const WString& line) override;
+	void AddLine(const Vector2f& line_position, const String& line) override;
 
 
 	/// Prevents the element from dirtying its document's layout when its text is changed.
 	/// Prevents the element from dirtying its document's layout when its text is changed.
 	void SuppressAutoLayout() override;
 	void SuppressAutoLayout() override;
@@ -92,12 +92,12 @@ private:
 	// Used to store the position and length of each line we have geometry for.
 	// Used to store the position and length of each line we have geometry for.
 	struct Line
 	struct Line
 	{
 	{
-		Line(const WString& text, const Vector2f& position) : text(text), position(position)
+		Line(const String& text, const Vector2f& position) : text(text), position(position)
 		{
 		{
 			width = 0;
 			width = 0;
 		}
 		}
 
 
-		WString text;
+		String text;
 		Vector2f position;
 		Vector2f position;
 		int width;
 		int width;
 	};
 	};
@@ -109,7 +109,7 @@ private:
 	// Generates any geometry necessary for rendering a line decoration (underline, strike-through, etc).
 	// Generates any geometry necessary for rendering a line decoration (underline, strike-through, etc).
 	void GenerateDecoration(const FontFaceHandle* font_face_handle, const Line& line);
 	void GenerateDecoration(const FontFaceHandle* font_face_handle, const Line& line);
 
 
-	WString text;
+	String text;
 
 
 	typedef std::vector< Line > LineList;
 	typedef std::vector< Line > LineList;
 	LineList lines;
 	LineList lines;

+ 1 - 1
Source/Core/ElementUtilities.cpp

@@ -161,7 +161,7 @@ float ElementUtilities::GetDensityIndependentPixelRatio(Element * element)
 }
 }
 
 
 // Returns the width of a string rendered within the context of the given element.
 // Returns the width of a string rendered within the context of the given element.
-int ElementUtilities::GetStringWidth(Element* element, const WString& string)
+int ElementUtilities::GetStringWidth(Element* element, const String& string)
 {
 {
 	FontFaceHandle* font_face_handle = element->GetFontFaceHandle();
 	FontFaceHandle* font_face_handle = element->GetFontFaceHandle();
 	if (font_face_handle == nullptr)
 	if (font_face_handle == nullptr)

+ 1 - 1
Source/Core/Factory.cpp

@@ -293,7 +293,7 @@ bool Factory::InstanceElementText(Element* parent, const String& text)
 			return false;
 			return false;
 		}
 		}
 
 
-		text_element->SetText(StringUtilities::ToUCS2(translated_data));
+		text_element->SetText(translated_data);
 
 
 		// Add to active node.
 		// Add to active node.
 		parent->AppendChild(std::move(element));
 		parent->AppendChild(std::move(element));

+ 2 - 2
Source/Core/FontFaceHandle.cpp

@@ -96,7 +96,7 @@ const FontGlyphList& FontFaceHandle::GetGlyphs() const
 }
 }
 
 
 // Returns the width a string will take up if rendered with this handle.
 // Returns the width a string will take up if rendered with this handle.
-int FontFaceHandle::GetStringWidth(const WString& string, word prior_character) const
+int FontFaceHandle::GetStringWidth(const String& string, word prior_character) const
 {
 {
 	int width = 0;
 	int width = 0;
 
 
@@ -194,7 +194,7 @@ bool FontFaceHandle::GenerateLayerTexture(const byte*& texture_data, Vector2i& t
 }
 }
 
 
 // Generates the geometry required to render a single line of text.
 // Generates the geometry required to render a single line of text.
-int FontFaceHandle::GenerateString(GeometryList& geometry, const WString& string, const Vector2f& position, const Colourb& colour, int layer_configuration_index) const
+int FontFaceHandle::GenerateString(GeometryList& geometry, const String& string, const Vector2f& position, const Colourb& colour, int layer_configuration_index) const
 {
 {
 	int geometry_index = 0;
 	int geometry_index = 0;
 	int line_width = 0;
 	int line_width = 0;

+ 2 - 2
Source/Core/FontFaceHandle.h

@@ -77,7 +77,7 @@ public:
 	/// @param[in] string The string to measure.
 	/// @param[in] string The string to measure.
 	/// @param[in] prior_character The optionally-specified character that immediately precedes the string. This may have an impact on the string width due to kerning.
 	/// @param[in] prior_character The optionally-specified character that immediately precedes the string. This may have an impact on the string width due to kerning.
 	/// @return The width, in pixels, this string will occupy if rendered with this handle.
 	/// @return The width, in pixels, this string will occupy if rendered with this handle.
-	int GetStringWidth(const WString& string, word prior_character = 0) const;
+	int GetStringWidth(const String& string, word prior_character = 0) const;
 
 
 	/// Generates, if required, the layer configuration for a given array of font effects.
 	/// Generates, if required, the layer configuration for a given array of font effects.
 	/// @param[in] font_effects The list of font effects to generate the configuration for.
 	/// @param[in] font_effects The list of font effects to generate the configuration for.
@@ -96,7 +96,7 @@ public:
 	/// @param[in] position The position of the baseline of the first character to render.
 	/// @param[in] position The position of the baseline of the first character to render.
 	/// @param[in] colour The colour to render the text.
 	/// @param[in] colour The colour to render the text.
 	/// @return The width, in pixels, of the string geometry.
 	/// @return The width, in pixels, of the string geometry.
-	int GenerateString(GeometryList& geometry, const WString& string, const Vector2f& position, const Colourb& colour, int layer_configuration = 0) const;
+	int GenerateString(GeometryList& geometry, const String& string, const Vector2f& position, const Colourb& colour, int layer_configuration = 0) const;
 	/// Generates the geometry required to render a line above, below or through a line of text.
 	/// Generates the geometry required to render a line above, below or through a line of text.
 	/// @param[out] geometry The geometry to append the newly created geometry into.
 	/// @param[out] geometry The geometry to append the newly created geometry into.
 	/// @param[in] position The position of the baseline of the lined text.
 	/// @param[in] position The position of the baseline of the lined text.

+ 1 - 1
Source/Core/LayoutInlineBoxText.h

@@ -86,7 +86,7 @@ private:
 	// The index of the first character of this line.
 	// The index of the first character of this line.
 	int line_begin;
 	int line_begin;
 	// The contents on this line.
 	// The contents on this line.
-	WString line_contents;
+	String line_contents;
 
 
 	// True if this line can be segmented into parts, false if it consists of only a single word.
 	// True if this line can be segmented into parts, false if it consists of only a single word.
 	bool line_segmented;
 	bool line_segmented;

+ 2 - 2
Source/Core/Lua/ElementText.cpp

@@ -46,7 +46,7 @@ int ElementTextGetAttrtext(lua_State* L)
 {
 {
     ElementText* obj = LuaType<ElementText>::check(L, 1);
     ElementText* obj = LuaType<ElementText>::check(L, 1);
     LUACHECKOBJ(obj);
     LUACHECKOBJ(obj);
-    lua_pushstring(L, StringUtilities::ToUTF8(obj->GetText()).c_str());
+    lua_pushstring(L, obj->GetText().c_str());
     return 1;
     return 1;
 }
 }
 
 
@@ -55,7 +55,7 @@ int ElementTextSetAttrtext(lua_State* L)
     ElementText* obj = LuaType<ElementText>::check(L, 1);
     ElementText* obj = LuaType<ElementText>::check(L, 1);
     LUACHECKOBJ(obj);
     LUACHECKOBJ(obj);
     const char* text = luaL_checkstring(L,2);
     const char* text = luaL_checkstring(L,2);
-    obj->SetText(StringUtilities::ToUCS2(text));
+    obj->SetText(text);
     return 0;
     return 0;
 }
 }
 
 

+ 14 - 0
Source/Core/StringUtilities.cpp

@@ -1,3 +1,5 @@
+#include "..\..\Include\RmlUi\Core\StringUtilities.h"
+#include "..\..\Include\RmlUi\Core\StringUtilities.h"
 /*
 /*
  * This source file is part of RmlUi, the HTML/CSS Interface Middleware
  * This source file is part of RmlUi, the HTML/CSS Interface Middleware
  *
  *
@@ -99,6 +101,12 @@ WString StringUtilities::ToUCS2(const String& str)
 	return result;
 	return result;
 }
 }
 
 
+WString StringUtilities::ToUTF16(const String& str)
+{
+	// TODO: Convert to UTF16 instead of UCS2
+	return ToUCS2(str);
+}
+
 String StringUtilities::ToUTF8(const WString& wstr)
 String StringUtilities::ToUTF8(const WString& wstr)
 {
 {
 	String result;
 	String result;
@@ -107,6 +115,12 @@ String StringUtilities::ToUTF8(const WString& wstr)
 	return result;
 	return result;
 }
 }
 
 
+int StringUtilities::LengthUTF8(const String& str)
+{
+	// TODO: Actually consider multibyte characters
+	return (int)str.size();
+}
+
 String StringUtilities::Replace(String subject, const String& search, const String& replace)
 String StringUtilities::Replace(String subject, const String& search, const String& replace)
 {
 {
 	size_t pos = 0;
 	size_t pos = 0;

+ 1 - 1
Source/Core/StyleSheetParser.cpp

@@ -393,7 +393,7 @@ int StyleSheetParser::Parse(StyleSheetNode* node, Stream* _stream, const StyleSh
 					}
 					}
 					else if (at_rule_identifier == "decorator")
 					else if (at_rule_identifier == "decorator")
 					{
 					{
-						auto source = std::make_shared<PropertySource>(stream_file_name, line_number, pre_token_str);
+						auto source = std::make_shared<PropertySource>(stream_file_name, (int)line_number, pre_token_str);
 						ParseDecoratorBlock(at_rule_name, decorator_map, style_sheet, source);
 						ParseDecoratorBlock(at_rule_name, decorator_map, style_sheet, source);
 						
 						
 						at_rule_name.clear();
 						at_rule_name.clear();

+ 3 - 3
Source/Core/SystemInterface.cpp

@@ -37,7 +37,7 @@
 namespace Rml {
 namespace Rml {
 namespace Core {
 namespace Core {
 
 
-static WString clipboard_text;
+static String clipboard_text;
 
 
 SystemInterface::SystemInterface()
 SystemInterface::SystemInterface()
 {
 {
@@ -79,13 +79,13 @@ void SystemInterface::SetMouseCursor(const String& cursor_name)
 {
 {
 }
 }
 
 
-void SystemInterface::SetClipboardText(const WString& text)
+void SystemInterface::SetClipboardText(const String& text)
 {
 {
 	// The default implementation will only copy and paste within the application
 	// The default implementation will only copy and paste within the application
 	clipboard_text = text;
 	clipboard_text = text;
 }
 }
 
 
-void SystemInterface::GetClipboardText(WString& text)
+void SystemInterface::GetClipboardText(String& text)
 {
 {
 	text = clipboard_text;
 	text = clipboard_text;
 }
 }

+ 2 - 2
Source/Debugger/SystemInterface.cpp

@@ -70,12 +70,12 @@ void SystemInterface::SetMouseCursor(const Core::String& cursor_name)
 	application_interface->SetMouseCursor(cursor_name);
 	application_interface->SetMouseCursor(cursor_name);
 }
 }
 
 
-void SystemInterface::SetClipboardText(const Core::WString& text)
+void SystemInterface::SetClipboardText(const Core::String& text)
 {
 {
 	application_interface->SetClipboardText(text);
 	application_interface->SetClipboardText(text);
 }
 }
 
 
-void SystemInterface::GetClipboardText(Core::WString& text)
+void SystemInterface::GetClipboardText(Core::String& text)
 {
 {
 	application_interface->GetClipboardText(text);
 	application_interface->GetClipboardText(text);
 }
 }

+ 2 - 2
Source/Debugger/SystemInterface.h

@@ -73,11 +73,11 @@ public:
 
 
 	/// Set clipboard text.
 	/// Set clipboard text.
 	/// @param[in] text Text to apply to clipboard.
 	/// @param[in] text Text to apply to clipboard.
-	void SetClipboardText(const Core::WString& text) override;
+	void SetClipboardText(const Core::String& text) override;
 
 
 	/// Get clipboard text.
 	/// Get clipboard text.
 	/// @param[out] text Retrieved text from clipboard.
 	/// @param[out] text Retrieved text from clipboard.
-	void GetClipboardText(Core::WString& text) override;
+	void GetClipboardText(Core::String& text) override;
 
 
 	/// Activate keyboard (for touchscreen devices)
 	/// Activate keyboard (for touchscreen devices)
 	void ActivateKeyboard() override;
 	void ActivateKeyboard() override;