mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-30 00:55:51 -04:00
273 lines
8.9 KiB
C#
273 lines
8.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Drawing.Text;
|
|
using ClassicalSharp.GraphicsAPI;
|
|
|
|
namespace ClassicalSharp {
|
|
|
|
public static class Utils2D {
|
|
|
|
public static StringFormat format;
|
|
static Utils2D() {
|
|
format = StringFormat.GenericTypographic;
|
|
format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
|
|
format.Trimming = StringTrimming.None;
|
|
//format.FormatFlags |= StringFormatFlags.NoWrap;
|
|
//format.FormatFlags |= StringFormatFlags.NoClip;
|
|
}
|
|
|
|
const float shadowOffset = 1.3f;
|
|
public static Size MeasureSize( string text, string fontName, float fontSize, bool shadow ) {
|
|
using( Font font = new Font( fontName, fontSize ) ) {
|
|
return MeasureSize( text, font, shadow );
|
|
}
|
|
}
|
|
|
|
public static Size MeasureSize( string text, string fontName, float fontSize, FontStyle style, bool shadow ) {
|
|
using( Font font = new Font( fontName, fontSize, style ) ) {
|
|
return MeasureSize( text, font, shadow );
|
|
}
|
|
}
|
|
|
|
public static Size MeasureSize( string text, Font font, bool shadow ) {
|
|
using( Bitmap measuringBmp = new Bitmap( 1, 1 ) ) {
|
|
using( Graphics g = Graphics.FromImage( measuringBmp ) ) {
|
|
SizeF size = g.MeasureString( text, font, Int32.MaxValue, format );
|
|
if( shadow ) {
|
|
size.Width += shadowOffset;
|
|
size.Height += shadowOffset;
|
|
}
|
|
return Size.Ceiling( size );
|
|
}
|
|
}
|
|
}
|
|
|
|
public static Size MeasureSize( List<DrawTextArgs> parts, string fontName, float fontSize, bool shadow ) {
|
|
using( Font font = new Font( fontName, fontSize ) ) {
|
|
return MeasureSize( parts, font, shadow );
|
|
}
|
|
}
|
|
|
|
public static Size MeasureSize( List<DrawTextArgs> parts, Font font, bool shadow ) {
|
|
SizeF total = SizeF.Empty;
|
|
using( Bitmap measuringBmp = new Bitmap( 1, 1 ) ) {
|
|
using( Graphics g = Graphics.FromImage( measuringBmp ) ) {
|
|
for( int i = 0; i < parts.Count; i++ ) {
|
|
SizeF size = g.MeasureString( parts[i].Text, font, Int32.MaxValue, format );
|
|
total.Height = Math.Max( total.Height, size.Height );
|
|
total.Width += size.Width;
|
|
}
|
|
}
|
|
}
|
|
if( shadow ) {
|
|
total.Width += shadowOffset;
|
|
total.Height += shadowOffset;
|
|
}
|
|
return Size.Ceiling( total );
|
|
}
|
|
|
|
|
|
public static void DrawText( Graphics g, string fontName, float fontSize, DrawTextArgs args ) {
|
|
using( Font font = new Font( fontName, fontSize ) ) {
|
|
DrawText( g, font, args );
|
|
}
|
|
}
|
|
|
|
public static void DrawText( Graphics g, string fontName, float fontSize, FontStyle style, DrawTextArgs args ) {
|
|
using( Font font = new Font( fontName, fontSize, style ) ) {
|
|
DrawText( g, font, args );
|
|
}
|
|
}
|
|
|
|
public static void DrawText( Graphics g, Font font, DrawTextArgs args ) {
|
|
float x = args.XOffset, y = args.YOffset;
|
|
using( Brush textBrush = new SolidBrush( args.TextColour ),
|
|
shadowBrush = new SolidBrush( args.ShadowColour ) ) {
|
|
g.TextRenderingHint = TextRenderingHint.AntiAlias;
|
|
if( args.UseShadow ) {
|
|
g.DrawString( args.Text, font, shadowBrush, x + shadowOffset, y + shadowOffset, format );
|
|
}
|
|
g.DrawString( args.Text, font, textBrush, x, y, format );
|
|
}
|
|
}
|
|
|
|
public static void DrawText( Graphics g, List<DrawTextArgs> parts, string fontName, float fontSize ) {
|
|
using( Font font = new Font( fontName, fontSize ) ) {
|
|
DrawText( g, parts, font );
|
|
}
|
|
}
|
|
|
|
public static void DrawText( Graphics g, List<DrawTextArgs> parts, string fontName, float fontSize, float x, float y ) {
|
|
using( Font font = new Font( fontName, fontSize ) ) {
|
|
DrawText( g, parts, font, x, y );
|
|
}
|
|
}
|
|
|
|
public static void DrawText( Graphics g, List<DrawTextArgs> parts, Font font ) {
|
|
DrawText( g, parts, font, 0, 0 );
|
|
}
|
|
|
|
public static void DrawText( Graphics g, List<DrawTextArgs> parts, Font font, float x, float y ) {
|
|
for( int i = 0; i < parts.Count; i++ ) {
|
|
DrawTextArgs part = parts[i];
|
|
part.XOffset = x;
|
|
part.YOffset = y;
|
|
DrawText( g, font, part );
|
|
SizeF partSize = g.MeasureString( part.Text, font, Int32.MaxValue, format );
|
|
x += partSize.Width;
|
|
}
|
|
}
|
|
|
|
public static void DrawRect( Graphics g, Color colour, int x, int y, int width, int height ) {
|
|
using( Brush brush = new SolidBrush( colour ) ) {
|
|
g.FillRectangle( brush, x, y, width, height );
|
|
}
|
|
}
|
|
|
|
public static void DrawRect( Graphics g, Color colour, int width, int height ) {
|
|
DrawRect( g, colour, 0, 0, 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 DrawRectBounds( Graphics g, Color colour, float lineWidth, int width, int height ) {
|
|
DrawRectBounds( g, colour, lineWidth, 0, 0, width, height );
|
|
}
|
|
|
|
|
|
public static Texture MakeTextTexture( string fontName, float fontSize, int x1, int y1, DrawTextArgs args ) {
|
|
using( Font font = new Font( fontName, fontSize ) ) {
|
|
return MakeTextTexture( font, x1, y1, args );
|
|
}
|
|
}
|
|
|
|
public static Texture MakeTextTexture( string fontName, float fontSize, FontStyle style, int x1, int y1, DrawTextArgs args ) {
|
|
using( Font font = new Font( fontName, fontSize, style ) ) {
|
|
return MakeTextTexture( font, x1, y1, args );
|
|
}
|
|
}
|
|
|
|
public static Texture MakeTextTexture( Font font, int x1, int y1, 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 );
|
|
}
|
|
return Make2DTexture( args.Graphics, bmp, x1, y1 );
|
|
}
|
|
}
|
|
|
|
public static Texture MakeTextTexture( List<DrawTextArgs> parts, string fontName, float fontSize, Size size, int x1, int y1 ) {
|
|
using( Font font = new Font( fontName, fontSize ) ) {
|
|
return MakeTextTexture( parts, font, size, x1, y1 );
|
|
}
|
|
}
|
|
|
|
public static Texture MakeTextTexture( List<DrawTextArgs> parts, string fontName, float fontSize, FontStyle style, Size size, int x1, int y1 ) {
|
|
using( Font font = new Font( fontName, fontSize, style ) ) {
|
|
return MakeTextTexture( parts, font, size, x1, y1 );
|
|
}
|
|
}
|
|
|
|
public static Texture MakeTextTexture( List<DrawTextArgs> parts, Font font, Size size, int x1, int y1 ) {
|
|
if( parts.Count == 0 ) return new Texture( -1, x1, y1, 0, 0, 1, 1 );
|
|
using( Bitmap bmp = new Bitmap( size.Width, size.Height ) ) {
|
|
using( Graphics g = Graphics.FromImage( bmp ) ) {
|
|
DrawText( g, parts, font );
|
|
}
|
|
return Make2DTexture( parts[0].Graphics, bmp, x1, y1 );
|
|
}
|
|
}
|
|
|
|
public static Texture Make2DTexture( IGraphicsApi graphics, Bitmap bmp, int x1, int y1 ) {
|
|
if( graphics.SupportsNonPowerOf2Textures ) {
|
|
int textureID = graphics.LoadTexture( bmp );
|
|
return new Texture( textureID, x1, y1, bmp.Width, bmp.Height, 1f, 1f );
|
|
} else {
|
|
using( Bitmap adjBmp = ResizeToPower2( bmp ) ) {
|
|
int textureID = graphics.LoadTexture( adjBmp );
|
|
return new Texture( textureID, x1, y1, bmp.Width, bmp.Height,
|
|
(float)bmp.Width / adjBmp.Width, (float)bmp.Height / adjBmp.Height );
|
|
}
|
|
}
|
|
}
|
|
|
|
public static bool Contains( int recX, int recY, int width, int height, int x, int y ) {
|
|
return x >= recX && y >= recY && x < recX + width && y < recY + height;
|
|
}
|
|
|
|
public static Bitmap ResizeToPower2( Bitmap bmp ) {
|
|
int adjWidth = Utils.NextPowerOf2( bmp.Width );
|
|
int adjHeight = Utils.NextPowerOf2( bmp.Height );
|
|
Bitmap adjBmp = new Bitmap( adjWidth, adjHeight );
|
|
using( Graphics g = Graphics.FromImage( adjBmp ) ) {
|
|
g.DrawImage( bmp, 0, 0 );
|
|
}
|
|
return adjBmp;
|
|
}
|
|
}
|
|
|
|
public struct Texture {
|
|
public int ID;
|
|
public int X1, Y1;
|
|
public int Width, Height;
|
|
public float U1, V1;
|
|
// Normally just used for graphics cards that don't support non power of two textures.
|
|
public float U2, V2;
|
|
|
|
public Texture( int id, int x, int y, int width, int height, float u2, float v2 )
|
|
: this( id, x, y, width, height, 0, u2, 0, v2 ) {
|
|
}
|
|
|
|
public Texture( int id, int x, int y, int width, int height, TextureRectangle rec )
|
|
: this( id, x, y, width, height, rec.U1, rec.U2, rec.V1, rec.V2 ) {
|
|
}
|
|
|
|
public Texture( int id, int x, int y, int width, int height, float u1, float u2, float v1, float v2 ) {
|
|
ID = id;
|
|
X1 = x;
|
|
Y1 = y;
|
|
Width = width;
|
|
Height = height;
|
|
U1 = u1;
|
|
V1 = v1;
|
|
U2 = u2;
|
|
V2 = v2;
|
|
}
|
|
|
|
public bool IsValid {
|
|
get { return ID > 0; }
|
|
}
|
|
|
|
public void Render( IGraphicsApi graphics ) {
|
|
graphics.Texturing = true;
|
|
graphics.Bind2DTexture( ID );
|
|
graphics.Draw2DTexture( ref this );
|
|
graphics.Texturing = false;
|
|
}
|
|
|
|
public void RenderNoBind( IGraphicsApi graphics ) {
|
|
graphics.Draw2DTexture( ref this );
|
|
}
|
|
|
|
public int X2 {
|
|
get { return X1 + Width; }
|
|
//set { X1 = value - Width; }
|
|
}
|
|
|
|
public int Y2 {
|
|
get { return Y1 + Height; }
|
|
//set { Y1 = value - Height; }
|
|
}
|
|
|
|
public override string ToString() {
|
|
return ID + String.Format( "({0}, {1} -> {2},{3}", X1, Y1, Width, Height );
|
|
}
|
|
}
|
|
}
|