static unsafe void CopyScaledPixels( FastBitmap src, FastBitmap dst, Size scale, Rectangle srcRect, Rectangle dstRect, byte rgbScale) { int srcWidth = srcRect.Width, dstWidth = dstRect.Width; int srcHeight = srcRect.Height, dstHeight = dstRect.Height; int srcX = srcRect.X, dstX = dstRect.X; int srcY = srcRect.Y, dstY = dstRect.Y; int scaleWidth = scale.Width, scaleHeight = scale.Height; for( int yy = 0; yy < dstHeight; yy++ ) { int scaledY = yy * srcHeight / scaleHeight; int* srcRow = src.GetRowPtr( srcY + scaledY ); int* dstRow = dst.GetRowPtr( dstY + yy ); for( int xx = 0; xx < dstWidth; xx++ ) { int scaledX = xx * srcWidth / scaleWidth; int pixel = srcRow[srcX + scaledX]; int col = pixel & ~0xFFFFFF; // keep a but clear rgb col |= ((pixel & 0xFF) * rgbScale / 255); col |= (((pixel >> 8) & 0xFF) * rgbScale / 255) << 8; col |= (((pixel >> 16) & 0xFF) * rgbScale / 255) << 16; dstRow[dstX + xx] = col; } } }
public static unsafe void DrawScaledPixels( FastBitmap src, FastBitmap dst, Size scale, Rectangle srcRect, Rectangle dstRect, byte scaleA, byte scaleB) { int srcWidth = srcRect.Width, dstWidth = dstRect.Width; int srcHeight = srcRect.Height, dstHeight = dstRect.Height; int srcX = srcRect.X, dstX = dstRect.X; int srcY = srcRect.Y, dstY = dstRect.Y; int scaleWidth = scale.Width, scaleHeight = scale.Height; for( int yy = 0; yy < dstHeight; yy++ ) { int scaledY = (yy + dstY) * srcHeight / scaleHeight; int* srcRow = src.GetRowPtr( srcY + (scaledY % srcHeight) ); int* dstRow = dst.GetRowPtr( dstY + yy ); byte rgbScale = (byte)Utils.Lerp( scaleA, scaleB, (float)yy / dstHeight ); for( int xx = 0; xx < dstWidth; xx++ ) { int scaledX = (xx + dstX) * srcWidth / scaleWidth; int pixel = srcRow[srcX + (scaledX % srcWidth)]; int col = pixel & ~0xFFFFFF; // keep a, but clear rgb col |= ((pixel & 0xFF) * rgbScale / 255); col |= (((pixel >> 8) & 0xFF) * rgbScale / 255) << 8; col |= (((pixel >> 16) & 0xFF) * rgbScale / 255) << 16; dstRow[dstX + xx] = col; } } }
void DrawRun(FastBitmap dst, int x, int y, int runCount, byte *coords, int point, FastColour col) { if (runCount == 0) { return; } int srcY = (coords[0] >> 4) * boxSize; int textHeight = AdjTextSize(point), cellHeight = CellSize(textHeight); // inlined xPadding so we don't need to call PaddedWidth int xPadding = Utils.CeilDiv(point, 8), yPadding = (cellHeight - textHeight) / 2; int startX = x; ushort *dstWidths = stackalloc ushort[runCount]; for (int i = 0; i < runCount; i++) { dstWidths[i] = (ushort)Width(point, widths[coords[i]]); } for (int yy = 0; yy < textHeight; yy++) { int fontY = srcY + yy * boxSize / textHeight; int *fontRow = fontPixels.GetRowPtr(fontY); int dstY = y + (yy + yPadding); if (dstY >= dst.Height) { return; } int *dstRow = dst.GetRowPtr(dstY); for (int i = 0; i < runCount; i++) { int srcX = (coords[i] & 0x0F) * boxSize; int srcWidth = widths[coords[i]], dstWidth = dstWidths[i]; for (int xx = 0; xx < dstWidth; xx++) { int fontX = srcX + xx * srcWidth / dstWidth; int src = fontRow[fontX]; if ((byte)(src >> 24) == 0) { continue; } int dstX = x + xx; if (dstX >= dst.Width) { break; } int pixel = src & ~0xFFFFFF; pixel |= ((src & 0xFF) * col.B / 255); pixel |= (((src >> 8) & 0xFF) * col.G / 255) << 8; pixel |= (((src >> 16) & 0xFF) * col.R / 255) << 16; dstRow[dstX] = pixel; } x += dstWidth + xPadding; } x = startX; } }
static void CheckShadowTexture(IGraphicsApi graphics) { if (shadowTex != -1) { return; } const int size = 128, half = size / 2; using (Bitmap bmp = new Bitmap(size, size)) using (FastBitmap fastBmp = new FastBitmap(bmp, true, false)) { int inPix = new FastColour(0, 0, 0, 200).ToArgb(); int outPix = inPix & 0xFFFFFF; for (int y = 0; y < fastBmp.Height; y++) { int *row = fastBmp.GetRowPtr(y); for (int x = 0; x < fastBmp.Width; x++) { double dist = (half - (x + 0.5)) * (half - (x + 0.5)) + (half - (y + 0.5)) * (half - (y + 0.5)); row[x] = dist < half * half ? inPix : outPix; } } shadowTex = graphics.CreateTexture(fastBmp); } }
public static void MovePortion( int srcX, int srcY, int dstX, int dstY, FastBitmap src, FastBitmap dst, int size ) { for( int y = 0; y < size; y++ ) { int* srcRow = src.GetRowPtr( srcY + y ); int* dstRow = dst.GetRowPtr( dstY + y ); for( int x = 0; x < size; x++ ) dstRow[dstX + x] = srcRow[srcX + x]; } }
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; } } } widths[i] = 0; }
public static void CopyRow(int srcY, int dstY, FastBitmap src, FastBitmap dst, int width) { int *srcRow = src.GetRowPtr(srcY), dstRow = dst.GetRowPtr(dstY); for (int x = 0; x < width; x++) { dstRow[x] = srcRow[x]; } }
public static void MovePortion( int srcX, int srcY, int dstX, int dstY, FastBitmap src, FastBitmap dst, int size ) { for( int y = 0; y < size; y++ ) { int* srcRow = src.GetRowPtr( srcY + y ); int* dstRow = dst.GetRowPtr( dstY + y ); for( int x = 0; x < size; x++ ) dstRow[dstX + x] = srcRow[srcX + x]; } }
unsafe float GetSpriteBB_RightX( int size, int tileX, int tileY, FastBitmap fastBmp ) { for( int x = size - 1; x >= 0; x-- ) { for( int y = 0; y < size; y++ ) { int* row = fastBmp.GetRowPtr( tileY * size + y ) + (tileX * size); if( (row[x] & alphaTest) != 0 ) return (float)(x + 1) / size; } } return 0; }
unsafe float GetSpriteBB_TopY( int size, int tileX, int tileY, FastBitmap fastBmp ) { for( int y = 0; y < size; y++ ) { int* row = fastBmp.GetRowPtr( tileY * size + y ) + (tileX * size); for( int x = 0; x < size; x++ ) { if( (row[x] & alphaTest) != 0 ) return 1 - (float)y / size; } } return 0; }
unsafe float GetSpriteBB_BottomY( int size, int tileX, int tileY, FastBitmap fastBmp ) { for( int y = size - 1; y >= 0; y-- ) { int* row = fastBmp.GetRowPtr( tileY * size + y ) + (tileX * size); for( int x = 0; x < size; x++ ) { if( (row[x] & alphaTest) != 0 ) return 1 - (float)(y + 1) / size; } } return 1; }
unsafe float GetSpriteBB_LeftX( int size, int tileX, int tileY, FastBitmap fastBmp ) { for( int x = 0; x < size; x++ ) { for( int y = 0; y < size; y++ ) { int* row = fastBmp.GetRowPtr( tileY * size + y ) + (tileX * size); byte alpha = (byte)((row[x] & alphaTest) >> 24); if( alpha != 0 ) return (float)x / size; } } return 1; }
unsafe static void ClearHat(Bitmap bmp, SkinType skinType) { using (FastBitmap fastBmp = new FastBitmap(bmp, true, false)) { int sizeX = (bmp.Width / 64) * 32; int yScale = skinType == SkinType.Type64x32 ? 32 : 64; int sizeY = (bmp.Height / yScale) * 16; // determine if we actually need filtering for (int y = 0; y < sizeY; y++) { int *row = fastBmp.GetRowPtr(y); row += sizeX; for (int x = 0; x < sizeX; x++) { byte alpha = (byte)(row[x] >> 24); if (alpha != 255) { return; } } } // only perform filtering when the entire hat is opaque int fullWhite = FastColour.White.ToArgb(); int fullBlack = FastColour.Black.ToArgb(); for (int y = 0; y < sizeY; y++) { int *row = fastBmp.GetRowPtr(y); row += sizeX; for (int x = 0; x < sizeX; x++) { int pixel = row[x]; if (pixel == fullWhite || pixel == fullBlack) { row[x] = 0; } } } } }
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; int originX = x; foreach (char c in text) { int coords = ConvertToCP437(c); int srcX = (coords & 0x0F) * boxSize; int srcY = (coords >> 4) * boxSize; int srcWidth = widths[coords], dstWidth = PtToPx(point, srcWidth); int srcHeight = boxSize, dstHeight = PtToPx(point, srcHeight); for (int yy = 0; yy < dstHeight; yy++) { int fontY = srcY + yy * srcHeight / dstHeight; int *fontRow = fontPixels.GetRowPtr(fontY); int dstY = y + yy; if (dstY >= dst.Height) { continue; } int *dstRow = dst.GetRowPtr(dstY); 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; } 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; dstRow[dstX] = col; } } x += PtToPx(point, srcWidth + 1); } }
void CalculateTextWidths() { int width = fontPixels.Width, height = fontPixels.Height; for (int i = 0; i < widths.Length; i++) { widths[i] = 0; } // Iterate through each row in the bitmap for (int y = 0; y < height; y++) { int tileY = (y / boxSize); int *row = fontPixels.GetRowPtr(y); for (int x = 0; x < width; x += boxSize) { int tileX = (x / boxSize); // Iterate through each tile for (int xx = boxSize - 1; xx >= 0; xx--) { int pixel = row[x + xx]; byte a = (byte)(pixel >> 24); if (a < 127) { continue; } // Check if this is the pixel furthest to the right int index = (tileY << 4) | tileX; widths[index] = Math.Max(widths[index], xx + 1); break; } } } widths[' '] = boxSize / 4; }
unsafe float GetSpriteBB_LeftX(int size, int tileX, int tileY, FastBitmap fastBmp) { for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { int *row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size); if ((byte)(row[x] >> 24) != 0) { return((float)x / size); } } } return(1); }
unsafe static float GetSpriteBB_BottomY(int size, int tileX, int tileY, FastBitmap fastBmp) { for (int y = size - 1; y >= 0; y--) { int *row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size); for (int x = 0; x < size; x++) { if ((byte)(row[x] >> 24) != 0) { return(1 - (float)(y + 1) / size); } } } return(1); }
unsafe static float GetSpriteBB_RightX(int size, int tileX, int tileY, FastBitmap fastBmp) { for (int x = size - 1; x >= 0; x--) { for (int y = 0; y < size; y++) { int *row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size); if ((byte)(row[x] >> 24) != 0) { return((float)(x + 1) / size); } } } return(0); }
unsafe static float GetSpriteBB_TopY(int size, int tileX, int tileY, FastBitmap fastBmp) { for (int y = 0; y < size; y++) { int *row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size); for (int x = 0; x < size; x++) { if ((byte)(row[x] >> 24) != 0) { return(1 - (float)y / size); } } } return(0); }
void DrawUnderline(FastBitmap dst, ref DrawTextArgs args, int x, int y, bool shadow) { int point = Utils.Floor(args.Font.Size), dstHeight = point, startX = x; // adjust coords to make drawn text match GDI fonts int xPadding = Utils.CeilDiv(point, 8); int yPadding = (AdjHeight(dstHeight) - dstHeight) / 2; // scale up bottom row of a cell to drawn text font int startYY = (8 - 1) * dstHeight / 8; for (int yy = startYY; yy < dstHeight; yy++) { int dstY = y + (yy + yPadding); if (dstY >= dst.Height) { return; } int *dstRow = dst.GetRowPtr(dstY); PackedCol col = Cols['f']; string text = args.Text; for (int i = 0; i < text.Length; i++) { char c = text[i]; if (c == '&' && ValidColCode(text, i + 1)) { col = GetCol(text[i + 1]); i++; continue; // Skip over the colour code. } byte cur = Utils.UnicodeToCP437(c); int dstWidth = Width(point, cur); col = shadow ? PackedCol.Black : col; int argb = col.ToArgb(); for (int xx = 0; xx < dstWidth + xPadding; xx++) { if (x >= dst.Width) { break; } dstRow[x++] = argb; } } x = startX; } }
unsafe void PatchImage( Bitmap dstBitmap, Bitmap maskBitmap ) { using( FastBitmap dst = new FastBitmap( dstBitmap, true ), src = new FastBitmap( maskBitmap, true ) ) { int size = src.Width, tileSize = size / 16; for( int y = 0; y < size; y += tileSize ) { int* row = src.GetRowPtr( y ); for( int x = 0; x < size; x += tileSize ) { if( row[x] != unchecked((int)0x80000000) ) { FastBitmap.MovePortion( x, y, x, y, src, dst, tileSize ); } } } } }
public static unsafe void DrawTiledPixels( FastBitmap src, FastBitmap dst, Rectangle srcRect, Rectangle dstRect) { int srcX = srcRect.X, srcWidth = srcRect.Width, srcHeight = srcRect.Height; int dstX, dstY, dstWidth, dstHeight; if( !CheckCoords( dst, dstRect, out dstX, out dstY, out dstWidth, out dstHeight ) ) return; for( int yy = 0; yy < dstHeight; yy++ ) { // srcY is always 0 so we don't need to add int* srcRow = src.GetRowPtr( ((yy + dstY) % srcHeight) ); int* dstRow = dst.GetRowPtr( dstY + yy ); for( int xx = 0; xx < dstWidth; xx++ ) dstRow[dstX + xx] = srcRow[srcX + ((xx + dstX) % srcWidth)]; } }
void DrawUnderline(FastBitmap dst, int x, int yOffset, ref DrawTextArgs args, bool shadowCol) { int point = Utils.Floor(args.Font.Size); int padding = CellSize(point) - AdjTextSize(point); int height = AdjTextSize(point) + Utils.CeilDiv(padding, 2); int offset = ShadowOffset(args.Font.Size); int col = FastColour.White.ToArgb(); string text = args.Text; if (args.UseShadow) { height += offset; } int startX = x; for (int yy = height - offset; yy < height; yy++) { int *dstRow = dst.GetRowPtr(yy + yOffset); 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(); } }
void DrawUnderline(FastBitmap fastBmp, FastColour textCol, int startX, int endX, int yOffset, ref DrawTextArgs args) { int height = PtToPx(args.Font.Size, boxSize); int offset = ShadowOffset(args.Font.Size); int col = textCol.ToArgb(); 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; } } }
public static unsafe void DrawNoise( FastBitmap dst, Rectangle dstRect, FastColour col, int variation ) { int dstX, dstY, dstWidth, dstHeight; if( !CheckCoords( dst, dstRect, out dstX, out dstY, out dstWidth, out dstHeight ) ) return; const int alpha = 255 << 24; for( int yy = 0; yy < dstHeight; yy++ ) { int* row = dst.GetRowPtr( dstY + yy ); for( int xx = 0; xx < dstWidth; xx++ ) { int n = (dstX + xx) + (dstY + yy) * 57; n = (n << 13) ^ n; float noise = 1f - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824f; int r = col.R + (int)(noise * variation); r = r < 0 ? 0 : (r > 255 ? 255 : r); int g = col.G + (int)(noise * variation); g = g < 0 ? 0 : (g > 255 ? 255 : g); int b = col.B + (int)(noise * variation); b = b < 0 ? 0 : (b > 255 ? 255 : b); row[dstX + xx] = alpha | (r << 16) | (g << 8) | b; } } }
public static void CopyRow( int srcY, int dstY, FastBitmap src, FastBitmap dst, int width ) { int* srcRow = src.GetRowPtr( srcY ), dstRow = dst.GetRowPtr( dstY); for( int x = 0; x < width; x++ ) dstRow[x] = srcRow[x]; }
public static unsafe void FastClear( FastBitmap dst, Rectangle dstRect, FastColour col ) { int dstX, dstY, dstWidth, dstHeight; if( !CheckCoords( dst, dstRect, out dstX, out dstY, out dstWidth, out dstHeight ) ) return; int pixel = col.ToArgb(); for( int yy = 0; yy < dstHeight; yy++ ) { int* row = dst.GetRowPtr( dstY + yy ); for( int xx = 0; xx < dstWidth; xx++ ) row[dstX + xx] = pixel; } }
void DrawUnderline( FastBitmap fastBmp, FastColour textCol, int startX, int endX, int yOffset, ref DrawTextArgs args) { int height = PtToPx( args.Font.Size, boxSize ); int offset = ShadowOffset( args.Font.Size ); 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] = textCol.ToArgb(); } }
void DrawPart( FastBitmap fastBmp, 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; int originX = x; foreach( char c in text ) { int coords = ConvertToCP437( c ); int srcX = (coords & 0x0F) * boxSize; int srcY = (coords >> 4) * boxSize; int srcWidth = widths[coords], dstWidth = PtToPx( point, srcWidth ); int srcHeight = boxSize, dstHeight = PtToPx( point, srcHeight ); for( int yy = 0; yy < dstHeight; yy++ ) { int fontY = srcY + yy * srcHeight / dstHeight; int* fontRow = fontPixels.GetRowPtr( fontY ); int* dstRow = fastBmp.GetRowPtr( y + yy ); 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; 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; dstRow[x + xx + xOffset] = col; } } x += PtToPx( point, srcWidth + 1 ); } }
void DrawCore(FastBitmap dst, ref DrawTextArgs args, int x, int y, bool shadow) { PackedCol col = Cols['f']; if (shadow) { col = BlackTextShadows ? PackedCol.Black : PackedCol.Scale(col, 0.25f); } string text = args.Text; int point = Utils.Floor(args.Font.Size), count = 0; byte * coords = stackalloc byte[256]; PackedCol *cols = stackalloc PackedCol[256]; ushort * dstWidths = stackalloc ushort[256]; for (int i = 0; i < text.Length; i++) { char c = text[i]; if (c == '&' && ValidColCode(text, i + 1)) { col = GetCol(text[i + 1]); if (shadow) { col = BlackTextShadows ? PackedCol.Black : PackedCol.Scale(col, 0.25f); } i++; continue; // Skip over the colour code. } byte cur = Utils.UnicodeToCP437(c); coords[count] = cur; cols[count] = col; dstWidths[count] = (ushort)Width(point, cur); count++; } int dstHeight = point, startX = x; // adjust coords to make drawn text match GDI fonts int xPadding = Utils.CeilDiv(point, 8); int yPadding = (AdjHeight(dstHeight) - dstHeight) / 2; for (int yy = 0; yy < dstHeight; yy++) { int dstY = y + (yy + yPadding); if (dstY >= dst.Height) { return; } int fontY = 0 + yy * boxSize / dstHeight; int *dstRow = dst.GetRowPtr(dstY); for (int i = 0; i < count; i++) { int srcX = (coords[i] & 0x0F) * boxSize; int srcY = (coords[i] >> 4) * boxSize; int *fontRow = fontPixels.GetRowPtr(fontY + srcY); int srcWidth = widths[coords[i]], dstWidth = dstWidths[i]; col = cols[i]; for (int xx = 0; xx < dstWidth; xx++) { int fontX = srcX + xx * srcWidth / dstWidth; int src = fontRow[fontX]; if ((byte)(src >> 24) == 0) { continue; } int dstX = x + xx; if (dstX >= dst.Width) { break; } int pixel = src & ~0xFFFFFF; pixel |= ((src & 0xFF) * col.B / 255); pixel |= (((src >> 8) & 0xFF) * col.G / 255) << 8; pixel |= (((src >> 16) & 0xFF) * col.R / 255) << 16; dstRow[dstX] = pixel; } x += dstWidth + xPadding; } x = startX; } }
void DrawRun(FastBitmap dst, int x, int y, int xMul, int runCount, byte *coords, int point, FastColour col) { if (runCount == 0) { return; } int srcY = (coords[0] >> 4) * boxSize; int textHeight = AdjTextSize(point), cellHeight = CellSize(textHeight); int padding = (cellHeight - textHeight) / 2; int startX = x; ushort *dstWidths = stackalloc ushort[runCount]; for (int i = 0; i < runCount; i++) { dstWidths[i] = (ushort)PtToPx(point, widths[coords[i]]); } for (int yy = 0; yy < textHeight; yy++) { int fontY = srcY + yy * boxSize / textHeight; int *fontRow = fontPixels.GetRowPtr(fontY); int dstY = y + (yy + padding); if (dstY >= dst.Height) { return; } int *dstRow = dst.GetRowPtr(dstY); int xOffset = xMul * ((textHeight - 1 - yy) / italicSize); for (int i = 0; i < runCount; i++) { int srcX = (coords[i] & 0x0F) * boxSize; int srcWidth = widths[coords[i]], dstWidth = dstWidths[i]; for (int xx = 0; xx < dstWidth; xx++) { int fontX = srcX + xx * srcWidth / dstWidth; int src = fontRow[fontX]; if ((byte)(src >> 24) == 0) { continue; } int dstX = x + xx + xOffset; if (dstX >= dst.Width) { break; } int pixel = src & ~0xFFFFFF; pixel |= ((src & 0xFF) * col.B / 255); pixel |= (((src >> 8) & 0xFF) * col.G / 255) << 8; pixel |= (((src >> 16) & 0xFF) * col.R / 255) << 16; dstRow[dstX] = pixel; } x += PtToPx(point, srcWidth + 1); } x = startX; } }
static unsafe bool HasHat( Bitmap bmp, SkinType skinType ) { using( FastBitmap fastBmp = new FastBitmap( bmp, true ) ) { int sizeX = (bmp.Width / 64) * 32; int yScale = skinType == SkinType.Type64x32 ? 32 : 64; int sizeY = (bmp.Height / yScale) * 16; int fullWhite = FastColour.White.ToArgb(); int fullBlack = FastColour.Black.ToArgb(); for( int y = 0; y < sizeY; y++ ) { int* row = fastBmp.GetRowPtr( y ); row += sizeX; for( int x = 0; x < sizeX; x++ ) { int pixel = row[x]; if( !(pixel == fullWhite || pixel == fullBlack) ) { return true; } } } } return false; }
void DrawRun( FastBitmap dst, int x, int y, int xMul, string text, int runCount, byte* coords, int point, FastColour col) { if( runCount == 0 ) return; int srcY = (coords[0] >> 4) * boxSize; int textHeight = AdjTextSize( point ), cellHeight = CellSize( textHeight ); int padding = (cellHeight - textHeight) / 2; int startX = x; ushort* dstWidths = stackalloc ushort[runCount]; for( int i = 0; i < runCount; i++ ) dstWidths[i] = (ushort)PtToPx( point, widths[coords[i]] ); for( int yy = 0; yy < textHeight; yy++ ) { int fontY = srcY + yy * boxSize / textHeight; int* fontRow = fontPixels.GetRowPtr( fontY ); int dstY = y + (yy + padding); if( dstY >= dst.Height ) return; int* dstRow = dst.GetRowPtr( dstY ); int xOffset = xMul * ((textHeight - 1 - yy) / italicSize); for( int i = 0; i < runCount; i++ ) { int srcX = (coords[i] & 0x0F) * boxSize; int srcWidth = widths[coords[i]], dstWidth = dstWidths[i]; for( int xx = 0; xx < dstWidth; xx++ ) { int fontX = srcX + xx * srcWidth / dstWidth; int src = fontRow[fontX]; if( (byte)(src >> 24) == 0 ) continue; int dstX = x + xx + xOffset; if( dstX >= dst.Width ) break; int pixel = src & ~0xFFFFFF; pixel |= ((src & 0xFF) * col.B / 255); pixel |= (((src >> 8) & 0xFF) * col.G / 255) << 8; pixel |= (((src >> 16) & 0xFF) * col.R / 255) << 16; dstRow[dstX] = pixel; } x += PtToPx( point, srcWidth + 1 ); } x = startX; } }
void DrawUnderline( FastBitmap dst, int x, int yOffset, ref DrawTextArgs args, bool shadowCol ) { int point = Utils.Floor( args.Font.Size ); int padding = CellSize( point ) - AdjTextSize( point ); int height = AdjTextSize( point ) + Utils.CeilDiv(padding, 2); int offset = ShadowOffset( args.Font.Size ); int col = FastColour.White.ToArgb(); string text = args.Text; if( args.UseShadow ) height += offset; int startX = x; for( int yy = height - offset; yy < height; yy++ ) { int* dstRow = dst.GetRowPtr( yy + yOffset ); 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(); } }