We can manually ignore colour codes for the default.png text drawing backend, allocates less memory and optimises performance.

This commit is contained in:
UnknownShadow200 2016-04-11 14:42:59 +10:00
parent 3de395cb9f
commit c797909e76
4 changed files with 87 additions and 89 deletions

View File

@ -42,9 +42,6 @@ namespace ClassicalSharp {
FastBitmap bitmapWrapper = new FastBitmap();
public override void DrawBitmappedText( ref DrawTextArgs args, int x, int y ) {
if( !args.SkipPartsCheck )
GetTextParts( args.Text );
using( bitmapWrapper ) {
bitmapWrapper.SetData( curBmp, true, false );
DrawBitmappedTextImpl( bitmapWrapper, ref args, x, y );
@ -70,26 +67,7 @@ namespace ClassicalSharp {
}
public override Size MeasureBitmappedSize( ref DrawTextArgs args ) {
GetTextParts( args.Text );
if( parts.Count == 0 )
return Size.Empty;
float point = args.Font.Size;
Size total = new Size( 0, PtToPx( point, boxSize ) );
for( int i = 0; i < parts.Count; i++ ) {
foreach( char c in parts[i].Text ) {
int coords = ConvertToCP437( c );
total.X += PtToPx( point, widths[coords] + 1 );
}
}
if( args.Font.Style == FontStyle.Italic )
total.X += Utils.CeilDiv( total.Y, italicSize );
if( args.UseShadow ) {
int offset = ShadowOffset( args.Font.Size );
total.X += offset; total.Y += offset;
}
return total;
return MeasureBitmappedSizeImpl( ref args );
}
void DisposeText() {

View File

@ -70,9 +70,6 @@ namespace ClassicalSharp {
FastBitmap bitmapWrapper = new FastBitmap();
public override void DrawBitmappedText( ref DrawTextArgs args, int x, int y ) {
if( !args.SkipPartsCheck )
GetTextParts( args.Text );
using( bitmapWrapper ) {
bitmapWrapper.SetData( curBmp, true, false );
DrawBitmapTextImpl( bitmapWrapper, ref args, x, y );
@ -97,25 +94,7 @@ namespace ClassicalSharp {
}
public override Size MeasureBitmappedSize( ref DrawTextArgs args ) {
GetTextParts( args.Text );
if( parts.Count == 0 ) return Size.Empty;
float point = args.Font.Size;
Size total = new Size( 0, PtToPx( point, boxSize ) );
for( int i = 0; i < parts.Count; i++ ) {
foreach( char c in parts[i].Text ) {
int coords = ConvertToCP437( c );
total.Width += PtToPx( point, widths[coords] + 1 );
}
}
if( args.Font.Style == FontStyle.Italic )
total.Width += Utils.CeilDiv( total.Height, italicSize );
if( args.UseShadow ) {
int offset = ShadowOffset( args.Font.Size );
total.Width += offset; total.Height += offset;
}
return total;
return MeasureBitmappedSizeImpl( ref args );
}
void DisposeText() {

View File

@ -35,52 +35,51 @@ namespace ClassicalSharp {
void MakeTile( int i, int tileX, int tileY ) {
// find first column (from right) where there is a solid pixel
for( int x = boxSize - 1; x >= 0; x-- ) {
for( int y = 0; y < boxSize; y++ ) {
int pixel = fontPixels.GetRowPtr( tileY + y )[tileX + x];
byte a = (byte)(pixel >> 24);
if( a >= 127 ) { // found a solid pixel
widths[i] = x + 1;
return;
}
for( int x = boxSize - 1; x >= 0; x-- )
for( int y = 0; y < boxSize; y++ )
{
int pixel = fontPixels.GetRowPtr( tileY + y )[tileX + x];
byte a = (byte)(pixel >> 24);
if( a >= 127 ) { // found a solid pixel
widths[i] = x + 1;
return;
}
}
widths[i] = 0;
}
protected void DrawBitmapTextImpl( FastBitmap fastBmp, ref DrawTextArgs args, int x, int y ) {
protected void DrawBitmapTextImpl( FastBitmap dst, ref DrawTextArgs args, int x, int y ) {
bool underline = args.Font.Style == FontStyle.Underline;
if( args.UseShadow ) {
int offset = ShadowOffset( args.Font.Size );
int shadowX = x + offset, shadowY = y + offset;
for( int i = 0; i < parts.Count; i++ ) {
TextPart part = parts[i];
part.TextColour = FastColour.Black;
int orignX = shadowX;
DrawPart( fastBmp, args.Font, ref shadowX, shadowY, part );
if( underline )
DrawUnderline( fastBmp, part.TextColour, orignX, shadowX, 0, ref args );
}
}
for( int i = 0; i < parts.Count; i++ ) {
TextPart part = parts[i];
int orignX = x;
DrawPart( fastBmp, args.Font, ref x, y, part );
DrawPart( dst, ref args, ref shadowX, shadowY, true );
if( underline )
DrawUnderline( fastBmp, part.TextColour, orignX, x, -2, ref args );
DrawUnderline( dst, x + offset, 0, ref args, true );
}
int orignX = x;
DrawPart( dst, ref args, ref x, y, false );
if( underline )
DrawUnderline( dst, orignX, -2, ref args, false );
}
void DrawPart( FastBitmap dst, Font font, ref int x, int y, TextPart part ) {
string text = part.Text;
FastColour textCol = part.TextColour;
float point = font.Size;
int xMul = font.Style == FontStyle.Italic ? 1 : 0;
void DrawPart( FastBitmap dst, ref DrawTextArgs args, ref int x, int y, bool shadowCol ) {
FastColour textCol = FastColour.White;
float point = args.Font.Size;
int xMul = args.Font.Style == FontStyle.Italic ? 1 : 0;
string text = args.Text;
foreach( char c in text ) {
for( int i = 0; i < text.Length; i++ ) {
char c = text[i];
bool code = c == '&' && i < text.Length - 1;
if( code && ValidColour( text[i + 1] ) ) {
textCol = Colours[text[i + 1]];
i++; continue; // Skip over the colour code.
}
if( shadowCol ) textCol = FastColour.Black;
int coords = ConvertToCP437( c );
int srcX = (coords & 0x0F) * boxSize;
int srcY = (coords >> 4) * boxSize;
@ -94,18 +93,18 @@ namespace ClassicalSharp {
if( dstY >= dst.Height ) continue;
int* dstRow = dst.GetRowPtr( dstY );
int xOffset = xMul * ((dstHeight - 1 - yy) / italicSize);
int xOffset = xMul * ((dstHeight - 1 - yy) / italicSize);
for( int xx = 0; xx < dstWidth; xx++ ) {
int fontX = srcX + xx * srcWidth / dstWidth;
int pixel = fontRow[fontX];
if( (byte)(pixel >> 24) == 0 ) continue;
if( (byte)(pixel >> 24) == 0 ) continue;
int dstX = x + xx + xOffset;
if( dstX >= dst.Width ) continue;
int col = pixel & ~0xFFFFFF;
col |= ((pixel & 0xFF) * textCol.B / 255);
col |= (((pixel >> 8) & 0xFF) * textCol.G / 255) << 8;
col |= (((pixel >> 16) & 0xFF) * textCol.R / 255) << 16;
col |= (((pixel >> 16) & 0xFF) * textCol.R / 255) << 16;
dstRow[dstX] = col;
}
}
@ -113,21 +112,63 @@ namespace ClassicalSharp {
}
}
void DrawUnderline( FastBitmap fastBmp, FastColour textCol, int startX, int endX,
int yOffset, ref DrawTextArgs args ) {
void DrawUnderline( FastBitmap dst, int x, int yOffset, ref DrawTextArgs args, bool shadowCol ) {
int height = PtToPx( args.Font.Size, boxSize );
int offset = ShadowOffset( args.Font.Size );
int col = textCol.ToArgb();
if( args.UseShadow )
height += offset;
int col = FastColour.White.ToArgb();
float point = args.Font.Size;
string text = args.Text;
if( args.UseShadow ) height += offset;
for( int yy = height - offset; yy < height; yy++ ) {
int* dstRow = fastBmp.GetRowPtr( yy + yOffset );
for( int xx = startX; xx < endX; xx++ )
dstRow[xx] = col;
int* dstRow = dst.GetRowPtr( yy + yOffset );
int startX = x;
for( int i = 0; i < text.Length; i++ ) {
char c = text[i];
bool code = c == '&' && i < text.Length - 1;
if( code && ValidColour( text[i + 1] ) ) {
col = Colours[text[i + 1]].ToArgb();
i++; continue; // Skip over the colour code.
}
if( shadowCol ) col = FastColour.Black.ToArgb();
int coords = ConvertToCP437( c );
int width = PtToPx( point, widths[coords] + 1 );
for( int xx = 0; xx < width; xx++ )
dstRow[x + xx] = col;
x += width;
}
x = startX;
col = FastColour.White.ToArgb();
}
}
protected Size MeasureBitmappedSizeImpl( ref DrawTextArgs args ) {
if( String.IsNullOrEmpty( args.Text ) ) return Size.Empty;
float point = args.Font.Size;
Size total = new Size( 0, PtToPx( point, boxSize ) );
for( int i = 0; i < args.Text.Length; i++ ) {
char c = args.Text[i];
bool code = c == '&' && i < args.Text.Length - 1;
if( code && ValidColour( args.Text[i + 1] ) ) {
i++; continue; // Skip over the colour code.
}
int coords = ConvertToCP437( c );
total.Width += PtToPx( point, widths[coords] + 1 );
}
if( args.Font.Style == FontStyle.Italic )
total.Width += Utils.CeilDiv( total.Height, italicSize );
if( args.UseShadow ) {
int offset = ShadowOffset( args.Font.Size );
total.Width += offset; total.Height += offset;
}
return total;
}
protected static int ConvertToCP437( char c ) {
if( c >= ' ' && c <= '~')
return (int)c;

View File

@ -114,7 +114,7 @@ namespace ClassicalSharp {
Texture MakeTextureImpl( ref DrawTextArgs args, int windowX, int windowY, bool bitmapped ) {
Size size = bitmapped ? MeasureBitmappedSize( ref args ) : MeasureSize( ref args );
if( parts.Count == 0 )
if( size == Size.Empty )
return new Texture( -1, windowX, windowY, 0, 0, 1, 1 );
using( Bitmap bmp = CreatePow2Bitmap( size ) ) {