Ejemplo n.º 1
0
        /// <summary>
        /// Repaint the control.
        /// </summary>
        /// <param name="zoomcenter">The point on which to center when zooming.</param>
        /// <param name="hdcDest">The DC handle to paint on.</param>
        private void Redraw(PointF zoomcenter, IntPtr hdcDest)
        {
#if MAC
            return;
#endif
            // no map loaded

            if (this.hdcSrcBackground == IntPtr.Zero)
            {
                Graphics gr = Graphics.FromHdc(hdcDest);
                try
                {
                    gr.Clear(Color.FromArgb(60, 60, 60));
                }
                catch { } // known bug in GDI: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=96873
                gr.Dispose();

                this.prevZoomFactor = this.zoomFactor;

                return;
            }


            // scale & letterbox

            this.Xout = false;
            this.Yout = false;

            if (this.Width > (fullWidth * this.zoomFactor))
            {
                this.rectSrc.X      = 0;
                this.rectSrc.Width  = fullWidth;
                this.rectDest.X     = (this.Width - (fullWidth * this.zoomFactor)) / 2F;
                this.rectDest.Width = fullWidth * this.zoomFactor;
                Gdi32.BitBlt(hdcDest, 0, 0, (int)Math.Round(this.rectDest.X), this.Height, this.hdcSrcBackground, 0, 0, Gdi32.TernaryRasterOperations.BLACKNESS);
                Gdi32.BitBlt(hdcDest, (int)Math.Round(this.rectDest.Right), 0, (int)Math.Round(this.rectDest.X), this.Height, this.hdcSrcBackground, 0, 0, Gdi32.TernaryRasterOperations.BLACKNESS);
            }
            else
            {
                this.rectSrc.X     += ((this.Width / this.prevZoomFactor) - (this.Width / this.zoomFactor)) / ((this.Width + 0.001F) / zoomcenter.X);
                this.rectSrc.Width  = this.Width / this.zoomFactor;
                this.rectDest.X     = 0;
                this.rectDest.Width = this.Width;
            }

            if (this.Height > (fullHeight * this.zoomFactor))
            {
                this.rectSrc.Y       = 0;
                this.rectSrc.Height  = fullHeight;
                this.rectDest.Y      = (this.Height - (fullHeight * this.zoomFactor)) / 2F;
                this.rectDest.Height = fullHeight * this.zoomFactor;
                Gdi32.BitBlt(hdcDest, 0, 0, this.Width, (int)Math.Round(this.rectDest.Y), this.hdcSrcBackground, 0, 0, Gdi32.TernaryRasterOperations.BLACKNESS);
                Gdi32.BitBlt(hdcDest, 0, (int)Math.Round(this.rectDest.Bottom), this.Width, (int)Math.Round(this.rectDest.Y), this.hdcSrcBackground, 0, 0, Gdi32.TernaryRasterOperations.BLACKNESS);
            }
            else
            {
                this.rectSrc.Y      += ((this.Height / this.prevZoomFactor) - (this.Height / this.zoomFactor)) / ((this.Height + 0.001F) / zoomcenter.Y);
                this.rectSrc.Height  = this.Height / this.zoomFactor;
                this.rectDest.Y      = 0;
                this.rectDest.Height = this.Height;
            }

            this.prevZoomFactor = this.zoomFactor;

            if (this.rectSrc.Right > fullWidth)
            {
                this.Xout      = true;
                this.rectSrc.X = fullWidth - this.rectSrc.Width;
            }
            if (this.rectSrc.X < 0)
            {
                this.Xout      = true;
                this.rectSrc.X = 0;
            }
            if (this.rectSrc.Bottom > fullHeight)
            {
                this.Yout      = true;
                this.rectSrc.Y = fullHeight - this.rectSrc.Height;
            }
            if (this.rectSrc.Y < 0)
            {
                this.Yout      = true;
                this.rectSrc.Y = 0;
            }


            // draw

            if (this.MapFastScaling)
            {
                Gdi32.SetStretchBltMode(hdcDest, Gdi32.StretchMode.STRETCH_DELETESCANS);
            }
            else
            {
                Gdi32.SetStretchBltMode(hdcDest, Gdi32.StretchMode.STRETCH_HALFTONE);
            }


            if (this.hdcSrcOverlay == IntPtr.Zero)
            {
                // no overlay, just draw resized

                Gdi32.StretchBlt(hdcDest,
                                 (int)Math.Round(rectDest.X),
                                 (int)Math.Round(rectDest.Y),
                                 (int)Math.Round(rectDest.Width),
                                 (int)Math.Round(rectDest.Height),
                                 this.hdcSrcBackground,
                                 (int)Math.Round(rectSrc.X),
                                 (int)Math.Round(rectSrc.Y),
                                 (int)Math.Round(rectSrc.Width),
                                 (int)Math.Round(rectSrc.Height),
                                 Gdi32.TernaryRasterOperations.SRCCOPY);
            }
            else
            {
                // overlay, create merged image and draw

                IntPtr hdcBuffer = Gdi32.CreateCompatibleDC(IntPtr.Zero);
                //Gdi32.SetStretchBltMode( hdcBuffer, Gdi32.StretchMode.STRETCH_HALFTONE );
                IntPtr hBmpBuffer = Gdi32.CreateCompatibleBitmap(hdcSrcBackground, (int)Math.Round(rectSrc.Width), (int)Math.Round(rectSrc.Height));
                Gdi32.SelectObject(hdcBuffer, hBmpBuffer);


                // copy background source rect into buffer

                Gdi32.BitBlt(hdcBuffer,
                             0,
                             0,
                             (int)Math.Round(rectSrc.Width),
                             (int)Math.Round(rectSrc.Height),
                             hdcSrcBackground,
                             (int)Math.Round(rectSrc.X),
                             (int)Math.Round(rectSrc.Y),
                             Gdi32.TernaryRasterOperations.SRCCOPY);


                // alpha blend overlay source rect into buffer

                Gdi32.AlphaBlend(hdcBuffer,
                                 0,
                                 0,
                                 (int)Math.Round(rectSrc.Width),
                                 (int)Math.Round(rectSrc.Height),
                                 hdcSrcOverlay,
                                 (int)Math.Round(rectSrc.X),
                                 (int)Math.Round(rectSrc.Y),
                                 (int)Math.Round(rectSrc.Width),
                                 (int)Math.Round(rectSrc.Height),
                                 new Gdi32.BLENDFUNCTION(Gdi32.AC_SRC_OVER, 0, 0xff, Gdi32.AC_SRC_ALPHA));


                // draw buffer to destination resized

                Gdi32.StretchBlt(hdcDest,
                                 (int)Math.Round(rectDest.X),
                                 (int)Math.Round(rectDest.Y),
                                 (int)Math.Round(rectDest.Width),
                                 (int)Math.Round(rectDest.Height),
                                 hdcBuffer,
                                 0, 0,
                                 (int)Math.Round(rectSrc.Width),
                                 (int)Math.Round(rectSrc.Height),
                                 Gdi32.TernaryRasterOperations.SRCCOPY);

                // clean up buffer

                Gdi32.DeleteDC(hdcBuffer);
                hdcBuffer = IntPtr.Zero;
                Gdi32.DeleteObject(hBmpBuffer);
                hBmpBuffer = IntPtr.Zero;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Load a new background map image into memory for display.
        /// </summary>
        /// <param name="image">The Bitmap to load (will be destroyed).</param>
        public void LoadMap(Bitmap image)
        {
            if (this.hdcSrcBackground != IntPtr.Zero)
            {
                Gdi32.DeleteDC(this.hdcSrcBackground);
                this.hdcSrcBackground = IntPtr.Zero;
                Gdi32.DeleteObject(this.hBmpSrcBackground);
                this.hBmpSrcBackground = IntPtr.Zero;

                Gdi32.DeleteDC(this.hdcSrcOverlay);
                this.hdcSrcOverlay = IntPtr.Zero;
                Gdi32.DeleteObject(this.hBmpSrcOverlay);
                this.hBmpSrcOverlay = IntPtr.Zero;
            }


            this.hdcSrcBackground = Gdi32.CreateCompatibleDC(IntPtr.Zero);
            if (this.hdcSrcBackground == IntPtr.Zero)
            {
                throw new ApplicationException("CreateCompatibleDC() failed");
            }

            this.hBmpSrcBackground = image.GetHbitmap();
            if (this.hBmpSrcBackground == IntPtr.Zero)
            {
                throw new ApplicationException("GetHbitmap() failed");
            }

            IntPtr ret = Gdi32.SelectObject(this.hdcSrcBackground, this.hBmpSrcBackground);

            if (ret == IntPtr.Zero)
            {
                throw new ApplicationException("SelectObject() failed");
            }


            Size newMapSize = new Size(image.Width, image.Height);

            this.fullHeight = newMapSize.Height;
            this.fullWidth  = newMapSize.Width;

            if (newMapSize != prevMapSize)       // recenter
            {
                PointF prevCenter = this.Center; // must have already called InitSize()
                this.Center = new PointF((prevCenter.X / prevMapSize.Width) * newMapSize.Width,
                                         (prevCenter.Y / prevMapSize.Height) * newMapSize.Height);

                this.prevMapSize = newMapSize;
            }


            image.Dispose();
            image = null;

            GC.Collect();


            // update map zoom

            this.Zoom();
        }