mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-14 18:15:28 -04:00
Start work on using default.png as an alternative for text rendering.
This commit is contained in:
parent
30cffb2e20
commit
4f4b6e2a2f
@ -7,25 +7,14 @@ using ClassicalSharp.GraphicsAPI;
|
|||||||
|
|
||||||
namespace ClassicalSharp {
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
public sealed class GdiPlusDrawer2D : IDrawer2D {
|
public abstract class GdiPlusDrawer2D : IDrawer2D {
|
||||||
|
|
||||||
StringFormat format;
|
|
||||||
Bitmap measuringBmp;
|
|
||||||
Graphics measuringGraphics;
|
|
||||||
Dictionary<int, SolidBrush> brushCache = new Dictionary<int, SolidBrush>( 16 );
|
Dictionary<int, SolidBrush> brushCache = new Dictionary<int, SolidBrush>( 16 );
|
||||||
|
|
||||||
Graphics g;
|
protected Graphics g;
|
||||||
|
protected Bitmap curBmp;
|
||||||
public GdiPlusDrawer2D( IGraphicsApi graphics ) {
|
public GdiPlusDrawer2D( IGraphicsApi graphics ) {
|
||||||
this.graphics = graphics;
|
this.graphics = 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 ) {
|
public override void SetBitmap( Bitmap bmp ) {
|
||||||
@ -37,42 +26,7 @@ namespace ClassicalSharp {
|
|||||||
g = Graphics.FromImage( bmp );
|
g = Graphics.FromImage( bmp );
|
||||||
g.TextRenderingHint = TextRenderingHint.AntiAlias;
|
g.TextRenderingHint = TextRenderingHint.AntiAlias;
|
||||||
g.SmoothingMode = SmoothingMode.HighQuality;
|
g.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
}
|
curBmp = bmp;
|
||||||
|
|
||||||
public override void DrawText( ref DrawTextArgs args, float x, float y ) {
|
|
||||||
if( !args.SkipPartsCheck )
|
|
||||||
GetTextParts( args.Text );
|
|
||||||
|
|
||||||
Brush shadowBrush = GetOrCreateBrush( Color.Black );
|
|
||||||
for( int i = 0; i < parts.Count; i++ ) {
|
|
||||||
TextPart part = parts[i];
|
|
||||||
Brush textBrush = GetOrCreateBrush( part.TextColour );
|
|
||||||
if( args.UseShadow )
|
|
||||||
g.DrawString( part.Text, args.Font, shadowBrush, x + Offset, y + Offset, format );
|
|
||||||
|
|
||||||
g.DrawString( part.Text, args.Font, textBrush, x, y, format );
|
|
||||||
x += g.MeasureString( part.Text, args.Font, Int32.MaxValue, format ).Width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void DrawClippedText( ref DrawTextArgs args, float x, float y, float maxWidth, float maxHeight ) {
|
|
||||||
if( !args.SkipPartsCheck )
|
|
||||||
GetTextParts( args.Text );
|
|
||||||
|
|
||||||
Brush shadowBrush = GetOrCreateBrush( Color.Black );
|
|
||||||
format.Trimming = StringTrimming.EllipsisCharacter;
|
|
||||||
for( int i = 0; i < parts.Count; i++ ) {
|
|
||||||
TextPart part = parts[i];
|
|
||||||
Brush textBrush = GetOrCreateBrush( part.TextColour );
|
|
||||||
RectangleF rect = new RectangleF( x + Offset, y + Offset, maxWidth, maxHeight );
|
|
||||||
if( args.UseShadow )
|
|
||||||
g.DrawString( part.Text, args.Font, shadowBrush, rect, format );
|
|
||||||
|
|
||||||
rect = new RectangleF( x, y, maxWidth, maxHeight );
|
|
||||||
g.DrawString( part.Text, args.Font, textBrush, rect, format );
|
|
||||||
x += g.MeasureString( part.Text, args.Font, Int32.MaxValue, format ).Width;
|
|
||||||
}
|
|
||||||
format.Trimming = StringTrimming.None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void DrawRect( FastColour colour, int x, int y, int width, int height ) {
|
public override void DrawRect( FastColour colour, int x, int y, int width, int height ) {
|
||||||
@ -132,30 +86,13 @@ namespace ClassicalSharp {
|
|||||||
return bmp;
|
return bmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Size MeasureSize( ref DrawTextArgs args ) {
|
|
||||||
GetTextParts( args.Text );
|
|
||||||
SizeF total = SizeF.Empty;
|
|
||||||
for( int i = 0; i < parts.Count; i++ ) {
|
|
||||||
SizeF size = measuringGraphics.MeasureString( parts[i].Text, args.Font, Int32.MaxValue, format );
|
|
||||||
total.Height = Math.Max( total.Height, size.Height );
|
|
||||||
total.Width += size.Width;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( args.UseShadow && parts.Count > 0 ) {
|
|
||||||
total.Width += Offset; total.Height += Offset;
|
|
||||||
}
|
|
||||||
return Size.Ceiling( total );
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void DisposeInstance() {
|
public override void DisposeInstance() {
|
||||||
measuringBmp.Dispose();
|
|
||||||
measuringGraphics.Dispose();
|
|
||||||
foreach( var pair in brushCache ) {
|
foreach( var pair in brushCache ) {
|
||||||
pair.Value.Dispose();
|
pair.Value.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SolidBrush GetOrCreateBrush( Color color ) {
|
protected SolidBrush GetOrCreateBrush( Color color ) {
|
||||||
int key = color.ToArgb();
|
int key = color.ToArgb();
|
||||||
SolidBrush brush;
|
SolidBrush brush;
|
||||||
if( brushCache.TryGetValue( key, out brush ) ) {
|
if( brushCache.TryGetValue( key, out brush ) ) {
|
||||||
|
86
ClassicalSharp/2D/Drawing/GdiPlusDrawerFont.cs
Normal file
86
ClassicalSharp/2D/Drawing/GdiPlusDrawerFont.cs
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Text;
|
||||||
|
using ClassicalSharp.GraphicsAPI;
|
||||||
|
|
||||||
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
|
public sealed class GdiPlusDrawerFont : GdiPlusDrawer2D {
|
||||||
|
|
||||||
|
StringFormat format;
|
||||||
|
Bitmap measuringBmp;
|
||||||
|
Graphics measuringGraphics;
|
||||||
|
|
||||||
|
public GdiPlusDrawerFont( IGraphicsApi graphics ) : base( 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 DrawText( ref DrawTextArgs args, int x, int y ) {
|
||||||
|
if( !args.SkipPartsCheck )
|
||||||
|
GetTextParts( args.Text );
|
||||||
|
|
||||||
|
Brush shadowBrush = GetOrCreateBrush( Color.Black );
|
||||||
|
float textX = x;
|
||||||
|
for( int i = 0; i < parts.Count; i++ ) {
|
||||||
|
TextPart part = parts[i];
|
||||||
|
Brush textBrush = GetOrCreateBrush( part.TextColour );
|
||||||
|
if( args.UseShadow )
|
||||||
|
g.DrawString( part.Text, args.Font, shadowBrush, textX + Offset, y + Offset, format );
|
||||||
|
|
||||||
|
g.DrawString( part.Text, args.Font, textBrush, textX, y, format );
|
||||||
|
textX += g.MeasureString( part.Text, args.Font, Int32.MaxValue, format ).Width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DrawClippedText( ref DrawTextArgs args, int x, int y, float maxWidth, float maxHeight ) {
|
||||||
|
if( !args.SkipPartsCheck )
|
||||||
|
GetTextParts( args.Text );
|
||||||
|
|
||||||
|
Brush shadowBrush = GetOrCreateBrush( Color.Black );
|
||||||
|
format.Trimming = StringTrimming.EllipsisCharacter;
|
||||||
|
float textX = x;
|
||||||
|
|
||||||
|
for( int i = 0; i < parts.Count; i++ ) {
|
||||||
|
TextPart part = parts[i];
|
||||||
|
Brush textBrush = GetOrCreateBrush( part.TextColour );
|
||||||
|
RectangleF rect = new RectangleF( textX + Offset, y + Offset, maxWidth, maxHeight );
|
||||||
|
if( args.UseShadow )
|
||||||
|
g.DrawString( part.Text, args.Font, shadowBrush, rect, format );
|
||||||
|
|
||||||
|
rect = new RectangleF( textX, y, maxWidth, maxHeight );
|
||||||
|
g.DrawString( part.Text, args.Font, textBrush, rect, format );
|
||||||
|
textX += g.MeasureString( part.Text, args.Font, Int32.MaxValue, format ).Width;
|
||||||
|
}
|
||||||
|
format.Trimming = StringTrimming.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Size MeasureSize( ref DrawTextArgs args ) {
|
||||||
|
GetTextParts( args.Text );
|
||||||
|
SizeF total = SizeF.Empty;
|
||||||
|
for( int i = 0; i < parts.Count; i++ ) {
|
||||||
|
SizeF size = measuringGraphics.MeasureString( parts[i].Text, args.Font, Int32.MaxValue, format );
|
||||||
|
total.Height = Math.Max( total.Height, size.Height );
|
||||||
|
total.Width += size.Width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( args.UseShadow && parts.Count > 0 ) {
|
||||||
|
total.Width += Offset; total.Height += Offset;
|
||||||
|
}
|
||||||
|
return Size.Ceiling( total );
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DisposeInstance() {
|
||||||
|
base.DisposeInstance();
|
||||||
|
measuringGraphics.Dispose();
|
||||||
|
measuringBmp.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
140
ClassicalSharp/2D/Drawing/GdiPlusDrawerMCFont.cs
Normal file
140
ClassicalSharp/2D/Drawing/GdiPlusDrawerMCFont.cs
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using ClassicalSharp.GraphicsAPI;
|
||||||
|
|
||||||
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
|
public sealed class GdiPlusDrawerMCFont : GdiPlusDrawer2D {
|
||||||
|
|
||||||
|
// NOTE: This drawer is still a big work in progress and not close to done
|
||||||
|
// TODO: proper shadow colour
|
||||||
|
// TODO: italic and bold
|
||||||
|
Bitmap realBmp;
|
||||||
|
public GdiPlusDrawerMCFont( IGraphicsApi graphics ) : base( graphics ) {
|
||||||
|
realBmp = new Bitmap( "default.png" );
|
||||||
|
CalculateTextWidths();
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] widths = new int[256];
|
||||||
|
unsafe void CalculateTextWidths() {
|
||||||
|
using( FastBitmap fastBmp = new FastBitmap( realBmp, true ) ) {
|
||||||
|
for( int i = 0; i < 256; i++ ) {
|
||||||
|
int tileX = (i & 0x0F) * 8;
|
||||||
|
int tileY = (i >> 4) * 8;
|
||||||
|
MakeTile( fastBmp, i, tileX, tileY );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
widths[(int)' '] = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe void MakeTile( FastBitmap fastBmp, int i, int tileX, int tileY ) {
|
||||||
|
for( int x = 7; x >= 0; x-- ) {
|
||||||
|
for( int y = 0; y < 8; y++ ) {
|
||||||
|
uint pixel = (uint)fastBmp.GetRowPtr( tileY + y )[tileX + x];
|
||||||
|
uint a = pixel >> 24;
|
||||||
|
if( a >= 127 ) {
|
||||||
|
widths[i] = x + 1;
|
||||||
|
Console.WriteLine( widths[i] );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
widths[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DrawText( ref DrawTextArgs args, int x, int y ) {
|
||||||
|
if( !args.SkipPartsCheck )
|
||||||
|
GetTextParts( args.Text );
|
||||||
|
|
||||||
|
if( args.UseShadow ) {
|
||||||
|
int shadowX = x + 1, shadowY = y + 1;
|
||||||
|
for( int i = 0; i < parts.Count; i++ ) {
|
||||||
|
TextPart part = parts[i];
|
||||||
|
part.TextColour = FastColour.Black;
|
||||||
|
DrawPart( ref shadowX, shadowY, args.Font.Size, part );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int i = 0; i < parts.Count; i++ ) {
|
||||||
|
TextPart part = parts[i];
|
||||||
|
DrawPart( ref x, y, args.Font.Size, part );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawPart( ref int x, int y, float point, TextPart part ) {
|
||||||
|
string text = part.Text;
|
||||||
|
foreach( char c in text ) {
|
||||||
|
int coords = (int)c;
|
||||||
|
int srcX = (coords & 0x0F) * 8;
|
||||||
|
int srcY = (coords >> 4) * 8;
|
||||||
|
|
||||||
|
for( int yy = 0; yy < 8; yy++ ) {
|
||||||
|
for( int xx = 0; xx < widths[coords]; xx++ ) {
|
||||||
|
FastColour col = realBmp.GetPixel( srcX + xx, srcY + yy );
|
||||||
|
if( col.A < 127 ) continue;
|
||||||
|
col.R = (byte)(col.R * part.TextColour.R / 255);
|
||||||
|
col.G = (byte)(col.G * part.TextColour.G / 255);
|
||||||
|
col.B = (byte)(col.B * part.TextColour.B / 255);
|
||||||
|
|
||||||
|
curBmp.SetPixel( x + xx, y + yy, col );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x += widths[coords] + 1;
|
||||||
|
/*int rawWidth = widths[coords] + 1;
|
||||||
|
int rawHeight = 8;
|
||||||
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
|
||||||
|
g.DrawImage( realBmp,
|
||||||
|
new Rectangle( x, y, PtToPx( point, rawWidth ), PtToPx( point, rawHeight ) ),
|
||||||
|
new Rectangle( srcX, srcY, 8, 8 ),
|
||||||
|
GraphicsUnit.Pixel );
|
||||||
|
|
||||||
|
for( int yy = 0; yy < PtToPx( point, rawHeight ); yy++ ) {
|
||||||
|
for( int xx = 0; xx < PtToPx( point, rawWidth ); xx++ ) {
|
||||||
|
FastColour col = curBmp.GetPixel( x + xx, y + yy );
|
||||||
|
if( col.A < 127 ) continue;
|
||||||
|
col.R = (byte)(col.R * part.TextColour.R / 255);
|
||||||
|
col.G = (byte)(col.G * part.TextColour.G / 255);
|
||||||
|
col.B = (byte)(col.B * part.TextColour.B / 255);
|
||||||
|
|
||||||
|
curBmp.SetPixel( x + xx, y + yy, col );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x += PtToPx( point, rawWidth );*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DrawClippedText( ref DrawTextArgs args, int x, int y, float maxWidth, float maxHeight ) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Size MeasureSize( ref DrawTextArgs args ) {
|
||||||
|
GetTextParts( args.Text );
|
||||||
|
float point = args.Font.Size;
|
||||||
|
//Size total = new Size( 0, PtToPx( point, 8 ) );
|
||||||
|
Size total = new Size( 0, 8 );
|
||||||
|
|
||||||
|
for( int i = 0; i < parts.Count; i++ ) {
|
||||||
|
foreach( char c in parts[i].Text ) {
|
||||||
|
total.Width += widths[(int)c] + 1;//PtToPx( point, widths[(int)c] + 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( args.UseShadow && parts.Count > 0 ) {
|
||||||
|
total.Width += 1; total.Height += 1;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PtToPx( int point ) {
|
||||||
|
return (int)Math.Ceiling( (float)point / 72 * 96 ); // TODO: non 96 dpi?
|
||||||
|
}
|
||||||
|
|
||||||
|
int PtToPx( float point, float value ) {
|
||||||
|
return (int)Math.Ceiling( (value / 8f) * point / 72f * 96f );
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DisposeInstance() {
|
||||||
|
base.DisposeInstance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,11 +18,11 @@ namespace ClassicalSharp {
|
|||||||
|
|
||||||
/// <summary> Draws a string using the specified arguments and fonts at the
|
/// <summary> Draws a string using the specified arguments and fonts at the
|
||||||
/// specified coordinates in the currently bound bitmap. </summary>
|
/// specified coordinates in the currently bound bitmap. </summary>
|
||||||
public abstract void DrawText( ref DrawTextArgs args, float x, float y );
|
public abstract void DrawText( ref DrawTextArgs args, int x, int y );
|
||||||
|
|
||||||
/// <summary> Draws a string using the specified arguments and fonts at the
|
/// <summary> Draws a string using the specified arguments and fonts at the
|
||||||
/// specified coordinates in the currently bound bitmap, clipping if necessary. </summary>
|
/// specified coordinates in the currently bound bitmap, clipping if necessary. </summary>
|
||||||
public abstract void DrawClippedText( ref DrawTextArgs args, float x, float y, float maxWidth, float maxHeight );
|
public abstract void DrawClippedText( ref DrawTextArgs args, int x, int y, float maxWidth, float maxHeight );
|
||||||
|
|
||||||
/// <summary> Draws a 2D flat rectangle of the specified dimensions at the
|
/// <summary> Draws a 2D flat rectangle of the specified dimensions at the
|
||||||
/// specified coordinates in the currently bound bitmap. </summary>
|
/// specified coordinates in the currently bound bitmap. </summary>
|
||||||
|
@ -75,6 +75,8 @@
|
|||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="2D\Drawing\GdiPlusDrawerFont.cs" />
|
||||||
|
<Compile Include="2D\Drawing\GdiPlusDrawerMCFont.cs" />
|
||||||
<Compile Include="2D\GuiElement.cs" />
|
<Compile Include="2D\GuiElement.cs" />
|
||||||
<Compile Include="2D\IsometricBlockDrawer.cs" />
|
<Compile Include="2D\IsometricBlockDrawer.cs" />
|
||||||
<Compile Include="2D\Drawing\DrawTextArgs.cs" />
|
<Compile Include="2D\Drawing\DrawTextArgs.cs" />
|
||||||
|
@ -99,7 +99,7 @@ namespace ClassicalSharp {
|
|||||||
InputHandler = new InputHandler( this );
|
InputHandler = new InputHandler( this );
|
||||||
Chat = new ChatLog( this );
|
Chat = new ChatLog( this );
|
||||||
Chat.FontSize = Options.GetInt( OptionsKey.FontSize, 6, 30, 12 );
|
Chat.FontSize = Options.GetInt( OptionsKey.FontSize, 6, 30, 12 );
|
||||||
Drawer2D = new GdiPlusDrawer2D( Graphics );
|
Drawer2D = new GdiPlusDrawerFont( Graphics );
|
||||||
defaultIb = Graphics.MakeDefaultIb();
|
defaultIb = Graphics.MakeDefaultIb();
|
||||||
MouseSensitivity = Options.GetInt( OptionsKey.Sensitivity, 1, 100, 30 );
|
MouseSensitivity = Options.GetInt( OptionsKey.Sensitivity, 1, 100, 30 );
|
||||||
BlockInfo = new BlockInfo();
|
BlockInfo = new BlockInfo();
|
||||||
|
@ -76,7 +76,7 @@ namespace Launcher2 {
|
|||||||
Window = new NativeWindow( 480, 480, Program.AppName, 0,
|
Window = new NativeWindow( 480, 480, Program.AppName, 0,
|
||||||
GraphicsMode.Default, DisplayDevice.Default );
|
GraphicsMode.Default, DisplayDevice.Default );
|
||||||
Window.Visible = true;
|
Window.Visible = true;
|
||||||
Drawer = new GdiPlusDrawer2D( null );
|
Drawer = new GdiPlusDrawerFont( null );
|
||||||
Init();
|
Init();
|
||||||
platformDrawer.Init( Window.WindowInfo );
|
platformDrawer.Init( Window.WindowInfo );
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user