Exemplo n.º 1
0
        public void DrawTo(GR.Image.IImage TargetImage, int X, int Y, int SourceX, int SourceY, int DrawWidth, int DrawHeight)
        {
            // clip to source
            if ((SourceX >= Width) ||
                (SourceX + DrawWidth < 0) ||
                (SourceY >= Height) ||
                (SourceY + DrawHeight < 0))
            {
                return;
            }
            if (SourceX + DrawWidth > Width)
            {
                DrawWidth = Width - SourceX;
            }
            if (SourceX < 0)
            {
                DrawWidth += SourceX;
                X         += SourceX;
                SourceX    = 0;
            }
            if (SourceY + DrawHeight > Height)
            {
                DrawHeight = Height - SourceY;
            }
            if (SourceY < 0)
            {
                DrawHeight += SourceY;
                Y          += SourceY;
                SourceY     = 0;
            }

            int copyWidth  = DrawWidth;
            int copyHeight = DrawHeight;

            // clip to target
            if ((X >= TargetImage.Width) ||
                (Y >= TargetImage.Height) ||
                (X + copyWidth < 0) ||
                (Y + copyHeight < 0))
            {
                return;
            }

            if (X < 0)
            {
                SourceX   -= X;
                copyWidth += X;
                X          = 0;
            }
            if (X + copyWidth >= TargetImage.Width)
            {
                copyWidth = TargetImage.Width - X;
            }
            if (Y < 0)
            {
                SourceY    -= Y;
                copyHeight += Y;
                Y           = 0;
            }
            if (Y + copyHeight >= TargetImage.Height)
            {
                copyHeight = TargetImage.Height - Y;
            }

            if ((TargetImage.PixelFormat == PixelFormat) &&
                (BitsPerPixel >= 8))
            {
                unsafe
                {
                    byte *pTargetPos = (byte *)TargetImage.PinData();

                    pTargetPos += TargetImage.BytesPerLine * Y + X * TargetImage.BitsPerPixel / 8;

                    byte *pSourcePos = (byte *)PinData();

                    pSourcePos += BytesPerLine * SourceY + SourceX * BitsPerPixel / 8;
                    for (int y = 0; y < copyHeight; ++y)
                    {
                        CopyMemory(new IntPtr(pTargetPos), new IntPtr(pSourcePos), (uint)(copyWidth * BitsPerPixel / 8));

                        pTargetPos += TargetImage.BytesPerLine;
                        pSourcePos += BytesPerLine;
                    }
                    TargetImage.UnpinData();
                    UnpinData();
                }
            }
            else
            {
                // safe (but slow) copy
                for (int i = 0; i < copyWidth; ++i)
                {
                    for (int j = 0; j < copyHeight; ++j)
                    {
                        TargetImage.SetPixel(X + i, Y + j, GetPixel(SourceX + i, SourceY + j));
                    }
                }
            }
        }