コード例 #1
0
        /// <summary>
        /// Frees a bitmap previously allocated with AllocateBitmap.
        /// </summary>
        /// <param name="handle">The handle that was returned from a previous call to AllocateBitmap.</param>
        /// <param name="width">The width of the bitmap, as specified in the original call to AllocateBitmap.</param>
        /// <param name="height">The height of the bitmap, as specified in the original call to AllocateBitmap.</param>
        public static void FreeBitmap(IntPtr handle, int width, int height)
        {
            long bytes = (long)width * (long)height * 4;

            bool bResult = SafeNativeMethods.DeleteObject(handle);

            if (!bResult)
            {
                NativeMethods.ThrowOnWin32Error("DeleteObject returned false");
            }

            if (bytes > 0)
            {
                GC.RemoveMemoryPressure(bytes);
            }
        }
コード例 #2
0
        /// <summary>
        /// Retrieves an array of rectangles that approximates a region, and computes the
        /// pixel area of it. This method is necessary to work around some bugs in .NET
        /// and to increase performance for the way in which we typically use this data.
        /// </summary>
        /// <param name="region">The Region to retrieve data from.</param>
        /// <param name="scans">An array of Rectangle to put the scans into.</param>
        /// <param name="area">An integer to write the computed area of the region into.</param>
        /// <remarks>
        /// Note to implementors: Simple implementations may simple call region.GetRegionScans()
        /// and process the data for the 'out' variables.</remarks>
        public static void GetRegionScans(Region region, out Rectangle[] scans, out int area)
        {
            using (NullGraphics nullGraphics = new NullGraphics())
            {
                IntPtr hRgn = IntPtr.Zero;

                try
                {
                    hRgn = region.GetHrgn(nullGraphics.Graphics);
                    GetRegionScans(hRgn, out scans, out area);
                }

                finally
                {
                    if (hRgn != IntPtr.Zero)
                    {
                        SafeNativeMethods.DeleteObject(hRgn);
                        hRgn = IntPtr.Zero;
                    }
                }
            }

            GC.KeepAlive(region);
        }
コード例 #3
0
        private static void FillRectanglesImpl(Graphics g, Color color, Rectangle[] rects)
        {
            uint nativeColor = (uint)(color.R + (color.G << 8) + (color.B << 16));

            IntPtr hdc       = IntPtr.Zero;
            IntPtr brush     = IntPtr.Zero;
            IntPtr oldObject = IntPtr.Zero;

            try
            {
                hdc   = g.GetHdc();
                brush = SafeNativeMethods.CreateSolidBrush(nativeColor);

                if (brush == IntPtr.Zero)
                {
                    NativeMethods.ThrowOnWin32Error("CreateSolidBrush returned NULL");
                }

                oldObject = SafeNativeMethods.SelectObject(hdc, brush);

                foreach (Rectangle rect in rects)
                {
                    NativeStructs.RECT nativeRect;

                    nativeRect.left   = rect.Left;
                    nativeRect.top    = rect.Top;
                    nativeRect.right  = rect.Right;
                    nativeRect.bottom = rect.Bottom;

                    int result = SafeNativeMethods.FillRect(hdc, ref nativeRect, brush);

                    if (result == 0)
                    {
                        NativeMethods.ThrowOnWin32Error("FillRect returned zero");
                    }
                }
            }

            finally
            {
                if (oldObject != IntPtr.Zero)
                {
                    SafeNativeMethods.SelectObject(hdc, oldObject);
                    oldObject = IntPtr.Zero;
                }

                if (brush != IntPtr.Zero)
                {
                    SafeNativeMethods.DeleteObject(brush);
                    brush = IntPtr.Zero;
                }

                if (hdc != IntPtr.Zero)
                {
                    g.ReleaseHdc(hdc);
                    hdc = IntPtr.Zero;
                }
            }

            GC.KeepAlive(g);
        }
コード例 #4
0
        private static void DrawPolyLineImpl(Graphics g, Color color, Point[] points)
        {
            if (points.Length < 1)
            {
                return;
            }

            uint nativeColor = (uint)(color.R + (color.G << 8) + (color.B << 16));

            IntPtr hdc       = IntPtr.Zero;
            IntPtr pen       = IntPtr.Zero;
            IntPtr oldObject = IntPtr.Zero;

            try
            {
                hdc = g.GetHdc();
                pen = SafeNativeMethods.CreatePen(NativeConstants.PS_SOLID, 1, nativeColor);

                if (pen == IntPtr.Zero)
                {
                    NativeMethods.ThrowOnWin32Error("CreatePen returned NULL");
                }

                oldObject = SafeNativeMethods.SelectObject(hdc, pen);

                NativeStructs.POINT pt;
                bool bResult = SafeNativeMethods.MoveToEx(hdc, points[0].X, points[0].Y, out pt);

                if (!bResult)
                {
                    NativeMethods.ThrowOnWin32Error("MoveToEx returned false");
                }

                for (int i = 1; i < points.Length; ++i)
                {
                    bResult = SafeNativeMethods.LineTo(hdc, points[i].X, points[i].Y);

                    if (!bResult)
                    {
                        NativeMethods.ThrowOnWin32Error("LineTo returned false");
                    }
                }
            }

            finally
            {
                if (oldObject != IntPtr.Zero)
                {
                    SafeNativeMethods.SelectObject(hdc, oldObject);
                    oldObject = IntPtr.Zero;
                }

                if (pen != IntPtr.Zero)
                {
                    SafeNativeMethods.DeleteObject(pen);
                    pen = IntPtr.Zero;
                }

                if (hdc != IntPtr.Zero)
                {
                    g.ReleaseHdc(hdc);
                    hdc = IntPtr.Zero;
                }
            }

            GC.KeepAlive(g);
        }
コード例 #5
0
        /// <summary>
        /// Measures text with the given graphics context, font, string, location, and anti-aliasing flag.
        /// </summary>
        /// <param name="g">The Graphics context to measure for.</param>
        /// <param name="font">The Font to measure with.</param>
        /// <param name="text">The string of text to measure.</param>
        /// <param name="antiAliasing">Whether the font should be rendered with anti-aliasing.</param>
        public static Size MeasureString(Graphics g, Font font, string text, bool antiAliasing, FontSmoothing fontSmoothing)
        {
            if (fontSmoothing == FontSmoothing.Smooth && antiAliasing)
            {
                PixelOffsetMode oldPOM = g.PixelOffsetMode;
                g.PixelOffsetMode = PixelOffsetMode.Half;

                TextRenderingHint oldTRH = g.TextRenderingHint;
                g.TextRenderingHint = TextRenderingHint.AntiAlias;

                StringFormat format = (StringFormat)StringFormat.GenericTypographic.Clone();
                format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;

                SizeF sf = g.MeasureString(text, font, new PointF(0, 0), format);
                sf.Height = font.GetHeight();

                g.PixelOffsetMode   = oldPOM;
                g.TextRenderingHint = oldTRH;
                return(Size.Ceiling(sf));
            }
            else if (fontSmoothing == FontSmoothing.Sharp || !antiAliasing)
            {
                IntPtr hdc        = IntPtr.Zero;
                IntPtr hFont      = IntPtr.Zero;
                IntPtr hOldObject = IntPtr.Zero;

                try
                {
                    hdc        = g.GetHdc();
                    hFont      = CreateFontObject(font, antiAliasing);
                    hOldObject = SafeNativeMethods.SelectObject(hdc, hFont);

                    NativeStructs.RECT rect = new NativeStructs.RECT();
                    rect.left   = 0;
                    rect.top    = 0;
                    rect.right  = rect.left;
                    rect.bottom = rect.top;

                    int result = SafeNativeMethods.DrawTextW(
                        hdc,
                        text,
                        text.Length,
                        ref rect,
                        NativeConstants.DT_CALCRECT |
                        NativeConstants.DT_LEFT |
                        NativeConstants.DT_NOCLIP |
                        NativeConstants.DT_NOPREFIX |
                        NativeConstants.DT_SINGLELINE |
                        NativeConstants.DT_TOP);

                    if (result == 0)
                    {
                        NativeMethods.ThrowOnWin32Error("DrawTextW returned 0");
                    }

                    return(new Size(rect.right - rect.left, rect.bottom - rect.top));
                }

                finally
                {
                    if (hOldObject != IntPtr.Zero)
                    {
                        SafeNativeMethods.SelectObject(hdc, hOldObject);
                        hOldObject = IntPtr.Zero;
                    }

                    if (hFont != IntPtr.Zero)
                    {
                        SafeNativeMethods.DeleteObject(hFont);
                        hFont = IntPtr.Zero;
                    }

                    if (hdc != IntPtr.Zero)
                    {
                        g.ReleaseHdc(hdc);
                        hdc = IntPtr.Zero;
                    }
                }
            }
            else
            {
                throw new InvalidEnumArgumentException("fontSmoothing = " + (int)fontSmoothing);
            }
        }