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;
            }
        }
Exemple #4
0
        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;
 }
Exemple #7
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;
 }
Exemple #13
0
        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;
        }
Exemple #16
0
 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);
 }
Exemple #20
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 );
            }
        }
Exemple #30
0
        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;
            }
        }
Exemple #32
0
        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();
            }
        }