From d8b8e58656a65fac70a59f709c19a22982286c42 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 10 May 2015 07:17:21 +1000 Subject: [PATCH] Minimise DrawTextArgs allocations. --- 2D/DrawTextArgs.cs | 2 +- 2D/Screens/BlockSelectScreen.cs | 2 +- 2D/Screens/ChatScreen.cs | 4 +-- 2D/Screens/ErrorScreen.cs | 2 +- 2D/Utils2D.cs | 45 ++++++++++++++++++++++++++++--- 2D/Widgets/ExtPlayerListWidget.cs | 2 +- 2D/Widgets/PlayerListWidget.cs | 2 +- 2D/Widgets/TextGroupWidget.cs | 2 +- 2D/Widgets/TextInputWidget.cs | 4 +-- 2D/Widgets/TextWidget.cs | 2 +- Rendering/PlayerRenderer.cs | 2 +- Utils/Utils.cs | 36 ------------------------- 12 files changed, 53 insertions(+), 52 deletions(-) diff --git a/2D/DrawTextArgs.cs b/2D/DrawTextArgs.cs index 5ac901466..660e8204f 100644 --- a/2D/DrawTextArgs.cs +++ b/2D/DrawTextArgs.cs @@ -4,7 +4,7 @@ using ClassicalSharp.GraphicsAPI; namespace ClassicalSharp { - public class DrawTextArgs { + public struct DrawTextArgs { public Color TextColour; public string Text; diff --git a/2D/Screens/BlockSelectScreen.cs b/2D/Screens/BlockSelectScreen.cs index d99df3b0c..520f4fe40 100644 --- a/2D/Screens/BlockSelectScreen.cs +++ b/2D/Screens/BlockSelectScreen.cs @@ -109,7 +109,7 @@ namespace ClassicalSharp { Block block = blocksTable[selectedIndex].BlockId; string text = GetBlockInfo( block ); - List parts = Utils.SplitText( GraphicsApi, text, true ); + List parts = Utils2D.SplitText( GraphicsApi, text, true ); Size size = Utils2D.MeasureSize( parts, font, true ); int x = startX + ( blockSize * blocksPerRow ) / 2 - size.Width / 2; int y = startY - size.Height; diff --git a/2D/Screens/ChatScreen.cs b/2D/Screens/ChatScreen.cs index 22c2da9f9..a2903147c 100644 --- a/2D/Screens/ChatScreen.cs +++ b/2D/Screens/ChatScreen.cs @@ -142,7 +142,7 @@ namespace ClassicalSharp { void UpdateAnnouncement( string text ) { announcementDisplayTime = DateTime.UtcNow; if( !String.IsNullOrEmpty( text ) ) { - List parts = Utils.SplitText( GraphicsApi, text, true ); + List parts = Utils2D.SplitText( GraphicsApi, text, true ); Size size = Utils2D.MeasureSize( Utils.StripColours( text ), announcementFont, true ); int x = Window.Width / 2 - size.Width / 2; int y = Window.Height / 4 - size.Height / 2; @@ -232,7 +232,7 @@ namespace ClassicalSharp { using( Graphics g = Graphics.FromImage( bmp ) ) { Utils2D.DrawRect( g, backColour, 0, 0, bmp.Width, bmp.Height ); DrawTextArgs args = new DrawTextArgs( GraphicsApi, text, Color.Yellow, false ); - Utils2D.DrawText( g, historyFont, args, 0, 0 ); + Utils2D.DrawText( g, historyFont, ref args, 0, 0 ); } pageTexture = Utils2D.Make2DTexture( GraphicsApi, bmp, 10, y ); } diff --git a/2D/Screens/ErrorScreen.cs b/2D/Screens/ErrorScreen.cs index 14fc5cfd0..81ca0c9dc 100644 --- a/2D/Screens/ErrorScreen.cs +++ b/2D/Screens/ErrorScreen.cs @@ -36,7 +36,7 @@ namespace ClassicalSharp { } Texture ModifyText( int yOffset, string text, Font font ) { - List parts = Utils.SplitText( GraphicsApi, text, true ); + List parts = Utils2D.SplitText( GraphicsApi, text, true ); Size size = Utils2D.MeasureSize( Utils.StripColours( text ), font, true ); int x = Window.Width / 2 - size.Width / 2; int y = Window.Height / 2 - yOffset; diff --git a/2D/Utils2D.cs b/2D/Utils2D.cs index d46bb7dbc..af88e47b6 100644 --- a/2D/Utils2D.cs +++ b/2D/Utils2D.cs @@ -57,7 +57,7 @@ namespace ClassicalSharp { return Size.Ceiling( total ); } - public static void DrawText( Graphics g, Font font, DrawTextArgs args, float x, float y ) { + public static void DrawText( Graphics g, Font font, ref DrawTextArgs args, float x, float y ) { Brush textBrush = GetOrCreateBrush( args.TextColour ); Brush shadowBrush = GetOrCreateBrush( args.ShadowColour ); g.TextRenderingHint = TextRenderingHint.AntiAlias; @@ -71,7 +71,7 @@ namespace ClassicalSharp { public static void DrawText( Graphics g, List parts, Font font, float x, float y ) { for( int i = 0; i < parts.Count; i++ ) { DrawTextArgs part = parts[i]; - DrawText( g, font, part, x, y ); + DrawText( g, font, ref part, x, y ); SizeF partSize = g.MeasureString( part.Text, font, Int32.MaxValue, format ); x += partSize.Width; } @@ -88,11 +88,11 @@ namespace ClassicalSharp { } } - public static Texture MakeTextTexture( Font font, int x1, int y1, DrawTextArgs args ) { + public static Texture MakeTextTexture( Font font, int x1, int y1, ref DrawTextArgs args ) { Size size = MeasureSize( args.Text, font, args.UseShadow ); using( Bitmap bmp = new Bitmap( size.Width, size.Height ) ) { using( Graphics g = Graphics.FromImage( bmp ) ) { - DrawText( g, font, args, 0, 0 ); + DrawText( g, font, ref args, 0, 0 ); } return Make2DTexture( args.Graphics, bmp, x1, y1 ); } @@ -138,5 +138,42 @@ namespace ClassicalSharp { pair.Value.Dispose(); } } + + static Color[] colours = new Color[] { + Color.FromArgb( 0, 0, 0 ), // black + Color.FromArgb( 0, 0, 191 ), // dark blue + Color.FromArgb( 0, 191, 0 ), // dark green + Color.FromArgb( 0, 191, 191 ), // dark teal + Color.FromArgb( 191, 0, 0 ), // dark red + Color.FromArgb( 191, 0, 191 ), // purple + Color.FromArgb( 191, 191, 0 ), // gold + Color.FromArgb( 191, 191, 191 ), // gray + Color.FromArgb( 64, 64, 64 ), // dark gray + Color.FromArgb( 64, 64, 255 ), // blue + Color.FromArgb( 64, 255, 64 ), // lime + Color.FromArgb( 64, 255, 255 ), // teal + Color.FromArgb( 255, 64, 64 ), // red + Color.FromArgb( 255, 64, 255 ), // pink + Color.FromArgb( 255, 255, 64 ), // yellow + Color.FromArgb( 255, 255, 255 ), // white + }; + + static List parts = new List( 64 ); + public static List SplitText( IGraphicsApi graphics, string value, bool shadow ) { + int code = 15; + parts.Clear(); + for( int i = 0; i < value.Length; i++ ) { + int nextAnd = value.IndexOf( '&', i ); + int partLength = nextAnd == -1 ? value.Length - i : nextAnd - i; + + if( partLength > 0 ) { + string part = value.Substring( i, partLength ); + parts.Add( new DrawTextArgs( graphics, part, colours[code], shadow ) ); + } + i += partLength + 1; + code = nextAnd == -1 ? 0 : Utils.ParseHex( value[nextAnd + 1] ); + } + return parts; + } } } diff --git a/2D/Widgets/ExtPlayerListWidget.cs b/2D/Widgets/ExtPlayerListWidget.cs index 4b537ae1b..50fbdd69f 100644 --- a/2D/Widgets/ExtPlayerListWidget.cs +++ b/2D/Widgets/ExtPlayerListWidget.cs @@ -37,7 +37,7 @@ namespace ClassicalSharp { NameId = p.NameId; GroupName = p.GroupName; GroupRank = p.GroupRank; - List parts = Utils.SplitText( graphics, Name, true ); + List parts = Utils2D.SplitText( graphics, Name, true ); Size size = Utils2D.MeasureSize( Utils.StripColours( Name ), font, true ); Texture = Utils2D.MakeTextTexture( parts, font, size, 0, 0 ); } diff --git a/2D/Widgets/PlayerListWidget.cs b/2D/Widgets/PlayerListWidget.cs index fc34381f7..49cd6aa9d 100644 --- a/2D/Widgets/PlayerListWidget.cs +++ b/2D/Widgets/PlayerListWidget.cs @@ -31,7 +31,7 @@ namespace ClassicalSharp { public PlayerInfo( IGraphicsApi graphics, Player p, Font font ) { Name = p.DisplayName; PlayerId = p.ID; - List parts = Utils.SplitText( graphics, Name, true ); + List parts = Utils2D.SplitText( graphics, Name, true ); Size size = Utils2D.MeasureSize( Utils.StripColours( Name ), font, true ); Texture = Utils2D.MakeTextTexture( parts, font, size, 0, 0 ); } diff --git a/2D/Widgets/TextGroupWidget.cs b/2D/Widgets/TextGroupWidget.cs index ea1376524..7dd4f6180 100644 --- a/2D/Widgets/TextGroupWidget.cs +++ b/2D/Widgets/TextGroupWidget.cs @@ -32,7 +32,7 @@ namespace ClassicalSharp { List parts = null; Size size = new Size( 0, defaultHeight ); if( !String.IsNullOrEmpty( text ) ) { - parts = Utils.SplitText( GraphicsApi, text, true ); + parts = Utils2D.SplitText( GraphicsApi, text, true ); size = Utils2D.MeasureSize( Utils.StripColours( text ), font, true ); } diff --git a/2D/Widgets/TextInputWidget.cs b/2D/Widgets/TextInputWidget.cs index e47079c15..4c0fc4825 100644 --- a/2D/Widgets/TextInputWidget.cs +++ b/2D/Widgets/TextInputWidget.cs @@ -38,7 +38,7 @@ namespace ClassicalSharp { public override void Init() { X = 10; DrawTextArgs caretArgs = new DrawTextArgs( GraphicsApi, "_", Color.White, false ); - chatCaretTexture = Utils2D.MakeTextTexture( boldFont, 0, 0, caretArgs ); + chatCaretTexture = Utils2D.MakeTextTexture( boldFont, 0, 0, ref caretArgs ); if( chatInputText.Length == 0 ) { caretPos = -1; @@ -61,7 +61,7 @@ namespace ClassicalSharp { using( Graphics g = Graphics.FromImage( bmp ) ) { Utils2D.DrawRect( g, backColour, 0, 0, bmp.Width, bmp.Height ); DrawTextArgs args = new DrawTextArgs( GraphicsApi, chatInputText, Color.White, false ); - Utils2D.DrawText( g, font, args, 0, 0 ); + Utils2D.DrawText( g, font, ref args, 0, 0 ); } chatInputTexture = Utils2D.Make2DTexture( GraphicsApi, bmp, 10, y ); } diff --git a/2D/Widgets/TextWidget.cs b/2D/Widgets/TextWidget.cs index 926bacb94..b29daa39e 100644 --- a/2D/Widgets/TextWidget.cs +++ b/2D/Widgets/TextWidget.cs @@ -33,7 +33,7 @@ namespace ClassicalSharp { List parts = null; Size size = new Size( 0, defaultHeight ); - parts = Utils.SplitText( GraphicsApi, text, true ); + parts = Utils2D.SplitText( GraphicsApi, text, true ); size = Utils2D.MeasureSize( Utils.StripColours( text ), font, true ); X = CalcAdjOffset( XOffset, Window.Width, size.Width, HorizontalDocking ); diff --git a/Rendering/PlayerRenderer.cs b/Rendering/PlayerRenderer.cs index 7b2a046b4..d6029e5f8 100644 --- a/Rendering/PlayerRenderer.cs +++ b/Rendering/PlayerRenderer.cs @@ -23,7 +23,7 @@ namespace ClassicalSharp.Renderers { Graphics = window.Graphics; using( Font font = new Font( "Arial", 14 ) ) { - List parts = Utils.SplitText( Graphics, player.DisplayName, true ); + List parts = Utils2D.SplitText( Graphics, player.DisplayName, true ); Size size = Utils2D.MeasureSize( Utils.StripColours( player.DisplayName ), font, true ); nameTexture = Utils2D.MakeTextTexture( parts, font, size, 0, 0 ); nameWidth = size.Width; diff --git a/Utils/Utils.cs b/Utils/Utils.cs index 4f8d85c16..880ca7466 100644 --- a/Utils/Utils.cs +++ b/Utils/Utils.cs @@ -54,42 +54,6 @@ namespace ClassicalSharp { return new String( output, 0, usedChars ); } - static Color[] colours = new Color[] { - Color.FromArgb( 0, 0, 0 ), // black - Color.FromArgb( 0, 0, 191 ), // dark blue - Color.FromArgb( 0, 191, 0 ), // dark green - Color.FromArgb( 0, 191, 191 ), // dark teal - Color.FromArgb( 191, 0, 0 ), // dark red - Color.FromArgb( 191, 0, 191 ), // purple - Color.FromArgb( 191, 191, 0 ), // gold - Color.FromArgb( 191, 191, 191 ), // gray - Color.FromArgb( 64, 64, 64 ), // dark gray - Color.FromArgb( 64, 64, 255 ), // blue - Color.FromArgb( 64, 255, 64 ), // lime - Color.FromArgb( 64, 255, 255 ), // teal - Color.FromArgb( 255, 64, 64 ), // red - Color.FromArgb( 255, 64, 255 ), // pink - Color.FromArgb( 255, 255, 64 ), // yellow - Color.FromArgb( 255, 255, 255 ), // white - }; - - public static List SplitText( IGraphicsApi graphics, string value, bool shadow ) { - int code = 15; - List parts = new List(); - for( int i = 0; i < value.Length; i++ ) { - int nextAnd = value.IndexOf( '&', i ); - int partLength = nextAnd == -1 ? value.Length - i : nextAnd - i; - - if( partLength > 0 ) { - string part = value.Substring( i, partLength ); - parts.Add( new DrawTextArgs( graphics, part, colours[code], shadow ) ); - } - i += partLength + 1; - code = nextAnd == -1 ? 0 : ParseHex( value[nextAnd + 1] ); - } - return parts; - } - public static string ToHexString( byte[] array ) { int len = array.Length; char[] hexadecimal = new char[len * 2];