/// <devdoc>
        ///     Dispose of all cached WindowsFont objects and reset the collection.
        /// </devdoc>
        public static void ResetFontCache()
        {
            if (WindowsFontCache.Count > 0)
            {
                for (int index = 0; index < WindowsFontCache.Count; index++)
                {
                    WindowsFontCache[index].Value.Dispose();
                }

                WindowsFontCache.Clear();
                currentIndex = -1;

#if GDI_FONT_CACHE_TRACK
                Debug.WriteLine("Font cache reset.  Count: " + WindowsFontCache.Count);
#endif
            }
        }
Example #2
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);
        }
Example #3
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);
        }