コード例 #1
0
        public IntPtr SelectFont(WindowsFont font)
        {
            if (font.Equals(this.Font))
            {
                return(IntPtr.Zero);
            }
            IntPtr      ptr          = this.SelectObject(font.Hfont, GdiObjectType.Font);
            WindowsFont selectedFont = this.selectedFont;

            this.selectedFont = font;
            this.hCurrentFont = font.Hfont;
            if ((selectedFont != null) && MeasurementDCInfo.IsMeasurementDC(this))
            {
                selectedFont.Dispose();
            }
            if (MeasurementDCInfo.IsMeasurementDC(this))
            {
                if (ptr != IntPtr.Zero)
                {
                    MeasurementDCInfo.LastUsedFont = font;
                    return(ptr);
                }
                MeasurementDCInfo.Reset();
            }
            return(ptr);
        }
コード例 #2
0
 public void RestoreHdc()
 {
     IntUnsafeNativeMethods.RestoreDC(new HandleRef(this, this.hDC), -1);
     if (this.contextStack != null)
     {
         GraphicsState state = (GraphicsState)this.contextStack.Pop();
         this.hCurrentBmp   = state.hBitmap;
         this.hCurrentBrush = state.hBrush;
         this.hCurrentPen   = state.hPen;
         this.hCurrentFont  = state.hFont;
         if ((state.font != null) && state.font.IsAlive)
         {
             this.selectedFont = state.font.Target as WindowsFont;
         }
         else
         {
             WindowsFont selectedFont = this.selectedFont;
             this.selectedFont = null;
             if ((selectedFont != null) && MeasurementDCInfo.IsMeasurementDC(this))
             {
                 selectedFont.Dispose();
             }
         }
     }
     MeasurementDCInfo.ResetIfIsMeasurementDC(this.hDC);
 }
コード例 #3
0
        public float GetOverhangPadding(WindowsFont font)
        {
            WindowsFont font2 = font;

            if (font2 == null)
            {
                font2 = this.dc.Font;
            }
            float num = ((float)font2.Height) / 6f;

            if (font2 != font)
            {
                font2.Dispose();
            }
            return(num);
        }
コード例 #4
0
ファイル: DeviceContext2.cs プロジェクト: mairaw/winforms
        /// <summary>
        ///  Selects the specified object into the dc.  If the specified object is the same as the one currently selected
        ///  in the dc, the object is not set and a null value is returned.
        /// </summary>
        public IntPtr SelectFont(WindowsFont font)
        {
            // Fonts are one of the most expensive objects to select in an hdc and in many cases we are passed a Font that is the
            // same as the one already selected in the dc so to avoid a perf hit we get the hdc font's log font and compare it
            // with the one passed in before selecting it in the hdc.
            // Also, we avoid performing GDI operations that if done on an enhanced metafile DC would add an entry to it, hence
            // reducing the size of the metafile.
            if (font.Equals(Font))
            {
                return(IntPtr.Zero);
            }
            IntPtr result = SelectObject(font.Hfont, GdiObjectType.Font);

            WindowsFont previousFont = selectedFont;

            selectedFont = font;
            hCurrentFont = font.Hfont;

            // the measurement DC always leaves fonts selected for pref reasons.
            // in this case, we need to diposse the font since the original
            // creator didn't fully dispose.
            if (previousFont != null)
            {
                if (MeasurementDCInfo.IsMeasurementDC(this))
                {
                    previousFont.Dispose();
                }
            }

#if OPTIMIZED_MEASUREMENTDC
            // once we've changed the font, update the last used font.
            if (MeasurementDCInfo.IsMeasurementDC(this))
            {
                if (result != IntPtr.Zero)
                {
                    MeasurementDCInfo.LastUsedFont = font;
                }
                else
                {
                    // there was an error selecting the Font into the DC, we dont know anything about it.
                    MeasurementDCInfo.Reset();
                }
            }
#endif
            return(result);
        }
コード例 #5
0
        /// <summary>
        ///  Restores the device context to the specified state. The DC is restored by popping state information off a
        ///  stack created by earlier calls to the SaveHdc function.
        ///  The stack can contain the state information for several instances of the DC. If the state specified by the
        ///  specified parameter is not at the top of the stack, RestoreDC deletes all state information between the top
        ///  of the stack and the specified instance.
        ///  Specifies the saved state to be restored. If this parameter is positive, nSavedDC represents a specific
        ///  instance of the state to be restored. If this parameter is negative, nSavedDC represents an instance relative
        ///  to the current state. For example, -1 restores the most recently saved state.
        ///  See MSDN for more info.
        /// </summary>
        public void RestoreHdc()
        {
#if TRACK_HDC
            bool result =
#endif
            // Note: Don't use the Hdc property here, it would force handle creation.
            Gdi32.RestoreDC(new HandleRef(this, _hDC), -1);
#if TRACK_HDC
            // Note: Winforms may call this method during app exit at which point the DC may have been finalized already causing this assert to popup.
            Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("ret[0]=DC.RestoreHdc(hDc=0x{1:x8})", result, unchecked ((int)this.hDC))));
#endif
            Debug.Assert(_contextStack != null, "Someone is calling RestoreHdc() before SaveHdc()");

            if (_contextStack != null)
            {
                GraphicsState g = (GraphicsState)_contextStack.Pop();

                _hCurrentBmp   = g.hBitmap;
                _hCurrentBrush = g.hBrush;
                _hCurrentPen   = g.hPen;
                _hCurrentFont  = g.hFont;

                if (g.font != null && g.font.IsAlive)
                {
                    ActiveFont = g.font.Target as WindowsFont;
                }
                else
                {
                    WindowsFont previousFont = ActiveFont;
                    ActiveFont = null;
                    if (previousFont != null && MeasurementDCInfo.IsMeasurementDC(this))
                    {
                        previousFont.Dispose();
                    }
                }
            }

#if OPTIMIZED_MEASUREMENTDC
            // in this case, GDI will copy back the previously saved font into the DC.
            // we dont actually know what the font is in our measurement DC so
            // we need to clear it off.
            MeasurementDCInfo.ResetIfIsMeasurementDC(_hDC);
#endif
        }
コード例 #6
0
        /// <summary>
        ///  Calculates the spacing required for drawing text w/o clipping parts of a glyph.
        /// </summary>
        public float GetOverhangPadding(WindowsFont font)
        {
            // Some parts of a glyphs may be clipped depending on the font & font style, GDI+ adds 1/6 of tmHeight
            // to each size of the text bounding box when drawing text to account for that; we do it here as well.

            WindowsFont tmpfont = font;

            if (tmpfont == null)
            {
                tmpfont = DeviceContext.Font;
            }

            float overhangPadding = tmpfont.Height / 6f;

            if (tmpfont != font)
            {
                tmpfont.Dispose();
            }

            return(overhangPadding);
        }
コード例 #7
0
ファイル: DeviceContext2.cs プロジェクト: mairaw/winforms
        internal void DisposeFont(bool disposing)
        {
            if (disposing)
            {
                DeviceContexts.RemoveDeviceContext(this);
            }

            if (selectedFont != null && selectedFont.Hfont != IntPtr.Zero)
            {
                IntPtr hCurrentFont = Interop.Gdi32.GetCurrentObject(new HandleRef(this, hDC), Interop.Gdi32.ObjectType.OBJ_FONT);
                if (hCurrentFont == selectedFont.Hfont)
                {
                    // select initial font back in
                    Interop.Gdi32.SelectObject(new HandleRef(this, Hdc), hInitialFont);
                    hCurrentFont = hInitialFont;
                }

                selectedFont.Dispose(disposing);
                selectedFont = null;
            }
        }
コード例 #8
0
        public static WindowsFont GetWindowsFont(Font font, Interop.Gdi32.QUALITY fontQuality)
        {
            if (font == null)
            {
                return(null);
            }

            // First check if font is in the cache.

            int count = 0;
            int index = currentIndex;

            // Search by index of most recently added object.
            while (count < WindowsFontCache.Count)
            {
                if (WindowsFontCache[index].Key.Equals(font))  // don't do shallow comparison, we could miss cloned fonts.
                {
                    // We got a Font in the cache, let's see if we have a WindowsFont with the same quality as required by the caller.

                    // WARNING: It is not expected that the WindowsFont is disposed externally since it is created by this class.
                    Debug.Assert(WindowsFontCache[index].Value.Hfont != IntPtr.Zero, "Cached WindowsFont was disposed, enable GDI_FINALIZATION_WATCH to track who did it!");

                    WindowsFont wf = WindowsFontCache[index].Value;
                    if (wf.Quality == fontQuality)
                    {
                        return(wf);
                    }
                }

                index--;
                count++;

                if (index < 0)
                {
                    index = CacheSize - 1;
                }
            }

            // Font is not in the cache, let's add it.

            WindowsFont winFont = WindowsFont.FromFont(font, fontQuality);
            KeyValuePair <Font, WindowsFont> newEntry = new KeyValuePair <Font, WindowsFont>(font, winFont);

            currentIndex++;

            if (currentIndex == CacheSize)
            {
                currentIndex = 0;
            }

            if (WindowsFontCache.Count == CacheSize)  // No more room, update current index.
            {
                WindowsFont wfont = null;

                // Go through the existing fonts in the cache, and see if any
                // are not in use by a DC.  If one isn't, replace that.  If
                // all are in use, new up a new font and do not cache it.

                bool finished   = false;
                int  startIndex = currentIndex;
                int  loopIndex  = startIndex + 1;
                while (!finished)
                {
                    if (loopIndex >= CacheSize)
                    {
                        loopIndex = 0;
                    }

                    if (loopIndex == startIndex)
                    {
                        finished = true;
                    }

                    wfont = WindowsFontCache[loopIndex].Value;
                    if (!DeviceContexts.IsFontInUse(wfont))
                    {
                        currentIndex = loopIndex;
                        finished     = true;
                        break;
                    }
                    else
                    {
                        loopIndex++;
                        wfont = null;
                    }
                }

                if (wfont != null)
                {
                    WindowsFontCache[currentIndex] = newEntry;
                    winFont.OwnedByCacheManager    = true;

#if GDI_FONT_CACHE_TRACK
                    Debug.WriteLine("Removing from cache: " + wfont);
                    Debug.WriteLine("Adding to cache: " + winFont);
#endif

                    wfont.OwnedByCacheManager = false;
                    wfont.Dispose();
                }
                else
                {
                    // do not cache font - caller is ALWAYS responsible for
                    // disposing now.  If it is owned  by the CM, it will not
                    // disposed.

                    winFont.OwnedByCacheManager = false;

#if GDI_FONT_CACHE_TRACK
                    Debug.WriteLine("Creating uncached font: " + winFont);
#endif
                }
            }
            else
            {
                winFont.OwnedByCacheManager = true;
                WindowsFontCache.Add(newEntry);

#if GDI_FONT_CACHE_TRACK
                Debug.WriteLine("Adding to cache: " + winFont);
#endif
            }
            return(winFont);
        }
コード例 #9
0
        public static WindowsFont GetWindowsFont(Font font, WindowsFontQuality fontQuality)
        {
            if (font == null)
            {
                return(null);
            }
            int num          = 0;
            int currentIndex = WindowsGraphicsCacheManager.currentIndex;

            while (num < WindowsFontCache.Count)
            {
                KeyValuePair <Font, WindowsFont> pair2 = WindowsFontCache[currentIndex];
                if (pair2.Key.Equals(font))
                {
                    KeyValuePair <Font, WindowsFont> pair3 = WindowsFontCache[currentIndex];
                    WindowsFont font2 = pair3.Value;
                    if (font2.Quality == fontQuality)
                    {
                        return(font2);
                    }
                }
                currentIndex--;
                num++;
                if (currentIndex < 0)
                {
                    currentIndex = 9;
                }
            }
            WindowsFont font3 = WindowsFont.FromFont(font, fontQuality);
            KeyValuePair <Font, WindowsFont> item = new KeyValuePair <Font, WindowsFont>(font, font3);

            WindowsGraphicsCacheManager.currentIndex++;
            if (WindowsGraphicsCacheManager.currentIndex == 10)
            {
                WindowsGraphicsCacheManager.currentIndex = 0;
            }
            if (WindowsFontCache.Count != 10)
            {
                font3.OwnedByCacheManager = true;
                WindowsFontCache.Add(item);
                return(font3);
            }
            WindowsFont wf   = null;
            bool        flag = false;
            int         num3 = WindowsGraphicsCacheManager.currentIndex;
            int         num4 = num3 + 1;

            while (!flag)
            {
                if (num4 >= 10)
                {
                    num4 = 0;
                }
                if (num4 == num3)
                {
                    flag = true;
                }
                KeyValuePair <Font, WindowsFont> pair4 = WindowsFontCache[num4];
                wf = pair4.Value;
                if (!DeviceContexts.IsFontInUse(wf))
                {
                    WindowsGraphicsCacheManager.currentIndex = num4;
                    flag = true;
                    break;
                }
                num4++;
                wf = null;
            }
            if (wf != null)
            {
                WindowsFontCache[WindowsGraphicsCacheManager.currentIndex] = item;
                font3.OwnedByCacheManager = true;
                wf.OwnedByCacheManager    = false;
                wf.Dispose();
                return(font3);
            }
            font3.OwnedByCacheManager = false;
            return(font3);
        }
コード例 #10
0
 public IntPtr SelectFont(WindowsFont font)
 {
     if (font.Equals(this.Font))
     {
         return IntPtr.Zero;
     }
     IntPtr ptr = this.SelectObject(font.Hfont, GdiObjectType.Font);
     WindowsFont selectedFont = this.selectedFont;
     this.selectedFont = font;
     this.hCurrentFont = font.Hfont;
     if ((selectedFont != null) && MeasurementDCInfo.IsMeasurementDC(this))
     {
         selectedFont.Dispose();
     }
     if (MeasurementDCInfo.IsMeasurementDC(this))
     {
         if (ptr != IntPtr.Zero)
         {
             MeasurementDCInfo.LastUsedFont = font;
             return ptr;
         }
         MeasurementDCInfo.Reset();
     }
     return ptr;
 }
コード例 #11
0
 public void RestoreHdc()
 {
     IntUnsafeNativeMethods.RestoreDC(new HandleRef(this, this.hDC), -1);
     if (this.contextStack != null)
     {
         GraphicsState state = (GraphicsState) this.contextStack.Pop();
         this.hCurrentBmp = state.hBitmap;
         this.hCurrentBrush = state.hBrush;
         this.hCurrentPen = state.hPen;
         this.hCurrentFont = state.hFont;
         if ((state.font != null) && state.font.IsAlive)
         {
             this.selectedFont = state.font.Target as WindowsFont;
         }
         else
         {
             WindowsFont selectedFont = this.selectedFont;
             this.selectedFont = null;
             if ((selectedFont != null) && MeasurementDCInfo.IsMeasurementDC(this))
             {
                 selectedFont.Dispose();
             }
         }
     }
     MeasurementDCInfo.ResetIfIsMeasurementDC(this.hDC);
 }