From ae4324032a48ee08a808354673f47536e76759d0 Mon Sep 17 00:00:00 2001
From: Andrey Sukharev <SukharevAndrey@users.noreply.github.com>
Date: Thu, 19 Jan 2023 01:25:16 +0300
Subject: Optimize string memory usage. Use Spans and StringBuilders where
 possible (#3933)

* Optimize string memory usage. Use ReadOnlySpan<char> and StringBuilder where possible.

* Fix copypaste error

* Code generator review fixes

* Use if statement instead of switch

* Code style fixes

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Another code style fix

* Styling fix

Co-authored-by: Mary-nyan <thog@protonmail.com>

* Styling fix

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
Co-authored-by: Mary-nyan <thog@protonmail.com>
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
---
 .../SoftwareKeyboardRendererBase.cs                | 39 +++++++++++++++-------
 1 file changed, 27 insertions(+), 12 deletions(-)

(limited to 'Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs')

diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs
index 8216a65e..71835e2d 100644
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs
+++ b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs
@@ -292,20 +292,35 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
 
             _logoPosition = new Point(logoPositionX, logoPositionY);
         }
-
-        private RectangleF MeasureString(string text, Font font)
+        private static RectangleF MeasureString(string text, Font font)
         {
             RendererOptions options = new RendererOptions(font);
-            FontRectangle rectangle = TextMeasurer.Measure(text == "" ? " " : text, options);
 
             if (text == "")
             {
-                return new RectangleF(0, rectangle.Y, 0, rectangle.Height);
+                FontRectangle emptyRectangle = TextMeasurer.Measure(" ", options);
+
+                return new RectangleF(0, emptyRectangle.Y, 0, emptyRectangle.Height);
             }
-            else
+
+            FontRectangle rectangle = TextMeasurer.Measure(text, options);
+
+            return new RectangleF(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
+        }
+
+        private static RectangleF MeasureString(ReadOnlySpan<char> text, Font font)
+        {
+            RendererOptions options = new RendererOptions(font);
+            
+            if (text == "")
             {
-                return new RectangleF(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
+                FontRectangle emptyRectangle = TextMeasurer.Measure(" ", options);
+                return new RectangleF(0, emptyRectangle.Y, 0, emptyRectangle.Height);
             }
+
+            FontRectangle rectangle = TextMeasurer.Measure(text, options);
+
+            return new RectangleF(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
         }
 
         private void DrawTextBox(IImageProcessingContext context, SoftwareKeyboardUiState state)
@@ -354,8 +369,8 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
                 cursorBrush     = _selectionBoxBrush;
                 cursorPen       = _selectionBoxPen;
 
-                string textUntilBegin = state.InputText.Substring(0, state.CursorBegin);
-                string textUntilEnd   = state.InputText.Substring(0, state.CursorEnd);
+                ReadOnlySpan<char> textUntilBegin = state.InputText.AsSpan(0, state.CursorBegin);
+                ReadOnlySpan<char> textUntilEnd   = state.InputText.AsSpan(0, state.CursorEnd);
 
                 var selectionBeginRectangle = MeasureString(textUntilBegin, _inputTextFont);
                 var selectionEndRectangle   = MeasureString(textUntilEnd  , _inputTextFont);
@@ -374,9 +389,9 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
                 {
                     // Show the blinking cursor.
 
-                    int    cursorBegin         = Math.Min(state.InputText.Length, state.CursorBegin);
-                    string textUntilCursor     = state.InputText.Substring(0, cursorBegin);
-                    var    cursorTextRectangle = MeasureString(textUntilCursor, _inputTextFont);
+                    int                cursorBegin         = Math.Min(state.InputText.Length, state.CursorBegin);
+                    ReadOnlySpan<char> textUntilCursor     = state.InputText.AsSpan(0, cursorBegin);
+                    var                cursorTextRectangle = MeasureString(textUntilCursor, _inputTextFont);
 
                     cursorVisible       = true;
                     cursorPositionXLeft = inputTextX + cursorTextRectangle.Width + cursorTextRectangle.X;
@@ -387,7 +402,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
 
                         if (state.CursorBegin < state.InputText.Length)
                         {
-                            textUntilCursor      = state.InputText.Substring(0, cursorBegin + 1);
+                            textUntilCursor      = state.InputText.AsSpan(0, cursorBegin + 1);
                             cursorTextRectangle  = MeasureString(textUntilCursor, _inputTextFont);
                             cursorPositionXRight = inputTextX + cursorTextRectangle.Width + cursorTextRectangle.X;
                         }
-- 
cgit v1.2.3-70-g09d2