pixelbuffer.cs

来自「Fireball.CodeEditor is an source code ed」· CS 代码 · 共 1,714 行 · 第 1/4 页

CS
1,714
字号
            if (y < 0)
            {
                sy = 0;
                sh += y;
            }
            else if ((y + height) > _height)
            {
                sh = _height - y;
            }

            if (sw <= 0 || sh <= 0)
            {
                return;
            }

            fixed (int* dest = _buffer)
            {
                BlendBufferRectColor(dest, color, sx, sy, sw, sh);
            }

        }
        private unsafe int CountColor(int* buff, int color)
        {
            int count = 0;
            for (int i = 0; i < _pixelsCount; i++)
            {
                if (*((int*)buff) == color)
                {
                    count++;
                }
            }
            return count;
        }
        private unsafe int ChangeColor(int* buff, int oldColor, int newColor)
        {
            int count = 0;
            for (int i = 0; i < _pixelsCount; i++)
            {
                if (*((int*)buff) == oldColor)
                {
                    *((int*)buff) = newColor;
                    count++;
                }
            }
            return count;
        }
        private bool ClipRect(ref int x, ref int y, ref int w, ref int h, int width, int height)
        {
            if (x >= width) return false;
            if (y >= height) return false;
            if ((x + w) <= 0) return false;
            if ((y + h) <= 0) return false;

            if ((x + w) > width) w = width - x;
            if ((y + h) > height) h = height - y;

            if (x < 0)
            {
                w += x;
                x = 0;
            }
            if (y < 0)
            {
                h += y;
                y = 0;
            }

            return true;
        }
        private unsafe void CopyBitmapToBuffer(Bitmap bmp)
        {
            BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, _width, _height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            int* src = (int*)bmpData.Scan0;

            fixed (int* dest = _buffer)
            {
                CopyBuffer(dest, src, _buffer.Length);
            }

            bmp.UnlockBits(bmpData);
        }
        private unsafe void CopyBuffer(int* dest, int* src, int lenght)
        {
            for (int i = 0; i < lenght; i++)
            {
                *((int*)dest) = *((int*)src);
                dest++;
                src++;
            }
        }
        private unsafe void CopyBufferRect(int* dest, int* src, int x, int y, int width, int height)
        {
            int lineOffset = (_width - width);
            int start = GetPixelBytesIndex(x, y,_width);
            src += start;

            for (int iy = 0; iy < height; iy++)
            {
                for (int ix = 0; ix < width; ix++)
                {
                    *((int*)dest) = *((int*)src);
                    dest++;
                    src++;
                }
                src += lineOffset;
            }
        }
        private unsafe Bitmap CopyBufferToBitmap()
        {
            Bitmap bmp = new Bitmap(_width, _height, PixelFormat.Format32bppArgb);
            BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, _width, _height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
            int* dest = (int*)bmpData.Scan0;

            fixed (int* src = _buffer)
            {
                CopyBuffer(dest, src, _buffer.Length);
            }

            bmp.UnlockBits(bmpData);
            return bmp;
        }
        private unsafe void FillZeroBuffer(int* buff)
        {
            SetBufferColor(buff, 0);
        }
        private unsafe void FlipBufferBoth(int* src, int* dest)
        {
            dest += GetPixelBytesIndex(_width - 1, _height - 1, _width);
            for (int y = 0; y < _height; y++)
            {
                for (int x = 0; x < _width; x++)
                {
                    *((int*)dest) = *((int*)src);
                    src++;
                    dest--;
                }
            }
        }
        private unsafe void FlipBufferHorizontal(int* src, int* dest)
        {
            for (int y = 0; y < _height; y++)
            {
                dest += _width - 1;
                for (int x = 0; x < _width; x++)
                {
                    *((int*)dest) = *((int*)src);
                    src++;
                    dest--;
                }
                dest += _width + 1;
            }
        }
        private unsafe void FlipBufferVertical(int* src, int* dest)
        {
            dest += GetPixelBytesIndex(0, _height - 1,_width);
            for (int y = 0; y < _height; y++)
            {
                for (int x = 0; x < _width; x++)
                {
                    *((int*)dest) = *((int*)src);
                    src++;
                    dest++;
                }
                dest -= _width * 2;
            }
        }
        private unsafe int[] GetBufferColorArray(int* src)
        {
            int[] colors = new int[_pixelsCount];
            for (int i = 0; i < _pixelsCount; i++)
            {
                colors[i] = *((int*)src);
                src++;
            }
            return colors;
        }
        private unsafe int[] GetBufferUsedColorArray(int* src)
        {
            LightCollection<int> colors = new LightCollection<int>();
            for (int i = 0; i < _pixelsCount; i++)
            {
                int c = *((int*)src);
                if (!colors.Contains(c))
                {
                    colors.Add(c);
                }
                src++;
            }
            return colors.GetItems();
        }
        private int GetPixelBytesIndex(int x, int y,int width)
        {
            return ((width * y) + x);
        }
        private unsafe int GetPixelColorByIndex(int* buff, int index)
        {
            buff += index;
            int i = *((int*)buff);

            return i;
        }
        private unsafe PixelBuffer GetSubBufferOutside(int x, int y, int width, int height)
        {
            PixelBuffer retBuff = new PixelBuffer(width, height);

            int sx = x;
            int sy = y;
            int sw = width;
            int sh = height;

            if (x < 0)
            {
                sx = 0;
                sw += x;
            }
            else if ((x + width) > _width)
            {
                sw = _width - x;
            }

            if (y < 0)
            {
                sy = 0;
                sh += y;
            }
            else if ((y + height) > _height)
            {
                sh = _height - y;
            }

            if (sw <= 0 || sh <= 0)
            {
                return new PixelBuffer(width,height);
            }

            int defaultColor = 0;
            fixed (int* src = _buffer)
            {
                int index = this.GetPixelBytesIndex(sx, sy, _width);
                defaultColor = this.GetPixelColorByIndex(src, index);
            }

            fixed (int* dest = retBuff.InternalBuffer)
            {
                retBuff.SetBufferColor(dest, defaultColor);
            }

            using (PixelBuffer subBuff = this.GetSubBuffer(sx, sy, sw, sh))
            {
                int fx = 0;
                int fy = 0;
                if (x < 0) fx = -x;
                if (y < 0) fy = -y;

                retBuff.SetSubBuffer(subBuff, fx, fy);
            }

            return retBuff;
        }
        private unsafe void InvertBufferRGB(int* src)
        {
            for (int i = 0; i < _pixelsCount; i++)
            {
                int color = *src;
                int b = 255 - (color & 0xff);
                int g = 255 - ((color >> 8) & 0xff);
                int r = 255 - ((color >> 16) & 0xff);
                int a = (color >> 24) & 0xff;
                *src = ((a << 24) | (r << 16) | (g << 8) | b);
                src++;
            }
        }
        private unsafe void SetPixelColorByIndex(int* buff, int index, int color)
        {
            buff += index;
            *((int*)buff) = color;
        }
        private unsafe void SetPixels(int* buff, int index, int* offsets, int offsetsCount, int color)
        {
            buff += index;
            for (int i = 0; i < (offsetsCount+1); i++)
            {
                *buff = color;
                buff += *offsets;
                offsets++;
            }
        }
        private unsafe void SetBufferColor(int* buff, int color)
        {
            for (int i = 0; i < _pixelsCount; i++)
            {
                *((int*)buff) = color;
                buff++;
            }
        }
        private unsafe void SetBufferRectBuffer(int* dest, int* src, int x, int y, int width, int height)
        {
            int lineOffset = (_width - width);
            int start = GetPixelBytesIndex(x, y, _width);
            dest += start;

            for (int iy = 0; iy < height; iy++)
            {
                for (int ix = 0; ix < width; ix++)
                {
                    *((int*)dest) = *((int*)src);
                    dest++;
                    src++;
                }
                dest += lineOffset;
            }
        }
        private unsafe void SetBufferRectBufferOutside(int[] srcBuffer, int x, int y, int width, int height)
        {
            int sx = 0;
            int sy = 0;
            int sw = width;
            int sh = height;

            if (x < 0)
            {
                sx = -x;
                sw += x;
            }
            else if ((x + width) > _width)
            {
                sx = 0;
                sw = _width - x;
            }

            if (y < 0)
            {
                sy = -y;
                sh += y;
            }
            else if ((y + height) > _height)
            {
                sy = 0;
                sh = _height - y;
            }

            if (sw <= 0 || sh <= 0)
            {
                return;
            }

            //TODO: problema con l'indice del pixel di un buffer senza istanza
            //
            //int[] blitBufferArray = new int[sw * sh];
            //fixed (int* src = srcBuffer)
            //{
            //    fixed (int* dest = blitBufferArray)
            //    {
            //        CopyBufferRect(dest, src, sx, sy, sw, sh);
            //    }
            //}
            PixelBuffer srcBufferHelper = new PixelBuffer(width, height, srcBuffer);
            PixelBuffer blitBufferArray = srcBufferHelper.GetSubBuffer(sx, sy, sw, sh);

            int fx = x;
            int fy = y;
            if (x < 0) fx = 0;
            if (y < 0) fy = 0;

            fixed (int* src = blitBufferArray.InternalBuffer)
            {
                fixed (int* dest = _buffer)
                {
                    SetBufferRectBuffer(dest, src, fx, fy, sw, sh);
                }
            }

            srcBufferHelper.Dispose();
            blitBufferArray.Dispose();
        }
        private unsafe void SetBufferRectColor(int* dest, int color, int x, int y, int width, int height)
        {
            int lineOffset = (_width - width);
            int start = GetPixelBytesIndex(x, y, _width);
            dest += start;

            for (int iy = 0; iy < height; iy++)
            {
                for (int ix = 0; ix < width; ix++)
                {
                    *((int*)dest) = color;
                    dest++;
                }
                dest += lineOffset;
            }
        }
        private unsafe void SetBufferRectColorOutside(int color, int x, int y, int width, int height)
        {
            int sx = x;
            int sy = y;
            int sw = width;
            int sh = height;

            if (x < 0)
            {
                sx = -x;
                sw += x;
            }
            else if ((x + width) > _width)
            {
                sx = 0;
                sw = _width - x;
            }

            if (y < 0)
            {
                sy = -y;
                sh += y;
            }
            else if ((y + height) > _height)
            {
                sy = 0;
                sh = _height - y;
            }

            if (sw <= 0 || sh <= 0)
            {
                return;
            }

            fixed (int* dest = _buffer)
            {
                SetBufferRectColor(dest, color, sx, sy, sw, sh);
            }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?