diff --git a/ClassicalSharp/2D/DrawTextArgs.cs b/ClassicalSharp/2D/DrawTextArgs.cs deleted file mode 100644 index 71780f3a3..000000000 --- a/ClassicalSharp/2D/DrawTextArgs.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Drawing; -using ClassicalSharp.GraphicsAPI; - -namespace ClassicalSharp { - - public struct DrawTextArgs { - - public Color TextColour; - public string Text; - - public bool UseShadow; - public Color ShadowColour; - public IGraphicsApi Graphics; - internal bool SkipPartsCheck; - - public DrawTextArgs( IGraphicsApi graphics, string text, Color col, bool useShadow ) : - this( graphics, text, col, useShadow, Color.Black ) { - } - - public DrawTextArgs( IGraphicsApi graphics, string text, bool useShadow ) : - this( graphics, text, Color.White, useShadow, Color.Black ) { - } - - public DrawTextArgs( IGraphicsApi graphics, string text, Color col, bool useShadow, Color shadowCol ) { - Graphics = graphics; - Text = text; - TextColour = col; - UseShadow = useShadow; - ShadowColour = shadowCol; - SkipPartsCheck = false; - } - } -} \ No newline at end of file diff --git a/ClassicalSharp/2D/Drawing/DrawTextArgs.cs b/ClassicalSharp/2D/Drawing/DrawTextArgs.cs new file mode 100644 index 000000000..a2234ce08 --- /dev/null +++ b/ClassicalSharp/2D/Drawing/DrawTextArgs.cs @@ -0,0 +1,29 @@ +using System; +using System.Drawing; + +namespace ClassicalSharp { + + public struct DrawTextArgs { + + public Color TextColour; + public string Text; + + public bool UseShadow; + public Color ShadowColour; + internal bool SkipPartsCheck; + + public DrawTextArgs( string text, Color col, bool useShadow ) : + this( text, col, useShadow, Color.Black ) { } + + public DrawTextArgs( string text, bool useShadow ) : + this( text, Color.White, useShadow, Color.Black ) { } + + public DrawTextArgs( string text, Color col, bool useShadow, Color shadowCol ) { + Text = text; + TextColour = col; + UseShadow = useShadow; + ShadowColour = shadowCol; + SkipPartsCheck = false; + } + } +} diff --git a/ClassicalSharp/2D/Drawing/GdiDrawer2D.cs b/ClassicalSharp/2D/Drawing/GdiDrawer2D.cs new file mode 100644 index 000000000..c823b56b5 --- /dev/null +++ b/ClassicalSharp/2D/Drawing/GdiDrawer2D.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; + +namespace ClassicalSharp { + + public sealed class GdiDrawer2D : IDrawer2D { + + StringFormat format; + Bitmap measuringBmp; + Graphics measuringGraphics; + Dictionary brushCache = new Dictionary( 16 ); + + Graphics g; + + public GdiDrawer2D( Game game ) { + graphics = game.Graphics; + format = StringFormat.GenericTypographic; + format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces; + format.Trimming = StringTrimming.None; + //format.FormatFlags |= StringFormatFlags.NoWrap; + //format.FormatFlags |= StringFormatFlags.NoClip; + measuringBmp = new Bitmap( 1, 1 ); + measuringGraphics = Graphics.FromImage( measuringBmp ); + measuringGraphics.TextRenderingHint = TextRenderingHint.AntiAlias; + } + + public override void SetBitmap( Bitmap bmp ) { + if( g != null ) { + Utils.LogWarning( "Previous IDrawer2D.SetBitmap() call was not properly disposed" ); + g.Dispose(); + } + + g = Graphics.FromImage( bmp ); + g.TextRenderingHint = TextRenderingHint.AntiAlias; + g.SmoothingMode = SmoothingMode.HighQuality; + } + + public override void DrawText( Font font, ref DrawTextArgs args, float x, float y ) { + if( !args.SkipPartsCheck ) + GetTextParts( args.Text ); + + Brush shadowBrush = GetOrCreateBrush( args.ShadowColour ); + for( int i = 0; i < parts.Count; i++ ) { + TextPart part = parts[i]; + Brush textBrush = GetOrCreateBrush( part.TextColour ); + if( args.UseShadow ) + g.DrawString( part.Text, font, shadowBrush, x + shadowOffset, y + shadowOffset, format ); + + g.DrawString( part.Text, font, textBrush, x, y, format ); + x += g.MeasureString( part.Text, font, Int32.MaxValue, format ).Width; + } + } + + public override void DrawRect( Color colour, int x, int y, int width, int height ) { + Brush brush = GetOrCreateBrush( colour ); + g.FillRectangle( brush, x, y, width, height ); + } + + public override void DrawRectBounds( Color colour, float lineWidth, int x, int y, int width, int height ) { + using( Pen pen = new Pen( colour, lineWidth ) ) + g.DrawRectangle( pen, x, y, width, height ); + } + + public override void DrawRoundedRect( Color colour, float x, float y, float width, float height ) { + GraphicsPath path = new GraphicsPath(); + float x1 = x, y1 = y, x2 = x + width, y2 = y + height; + + const float r = 3, dia = r * 2; + path.AddArc( x1, y1, dia, dia, 180, 90 ); + path.AddLine( x1 + r, y1, x2 - r, y1 ); + path.AddArc( x2 - dia, y1, dia, dia, 270, 90 ); + path.AddLine( x2, y1 + r, x2, y2 - r ); + path.AddArc( x2 - dia, y2 - dia, dia, dia, 0, 90 ); + path.AddLine( x1 + r, y2, x2 - r, y2 ); + path.AddArc( x1, y2 - dia, dia, dia, 90, 90 ); + path.AddLine( x1, y1 + r, x1, y2 - r ); + path.CloseAllFigures(); + + using( Brush brush = new SolidBrush( colour ) ) + g.FillPath( brush, path ); + path.Dispose(); + } + + public override void Dispose() { + g.Dispose(); + g = null; + } + + public override Size MeasureSize( string text, Font font, bool shadow ) { + GetTextParts( text ); + SizeF total = SizeF.Empty; + for( int i = 0; i < parts.Count; i++ ) { + SizeF size = measuringGraphics.MeasureString( parts[i].Text, font, Int32.MaxValue, format ); + total.Height = Math.Max( total.Height, size.Height ); + total.Width += size.Width; + } + + if( shadow && parts.Count > 0 ) { + total.Width += shadowOffset; + total.Height += shadowOffset; + } + return Size.Ceiling( total ); + } + + public override void DisposeInstance() { + measuringBmp.Dispose(); + measuringGraphics.Dispose(); + foreach( var pair in brushCache ) { + pair.Value.Dispose(); + } + } + + SolidBrush GetOrCreateBrush( Color color ) { + int key = color.ToArgb(); + SolidBrush brush; + if( brushCache.TryGetValue( key, out brush ) ) { + return brush; + } + brush = new SolidBrush( color ); + brushCache[key] = brush; + return brush; + } + } +} diff --git a/ClassicalSharp/2D/Drawing/IDrawer2D.cs b/ClassicalSharp/2D/Drawing/IDrawer2D.cs new file mode 100644 index 000000000..999ae6e8c --- /dev/null +++ b/ClassicalSharp/2D/Drawing/IDrawer2D.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using ClassicalSharp.GraphicsAPI; + +namespace ClassicalSharp { + + public abstract class IDrawer2D : IDisposable { + + protected IGraphicsApi graphics; + protected const float shadowOffset = 1.3f; + + /// Sets the underlying bitmap that drawing operations will be performed on. + public abstract void SetBitmap( Bitmap bmp ); + + public abstract void DrawText( Font font, ref DrawTextArgs args, float x, float y ); + + public abstract void DrawRect( Color colour, int x, int y, int width, int height ); + + public abstract void DrawRectBounds( Color colour, float lineWidth, int x, int y, int width, int height ); + + public abstract void DrawRoundedRect( Color colour, float x, float y, float width, float height ); + + /// Disposes of any resources used by this class that are associated with the underlying bitmap. + public abstract void Dispose(); + + + public abstract Size MeasureSize( string text, Font font, bool shadow ); + + /// Disposes of all native resources used by this class. + /// You will no longer be able to perform measuring or drawing calls after this. + public abstract void DisposeInstance(); + + public Texture MakeTextTexture( Font font, int screenX, int screenY, ref DrawTextArgs args ) { + Size size = MeasureSize( args.Text, font, args.UseShadow ); + if( parts.Count == 0 ) + return new Texture( -1, screenX, screenY, 0, 0, 1, 1 ); + + using( Bitmap bmp = CreatePow2Bitmap( size ) ) { + SetBitmap( bmp ); + args.SkipPartsCheck = true; + + DrawText( font, ref args, 0, 0 ); + Dispose(); + return Make2DTexture( bmp, size, screenX, screenY ); + } + } + + public Texture Make2DTexture( Bitmap bmp, Size used, int screenX, int screenY ) { + int texId = graphics.CreateTexture( bmp ); + return new Texture( texId, screenX, screenY, used.Width, used.Height, + (float)used.Width / bmp.Width, (float)used.Height / bmp.Height ); + } + + + public static Bitmap CreatePow2Bitmap( Size size ) { + return new Bitmap( Utils.NextPowerOf2( size.Width ), Utils.NextPowerOf2( size.Height ) ); + } + + protected List parts = new List( 64 ); + protected static Color white = Color.FromArgb( 255, 255, 255 ); + protected struct TextPart { + public string Text; + public Color TextColour; + + public TextPart( string text, Color col ) { + Text = text; + TextColour = col; + } + } + + protected void GetTextParts( string value ) { + parts.Clear(); + if( String.IsNullOrEmpty( value ) ) { + } else if( value.IndexOf( '&' ) == -1 ) { + parts.Add( new TextPart( value, white ) ); + } else { + SplitText( value ); + } + } + + protected void SplitText( string value ) { + int code = 0xF; + 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 ); + Color col = Color.FromArgb( + 191 * ( ( code >> 2 ) & 0x1 ) + 64 * ( code >> 3 ), + 191 * ( ( code >> 1 ) & 0x1 ) + 64 * ( code >> 3 ), + 191 * ( ( code >> 0 ) & 0x1 ) + 64 * ( code >> 3 ) ); + parts.Add( new TextPart( part, col ) ); + } + i += partLength + 1; + + if( nextAnd >= 0 && nextAnd + 1 < value.Length ) { + try { + code = Utils.ParseHex( value[nextAnd + 1] ); + } catch( FormatException ) { + code = 0xF; + i--; // include the character that isn't a colour code. + } + } + } + } + } +} diff --git a/ClassicalSharp/2D/Screens/BlockSelectScreen.cs b/ClassicalSharp/2D/Screens/BlockSelectScreen.cs index 8f5e53c3a..26897ecc2 100644 --- a/ClassicalSharp/2D/Screens/BlockSelectScreen.cs +++ b/ClassicalSharp/2D/Screens/BlockSelectScreen.cs @@ -76,11 +76,12 @@ namespace ClassicalSharp { public override void Init() { game.BlockPermissionsChanged += BlockPermissionsChanged; Size size = new Size( blockSize, blockSize ); - using( Bitmap bmp = Utils2D.CreatePow2Bitmap( size ) ) { - using( Graphics g = Graphics.FromImage( bmp ) ) { - Utils2D.DrawRectBounds( g, Color.White, blockSize / 8, 0, 0, blockSize, blockSize ); + using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) ) { + using( IDrawer2D drawer = game.Drawer2D ) { + drawer.SetBitmap( bmp ); + drawer.DrawRectBounds( Color.White, blockSize / 8, 0, 0, blockSize, blockSize ); + selectedBlock = drawer.Make2DTexture( bmp, size, 0, 0 ); } - selectedBlock = Utils2D.Make2DTexture( graphicsApi, bmp, size, 0, 0 ); } RecreateBlockTextures(); } @@ -139,18 +140,19 @@ namespace ClassicalSharp { UpdateBlockInfoString( block ); string value = buffer.GetString(); - Size size = Utils2D.MeasureSize( value, font, true ); + Size size = game.Drawer2D.MeasureSize( value, font, true ); int x = startX + ( blockSize * blocksPerRow ) / 2 - size.Width / 2; int y = startY - size.Height; - using( Bitmap bmp = Utils2D.CreatePow2Bitmap( size ) ) { - using( Graphics g = Graphics.FromImage( bmp ) ) { - Utils2D.DrawRect( g, backColour, 0, 0, bmp.Width, bmp.Height ); - DrawTextArgs args = new DrawTextArgs( graphicsApi, value, true ); + using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) ) { + using( IDrawer2D drawer = game.Drawer2D ) { + drawer.SetBitmap( bmp ); + drawer.DrawRect( backColour, 0, 0, bmp.Width, bmp.Height ); + DrawTextArgs args = new DrawTextArgs( value, true ); args.SkipPartsCheck = true; - Utils2D.DrawText( g, font, ref args, 0, 0 ); - } - blockInfoTexture = Utils2D.Make2DTexture( graphicsApi, bmp, size, x, y ); + drawer.DrawText( font, ref args, 0, 0 ); + blockInfoTexture = drawer.Make2DTexture( bmp, size, x, y ); + } } } diff --git a/ClassicalSharp/2D/Screens/ChatScreen.cs b/ClassicalSharp/2D/Screens/ChatScreen.cs index 99d67eee7..dbdbbd6d9 100644 --- a/ClassicalSharp/2D/Screens/ChatScreen.cs +++ b/ClassicalSharp/2D/Screens/ChatScreen.cs @@ -122,8 +122,8 @@ namespace ClassicalSharp { void UpdateAnnouncement( string text ) { announcementDisplayTime = DateTime.UtcNow; - DrawTextArgs args = new DrawTextArgs( graphicsApi, text, true ); - announcementTex = Utils2D.MakeTextTexture( announcementFont, 0, 0, ref args ); + DrawTextArgs args = new DrawTextArgs( text, true ); + announcementTex = game.Drawer2D.MakeTextTexture( announcementFont, 0, 0, ref args ); announcementTex.X1 = game.Width / 2 - announcementTex.Width / 2; announcementTex.Y1 = game.Height / 4 - announcementTex.Height / 2; } diff --git a/ClassicalSharp/2D/Screens/LoadingMapScreen.cs b/ClassicalSharp/2D/Screens/LoadingMapScreen.cs index ed89926b1..f41bc8220 100644 --- a/ClassicalSharp/2D/Screens/LoadingMapScreen.cs +++ b/ClassicalSharp/2D/Screens/LoadingMapScreen.cs @@ -36,11 +36,12 @@ namespace ClassicalSharp { progX = game.Width / 2f - progWidth / 2f; Size size = new Size( progWidth, progHeight ); - using( Bitmap bmp = Utils2D.CreatePow2Bitmap( size ) ) { - using( Graphics g = Graphics.FromImage( bmp ) ) { - Utils2D.DrawRectBounds( g, Color.White, 5f, 0, 0, progWidth, progHeight ); - } - progressBoxTexture = Utils2D.Make2DTexture( graphicsApi, bmp, size, (int)progX, (int)progY ); + using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) ) { + using( IDrawer2D drawer = game.Drawer2D ) { + drawer.SetBitmap( bmp ); + drawer.DrawRectBounds( Color.White, 5f, 0, 0, progWidth, progHeight ); + progressBoxTexture = drawer.Make2DTexture( bmp, size, (int)progX, (int)progY ); + } } game.MapLoading += MapLoading; } diff --git a/ClassicalSharp/2D/Utils2D.cs b/ClassicalSharp/2D/Utils2D.cs deleted file mode 100644 index 863b0c6fd..000000000 --- a/ClassicalSharp/2D/Utils2D.cs +++ /dev/null @@ -1,188 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Drawing2D; -using System.Drawing.Text; -using ClassicalSharp.GraphicsAPI; - -namespace ClassicalSharp { - - public static class Utils2D { - - public static StringFormat format; - static Bitmap measuringBmp; - static Graphics measuringGraphics; - static Dictionary brushCache = new Dictionary( 16 ); - - static Utils2D() { - format = StringFormat.GenericTypographic; - format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces; - format.Trimming = StringTrimming.None; - //format.FormatFlags |= StringFormatFlags.NoWrap; - //format.FormatFlags |= StringFormatFlags.NoClip; - measuringBmp = new Bitmap( 1, 1 ); - measuringGraphics = Graphics.FromImage( measuringBmp ); - measuringGraphics.TextRenderingHint = TextRenderingHint.AntiAlias; - } - - static SolidBrush GetOrCreateBrush( Color color ) { - int key = color.ToArgb(); - SolidBrush brush; - if( brushCache.TryGetValue( key, out brush ) ) { - return brush; - } - brush = new SolidBrush( color ); - brushCache[key] = brush; - return brush; - } - - public static Bitmap CreatePow2Bitmap( Size size ) { - return new Bitmap( Utils.NextPowerOf2( size.Width ), Utils.NextPowerOf2( size.Height ) ); - } - - const float shadowOffset = 1.3f; - public static Size MeasureSize( string text, Font font, bool shadow ) { - GetTextParts( text ); - SizeF total = SizeF.Empty; - for( int i = 0; i < parts.Count; i++ ) { - SizeF size = measuringGraphics.MeasureString( parts[i].Text, font, Int32.MaxValue, format ); - total.Height = Math.Max( total.Height, size.Height ); - total.Width += size.Width; - } - - if( shadow && parts.Count > 0 ) { - total.Width += shadowOffset; - total.Height += shadowOffset; - } - return Size.Ceiling( total ); - } - - public static void DrawText( Graphics g, Font font, ref DrawTextArgs args, float x, float y ) { - if( !args.SkipPartsCheck ) - GetTextParts( args.Text ); - DrawTextNoCheck( g, font, ref args, x, y ); - } - - static void DrawTextNoCheck( Graphics g, Font font, ref DrawTextArgs args, float x, float y ) { - g.TextRenderingHint = TextRenderingHint.AntiAlias; - Brush shadowBrush = GetOrCreateBrush( args.ShadowColour ); - - for( int i = 0; i < parts.Count; i++ ) { - TextPart part = parts[i]; - Brush textBrush = GetOrCreateBrush( part.TextColour ); - if( args.UseShadow ) { - g.DrawString( part.Text, font, shadowBrush, x + shadowOffset, y + shadowOffset, format ); - } - - g.DrawString( part.Text, font, textBrush, x, y, format ); - x += g.MeasureString( part.Text, font, Int32.MaxValue, format ).Width; - } - } - - public static void DrawRect( Graphics g, Color colour, int x, int y, int width, int height ) { - Brush brush = GetOrCreateBrush( colour ); - g.FillRectangle( brush, x, y, width, height ); - } - - public static void DrawRectBounds( Graphics g, Color colour, float lineWidth, int x, int y, int width, int height ) { - using( Pen pen = new Pen( colour, lineWidth ) ) - g.DrawRectangle( pen, x, y, width, height ); - } - - public static void DrawRoundedRect( Graphics g, Color colour, float x, float y, float width, float height ) { - GraphicsPath path = new GraphicsPath(); - float x1 = x, y1 = y, x2 = x + width, y2 = y + height; - - const float r = 3, dia = r * 2; - path.AddArc( x1, y1, dia, dia, 180, 90 ); - path.AddLine( x1 + r, y1, x2 - r, y1 ); - path.AddArc( x2 - dia, y1, dia, dia, 270, 90 ); - path.AddLine( x2, y1 + r, x2, y2 - r ); - path.AddArc( x2 - dia, y2 - dia, dia, dia, 0, 90 ); - path.AddLine( x1 + r, y2, x2 - r, y2 ); - path.AddArc( x1, y2 - dia, dia, dia, 90, 90 ); - path.AddLine( x1, y1 + r, x1, y2 - r ); - path.CloseAllFigures(); - - using( Brush brush = new SolidBrush( colour ) ) - g.FillPath( brush, path ); - path.Dispose(); - } - - public static Texture MakeTextTexture( Font font, int x1, int y1, ref DrawTextArgs args ) { - Size size = MeasureSize( args.Text, font, args.UseShadow ); - if( parts.Count == 0 ) - return new Texture( -1, x1, y1, 0, 0, 1, 1 ); - - using( Bitmap bmp = CreatePow2Bitmap( size ) ) { - using( Graphics g = Graphics.FromImage( bmp ) ) { - DrawTextNoCheck( g, font, ref args, 0, 0 ); - } - return Make2DTexture( args.Graphics, bmp, size, x1, y1 ); - } - } - - public static Texture Make2DTexture( IGraphicsApi graphics, Bitmap bmp, Size used, int x1, int y1 ) { - int texId = graphics.CreateTexture( bmp ); - return new Texture( texId, x1, y1, used.Width, used.Height, - (float)used.Width / bmp.Width, (float)used.Height / bmp.Height ); - } - - public static void Dispose() { - measuringBmp.Dispose(); - measuringGraphics.Dispose(); - foreach( var pair in brushCache ) { - pair.Value.Dispose(); - } - } - - static List parts = new List( 64 ); - static Color white = Color.FromArgb( 255, 255, 255 ); - struct TextPart { - public string Text; - public Color TextColour; - - public TextPart( string text, Color col ) { - Text = text; - TextColour = col; - } - } - - static void GetTextParts( string value ) { - parts.Clear(); - if( String.IsNullOrEmpty( value ) ) { - } else if( value.IndexOf( '&' ) == -1 ) { - parts.Add( new TextPart( value, white ) ); - } else { - SplitText( value ); - } - } - - static void SplitText( string value ) { - int code = 0xF; - 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 ); - Color col = Color.FromArgb( - 191 * ( ( code >> 2 ) & 0x1 ) + 64 * ( code >> 3 ), - 191 * ( ( code >> 1 ) & 0x1 ) + 64 * ( code >> 3 ), - 191 * ( ( code >> 0 ) & 0x1 ) + 64 * ( code >> 3 ) ); - parts.Add( new TextPart( part, col ) ); - } - i += partLength + 1; - - if( nextAnd >= 0 && nextAnd + 1 < value.Length ) { - try { - code = Utils.ParseHex( value[nextAnd + 1] ); - } catch( FormatException ) { - code = 0xF; - i--; // include the character that isn't a colour code. - } - } - } - } - } -} diff --git a/ClassicalSharp/2D/Widgets/BlockHotbarWidget.cs b/ClassicalSharp/2D/Widgets/BlockHotbarWidget.cs index 38736172a..e1ed5ce11 100644 --- a/ClassicalSharp/2D/Widgets/BlockHotbarWidget.cs +++ b/ClassicalSharp/2D/Widgets/BlockHotbarWidget.cs @@ -28,11 +28,12 @@ namespace ClassicalSharp { int y = game.Height - blockSize; Size size = new Size( 32, 32 ); - using( Bitmap bmp = Utils2D.CreatePow2Bitmap( size ) ) { - using( Graphics g = Graphics.FromImage( bmp ) ) { - Utils2D.DrawRectBounds( g, Color.White, blockSize / 8, 0, 0, blockSize, blockSize ); + using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) ) { + using( IDrawer2D drawer = game.Drawer2D ) { + drawer.SetBitmap( bmp ); + drawer.DrawRectBounds( Color.White, blockSize / 8, 0, 0, blockSize, blockSize ); + selectedBlock = drawer.Make2DTexture( bmp, size, 0, y ); } - selectedBlock = Utils2D.Make2DTexture( graphicsApi, bmp, size, 0, y ); } int x = game.Width / 2 - ( blockSize * barTextures.Length ) / 2; diff --git a/ClassicalSharp/2D/Widgets/ButtonWidget.cs b/ClassicalSharp/2D/Widgets/ButtonWidget.cs index e42a82ce2..eb9df3324 100644 --- a/ClassicalSharp/2D/Widgets/ButtonWidget.cs +++ b/ClassicalSharp/2D/Widgets/ButtonWidget.cs @@ -32,7 +32,7 @@ namespace ClassicalSharp { readonly Font font; public override void Init() { - defaultHeight = Utils2D.MeasureSize( "I", font, true ).Height; + defaultHeight = game.Drawer2D.MeasureSize( "I", font, true ).Height; Height = defaultHeight; } @@ -55,7 +55,7 @@ namespace ClassicalSharp { } public override void Render( double delta ) { - if( texture.IsValid ) { + if( texture.IsValid ) { FastColour col = Active ? FastColour.White : new FastColour( 200, 200, 200 ); graphicsApi.BindTexture( texture.ID ); graphicsApi.Draw2DTexture( ref texture, col ); @@ -80,9 +80,8 @@ namespace ClassicalSharp { public Action SetValue; public bool Active; - void MakeTexture( string text ) { - DrawTextArgs args = new DrawTextArgs( graphicsApi, text, true ); - Size size = Utils2D.MeasureSize( text, font, true ); + void MakeTexture( string text ) { + Size size = game.Drawer2D.MeasureSize( text, font, true ); int xOffset = Math.Max( size.Width, DesiredMaxWidth ) - size.Width; size.Width = Math.Max( size.Width, DesiredMaxWidth ); int yOffset = Math.Max( size.Height, DesiredMaxHeight ) - size.Height; @@ -91,15 +90,17 @@ namespace ClassicalSharp { const int borderSize = 3; // 1 px for base border, 2 px for shadow, 1 px for offset text size.Width += borderSize; size.Height += borderSize; - using( Bitmap bmp = Utils2D.CreatePow2Bitmap( size ) ) { - using( Graphics g = Graphics.FromImage( bmp ) ) { + using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) ) { + using( IDrawer2D drawer = game.Drawer2D ) { + drawer.SetBitmap( bmp ); + drawer.DrawRoundedRect( shadowCol, 1.3f, 1.3f, baseSize.Width, baseSize.Height ); + drawer.DrawRoundedRect( boxCol, 0, 0, baseSize.Width, baseSize.Height ); + + DrawTextArgs args = new DrawTextArgs( text, true ); args.SkipPartsCheck = true; - g.SmoothingMode = SmoothingMode.HighQuality; - Utils2D.DrawRoundedRect( g, shadowCol, 1.3f, 1.3f, baseSize.Width, baseSize.Height ); - Utils2D.DrawRoundedRect( g, boxCol, 0, 0, baseSize.Width, baseSize.Height ); - Utils2D.DrawText( g, font, ref args, 1 + xOffset / 2, 1 + yOffset / 2 ); + drawer.DrawText( font, ref args, 1 + xOffset / 2, 1 + yOffset / 2 ); + texture = drawer.Make2DTexture( bmp, size, 0, 0 ); } - texture = Utils2D.Make2DTexture( graphicsApi, bmp, size, 0, 0 ); } } } diff --git a/ClassicalSharp/2D/Widgets/ExtPlayerListWidget.cs b/ClassicalSharp/2D/Widgets/ExtPlayerListWidget.cs index ee33516e3..e134f30d2 100644 --- a/ClassicalSharp/2D/Widgets/ExtPlayerListWidget.cs +++ b/ClassicalSharp/2D/Widgets/ExtPlayerListWidget.cs @@ -106,8 +106,8 @@ namespace ClassicalSharp { } void AddPlayerInfo( CpeListInfo player, int index ) { - DrawTextArgs args = new DrawTextArgs( graphicsApi, player.ListName, true ); - Texture tex = Utils2D.MakeTextTexture( font, 0, 0, ref args ); + DrawTextArgs args = new DrawTextArgs(player.ListName, true ); + Texture tex = game.Drawer2D.MakeTextTexture( font, 0, 0, ref args ); if( index < 0 ) { info[namesCount] = new PlayerInfo( player ); textures[namesCount] = tex; diff --git a/ClassicalSharp/2D/Widgets/Menu/MenuInputWidget.cs b/ClassicalSharp/2D/Widgets/Menu/MenuInputWidget.cs index f1a9373e3..f84df46f8 100644 --- a/ClassicalSharp/2D/Widgets/Menu/MenuInputWidget.cs +++ b/ClassicalSharp/2D/Widgets/Menu/MenuInputWidget.cs @@ -48,31 +48,32 @@ namespace ClassicalSharp { } public override void Init() { - DrawTextArgs caretArgs = new DrawTextArgs( graphicsApi, "_", Color.White, false ); - chatCaretTexture = Utils2D.MakeTextTexture( boldFont, 0, 0, ref caretArgs ); + DrawTextArgs caretArgs = new DrawTextArgs( "_", Color.White, false ); + chatCaretTexture = game.Drawer2D.MakeTextTexture( boldFont, 0, 0, ref caretArgs ); SetText( chatInputText.GetString() ); } public void SetText( string value ) { chatInputText.Append( 0, value ); - Size textSize = Utils2D.MeasureSize( value, font, false ); + Size textSize = game.Drawer2D.MeasureSize( value, font, false ); Size size = new Size( Math.Max( textSize.Width, DesiredMaxWidth ), Math.Max( textSize.Height, DesiredMaxHeight ) ); - using( Bitmap bmp = Utils2D.CreatePow2Bitmap( size ) ) { - using( Graphics g = Graphics.FromImage( bmp ) ) { - Utils2D.DrawRect( g, backColour, 0, 0, size.Width, size.Height ); - DrawTextArgs args = new DrawTextArgs( graphicsApi, value, Color.White, false ); + using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) ) { + using( IDrawer2D drawer = game.Drawer2D ) { + drawer.SetBitmap( bmp ); + drawer.DrawRect( backColour, 0, 0, size.Width, size.Height ); + DrawTextArgs args = new DrawTextArgs( value, Color.White, false ); args.SkipPartsCheck = true; - Utils2D.DrawText( g, font, ref args, 0, 0 ); + drawer.DrawText( font, ref args, 0, 0 ); string range = Validator.Range; - Size hintSize = Utils2D.MeasureSize( range, hintFont, true ); - args = new DrawTextArgs( graphicsApi, range, Color.White, false ); + Size hintSize = drawer.MeasureSize( range, hintFont, true ); + args = new DrawTextArgs( range, Color.White, false ); args.SkipPartsCheck = true; - Utils2D.DrawText( g, hintFont, ref args, size.Width - hintSize.Width, 0 ); + drawer.DrawText( hintFont, ref args, size.Width - hintSize.Width, 0 ); + chatInputTexture = drawer.Make2DTexture( bmp, size, 0, 0 ); } - chatInputTexture = Utils2D.Make2DTexture( graphicsApi, bmp, size, 0, 0 ); } X = CalcOffset( game.Width, size.Width, XOffset, HorizontalDocking ); diff --git a/ClassicalSharp/2D/Widgets/NormalPlayerListWidget.cs b/ClassicalSharp/2D/Widgets/NormalPlayerListWidget.cs index 739c9371f..ff71b08a8 100644 --- a/ClassicalSharp/2D/Widgets/NormalPlayerListWidget.cs +++ b/ClassicalSharp/2D/Widgets/NormalPlayerListWidget.cs @@ -50,8 +50,8 @@ namespace ClassicalSharp { } void AddPlayerInfo( Player player ) { - DrawTextArgs args = new DrawTextArgs( graphicsApi, player.DisplayName, true ); - Texture tex = Utils2D.MakeTextTexture( font, 0, 0, ref args ); + DrawTextArgs args = new DrawTextArgs( player.DisplayName, true ); + Texture tex = game.Drawer2D.MakeTextTexture( font, 0, 0, ref args ); info[namesCount] = new PlayerInfo( player ); textures[namesCount] = tex; namesCount++; diff --git a/ClassicalSharp/2D/Widgets/TextGroupWidget.cs b/ClassicalSharp/2D/Widgets/TextGroupWidget.cs index 1801eb169..800065138 100644 --- a/ClassicalSharp/2D/Widgets/TextGroupWidget.cs +++ b/ClassicalSharp/2D/Widgets/TextGroupWidget.cs @@ -18,7 +18,7 @@ namespace ClassicalSharp { public override void Init() { textures = new Texture[ElementsCount]; - defaultHeight = Utils2D.MeasureSize( "I", font, true ).Height; + defaultHeight = game.Drawer2D.MeasureSize( "I", font, true ).Height; for( int i = 0; i < textures.Length; i++ ) { textures[i].Height = defaultHeight; } @@ -29,8 +29,8 @@ namespace ClassicalSharp { graphicsApi.DeleteTexture( ref textures[index] ); if( !String.IsNullOrEmpty( text ) ) { - DrawTextArgs args = new DrawTextArgs( graphicsApi, text, true ); - Texture tex = Utils2D.MakeTextTexture( font, 0, 0, ref args ); + DrawTextArgs args = new DrawTextArgs( text, true ); + Texture tex = game.Drawer2D.MakeTextTexture( font, 0, 0, ref args ); tex.X1 = CalcOffset( game.Width, tex.Width, XOffset, HorizontalDocking ); tex.Y1 = CalcY( index, tex.Height ); textures[index] = tex; diff --git a/ClassicalSharp/2D/Widgets/TextInputWidget.cs b/ClassicalSharp/2D/Widgets/TextInputWidget.cs index 63078aaf0..85eb6a1b3 100644 --- a/ClassicalSharp/2D/Widgets/TextInputWidget.cs +++ b/ClassicalSharp/2D/Widgets/TextInputWidget.cs @@ -31,14 +31,14 @@ namespace ClassicalSharp { public override void Init() { X = 10; - DrawTextArgs caretArgs = new DrawTextArgs( graphicsApi, "_", Color.White, false ); - chatCaretTexture = Utils2D.MakeTextTexture( boldFont, 0, 0, ref caretArgs ); + DrawTextArgs caretArgs = new DrawTextArgs( "_", Color.White, false ); + chatCaretTexture = game.Drawer2D.MakeTextTexture( boldFont, 0, 0, ref caretArgs ); string value = chatInputText.GetString(); if( chatInputText.Empty ) { caretPos = -1; } - Size size = Utils2D.MeasureSize( value, font, false ); + Size size = game.Drawer2D.MeasureSize( value, font, false ); if( caretPos == -1 ) { chatCaretTexture.X1 = 10 + size.Width; @@ -46,10 +46,10 @@ namespace ClassicalSharp { DrawString( size, value, true ); } else { string subString = chatInputText.GetSubstring( caretPos ); - Size trimmedSize = Utils2D.MeasureSize( subString, font, false ); + Size trimmedSize = game.Drawer2D.MeasureSize( subString, font, false ); chatCaretTexture.X1 = 10 + trimmedSize.Width; - Size charSize = Utils2D.MeasureSize( new String( value[caretPos], 1 ), font, false ); + Size charSize = game.Drawer2D.MeasureSize( new String( value[caretPos], 1 ), font, false ); chatCaretTexture.Width = charSize.Width; DrawString( size, value, false ); } @@ -59,14 +59,15 @@ namespace ClassicalSharp { size.Height = Math.Max( size.Height, chatCaretTexture.Height ); int y = game.Height - ChatInputYOffset - size.Height / 2; - using( Bitmap bmp = Utils2D.CreatePow2Bitmap( size ) ) { - using( Graphics g = Graphics.FromImage( bmp ) ) { - Utils2D.DrawRect( g, backColour, 0, 0, bmp.Width, bmp.Height ); - DrawTextArgs args = new DrawTextArgs( graphicsApi, value, Color.White, false ); + using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) ) { + using( IDrawer2D drawer = game.Drawer2D ) { + drawer.SetBitmap( bmp ); + drawer.DrawRect( backColour, 0, 0, bmp.Width, bmp.Height ); + DrawTextArgs args = new DrawTextArgs( value, Color.White, false ); args.SkipPartsCheck = skipCheck; - Utils2D.DrawText( g, font, ref args, 0, 0 ); + drawer.DrawText( font, ref args, 0, 0 ); + chatInputTexture = drawer.Make2DTexture( bmp, size, 10, y ); } - chatInputTexture = Utils2D.Make2DTexture( graphicsApi, bmp, size, 10, y ); } chatCaretTexture.Y1 = chatInputTexture.Y1; @@ -133,7 +134,7 @@ namespace ClassicalSharp { void BackspaceKey() { if( !chatInputText.Empty && caretPos != 0 ) { if( caretPos == -1 ) { - chatInputText.DeleteAt( chatInputText.Length - 1 ); + chatInputText.DeleteAt( chatInputText.Length - 1 ); } else { caretPos--; chatInputText.DeleteAt( caretPos ); diff --git a/ClassicalSharp/2D/Widgets/TextWidget.cs b/ClassicalSharp/2D/Widgets/TextWidget.cs index 6f21c26a1..5338fafdc 100644 --- a/ClassicalSharp/2D/Widgets/TextWidget.cs +++ b/ClassicalSharp/2D/Widgets/TextWidget.cs @@ -27,7 +27,7 @@ namespace ClassicalSharp { readonly Font font; public override void Init() { - defaultHeight = Utils2D.MeasureSize( "I", font, true ).Height; + defaultHeight = game.Drawer2D.MeasureSize( "I", font, true ).Height; Height = defaultHeight; } @@ -37,8 +37,8 @@ namespace ClassicalSharp { texture = new Texture(); Height = defaultHeight; } else { - DrawTextArgs args = new DrawTextArgs( graphicsApi, text, true ); - texture = Utils2D.MakeTextTexture( font, 0, 0, ref args ); + DrawTextArgs args = new DrawTextArgs( text, true ); + texture = game.Drawer2D.MakeTextTexture( font, 0, 0, ref args ); X = texture.X1 = CalcOffset( game.Width, texture.Width, XOffset, HorizontalDocking ); Y = texture.Y1 = CalcOffset( game.Height, texture.Height, YOffset, VerticalDocking ); Height = texture.Height; diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj index 9c6551ed6..f973caafe 100644 --- a/ClassicalSharp/ClassicalSharp.csproj +++ b/ClassicalSharp/ClassicalSharp.csproj @@ -65,7 +65,9 @@ - + + + @@ -81,7 +83,6 @@ - @@ -197,6 +198,7 @@ + diff --git a/ClassicalSharp/Entities/Player.Rendering.cs b/ClassicalSharp/Entities/Player.Rendering.cs index 5b6bb0e43..2100cb915 100644 --- a/ClassicalSharp/Entities/Player.Rendering.cs +++ b/ClassicalSharp/Entities/Player.Rendering.cs @@ -21,8 +21,8 @@ namespace ClassicalSharp { api = game.Graphics; using( Font font = new Font( "Arial", 14 ) ) { - DrawTextArgs args = new DrawTextArgs( api, DisplayName, true ); - nameTex = Utils2D.MakeTextTexture( font, 0, 0, ref args ); + DrawTextArgs args = new DrawTextArgs( DisplayName, true ); + nameTex = game.Drawer2D.MakeTextTexture( font, 0, 0, ref args ); } } diff --git a/ClassicalSharp/Game/Game.cs b/ClassicalSharp/Game/Game.cs index 11a36fefd..51fd4e097 100644 --- a/ClassicalSharp/Game/Game.cs +++ b/ClassicalSharp/Game/Game.cs @@ -39,6 +39,7 @@ namespace ClassicalSharp { public EnvRenderer EnvRenderer; public WeatherRenderer WeatherRenderer; public Inventory Inventory; + public IDrawer2D Drawer2D; public CommandManager CommandManager; public SelectionManager SelectionManager; @@ -98,6 +99,7 @@ namespace ClassicalSharp { Utils.LogWarning( "Unable to load options.txt" ); } Keys = new KeyMap(); + Drawer2D = new GdiDrawer2D( this ); ViewDistance = Options.GetInt( "viewdist", 16, 8192, 512 ); defaultIb = Graphics.MakeDefaultIb(); ModelCache = new ModelCache( this ); @@ -346,7 +348,7 @@ namespace ClassicalSharp { } Graphics.DeleteIb( defaultIb ); Graphics.Dispose(); - Utils2D.Dispose(); + Drawer2D.DisposeInstance(); Animations.Dispose(); Graphics.DeleteTexture( ref CloudsTextureId ); Graphics.DeleteTexture( ref RainTextureId );