Ejemplo n.º 1
0
        /// <summary>
        /// Handles the paint.
        /// </summary>
        internal unsafe void HandlePaintEvent(IntPtr sourceBuffer, Rect rect, int dx, int dy, Rect scrollRect)
        {
            System.Drawing.Imaging.BitmapData sourceData;
            var clientRect = new Rectangle(rect.Left, rect.Top, rect.Width, rect.Height);
            byte[] TemporaryBuffer = null;

            if (dx != 0 || dy != 0)
            {
                var sourceRect = new Rectangle(scrollRect.Left, scrollRect.Top, scrollRect.Width, scrollRect.Height);
                var destRect = sourceRect;
                destRect.X += dx;
                destRect.Y += dy;

                // We want to only draw the overlapping portion of the scrolled and unscrolled
                //  rectangles, since the scrolled rectangle is probably partially offscreen
                var overlap = Rectangle.Intersect(destRect, sourceRect);

                // We need to handle scrolling to the left
                if (destRect.Left < 0)
                {
                    sourceRect.X -= destRect.Left;
                    destRect.X = 0;
                }
                // And upward
                if (destRect.Top < 0)
                {
                    sourceRect.Y -= destRect.Top;
                    destRect.Y = 0;
                }

                destRect.Width = sourceRect.Width = overlap.Width;
                destRect.Height = sourceRect.Height = overlap.Height;

                // If the clipping calculations resulted in a rect that contains zero pixels,
                //  don't bother trying to do the blit.
                if ((sourceRect.Width > 0) && (sourceRect.Height > 0))
                {
                    sourceData = WindowBitmap.LockBits(
                        sourceRect, System.Drawing.Imaging.ImageLockMode.ReadOnly,
                        System.Drawing.Imaging.PixelFormat.Format32bppRgb
                    );

                    int totalSize = sourceData.Stride * sourceData.Height;

                    if ((TemporaryBuffer == null) || (totalSize > TemporaryBuffer.Length))
                        TemporaryBuffer = new byte[totalSize];

                    Marshal.Copy(sourceData.Scan0, TemporaryBuffer, 0, totalSize);
                    WindowBitmap.UnlockBits(sourceData);

                    fixed (byte* ptr = &(TemporaryBuffer[0]))
                    {
                        sourceData.Scan0 = new IntPtr(ptr);

                        var destData = WindowBitmap.LockBits(
                            destRect, System.Drawing.Imaging.ImageLockMode.WriteOnly | System.Drawing.Imaging.ImageLockMode.UserInputBuffer,
                            System.Drawing.Imaging.PixelFormat.Format32bppRgb, sourceData
                        );

                        WindowBitmap.UnlockBits(destData);
                    }

                    InvalidateBerkelium();
                }
            }

            // If we get a paint event after a resize, the rect can be larger than the buffer.
            if ((clientRect.Right > WindowBitmap.Width) || (clientRect.Bottom > WindowBitmap.Height))
                return;

            sourceData = new System.Drawing.Imaging.BitmapData();
            sourceData.Width = clientRect.Width;
            sourceData.Height = clientRect.Height;
            sourceData.PixelFormat = System.Drawing.Imaging.PixelFormat.Format32bppRgb;
            sourceData.Stride = clientRect.Width * 4;
            sourceData.Scan0 = sourceBuffer;

            // Sometimes this can fail if we process an old paint event after we
            //  request a resize, so we just eat the exception in that case.
            // Yes, this is terrible.
            //Bitmap windowBitmap = new Bitmap(clientRect.Width, clientRect.Height);
            try
            {
                // This oddball form of LockBits performs a write to the bitmap's
                //  internal buffer by copying from another BitmapData you pass in.
                // In this case we're passing in the source buffer.
                var bd = WindowBitmap.LockBits(
                    clientRect,
                    System.Drawing.Imaging.ImageLockMode.WriteOnly | System.Drawing.Imaging.ImageLockMode.UserInputBuffer,
                    System.Drawing.Imaging.PixelFormat.Format32bppRgb, sourceData
                );

                // For some reason we still have to unlock the bits afterward.
                WindowBitmap.UnlockBits(bd);

                InvalidateBerkelium();
            }
            catch
            {
            }
        }
Ejemplo n.º 2
0
 private void WebKit_Paint(Berkelium.Managed.Window window, IntPtr sourceBuffer, Rect rect, int dx, int dy, Rect scrollRect)
 {
     HandlePaintEvent(sourceBuffer, rect, dx, dy, scrollRect);
 }