/// <summary>
        /// Gets the WPF bitmap image.
        /// </summary>
        internal System.Windows.Media.Imaging.BitmapImage GetWpfBitmapImage(IconCollectionInfo collectionInfo, IconFileInfo fileInfo)
        {
            string iconFileKey = GetIconFileKey(collectionInfo, fileInfo);

            // Load the ImageSource (me may have cached it before
            System.Windows.Media.Imaging.BitmapImage result = null;
            if (!m_wpfBitmapImages.TryGetValue(iconFileKey, out result))
            {
                // Try to load the icon from png file
                var pngIconLink = TryFindPngIcon(collectionInfo, fileInfo);
                if (pngIconLink != null)
                {
                    using (Stream inStream = pngIconLink.OpenRead())
                    {
                        result = new System.Windows.Media.Imaging.BitmapImage();
                        result.BeginInit();
                        result.StreamSource = inStream;
                        result.EndInit();
                        result.Freeze();
                    }
                }

                m_wpfBitmapImages.Add(iconFileKey, result);
            }

            return(result);
        }
        public System.Drawing.Image GetGdiImage <EnumType>(EnumType icon, int sideWidth, Color foreColor)
            where EnumType : struct
        {
            IconCollectionInfo collectionInfo = new IconCollectionInfo(typeof(EnumType));

            collectionInfo.IconSideWidth = sideWidth;
            collectionInfo.IconForeColor = foreColor.ToArgb();
            return(GetGdiImage(collectionInfo, new IconFileInfo(icon.ToString())));
        }
        internal System.Drawing.Image GetGdiImage(IconCollectionInfo collectionInfo, IconFileInfo fileInfo)
        {
            string iconFileKey = GetIconFileKey(collectionInfo, fileInfo);

            System.Drawing.Image result = null;
            if (!m_gdiImages.TryGetValue(iconFileKey, out result))
            {
                // Try to load the icon from svg file
                var svgIconLink = TryFindSvgIcon(collectionInfo, fileInfo);
                if (svgIconLink != null)
                {
                    Stopwatch sw = new Stopwatch();
                    sw.Start();
                    using (Stream inStream = svgIconLink.OpenRead())
                    {
                        Svg.SvgDocument       svgDoc       = Svg.SvgDocument.Open <Svg.SvgDocument>(inStream);
                        System.Drawing.Bitmap targetBitmap = new System.Drawing.Bitmap(collectionInfo.IconSideWidthPixel, collectionInfo.IconSideWidthPixel);
                        using (CustomSvgRenderer svgRenderer = new CustomSvgRenderer(targetBitmap, Color.FromArgb(collectionInfo.IconForeColor)))
                        {
                            svgDoc.Overflow = Svg.SvgOverflow.Auto;

                            svgRenderer.SetBoundable(new GenericBoundable(0f, 0f, (float)targetBitmap.Width, (float)targetBitmap.Height));

                            SizeF dimensions = svgDoc.GetDimensions();
                            svgRenderer.ScaleTransform((float)targetBitmap.Width / dimensions.Width, (float)targetBitmap.Height / dimensions.Height, MatrixOrder.Append);

                            svgDoc.Draw(svgRenderer);
                        }
                        result = targetBitmap;
                    }

                    sw.Stop();
                }

                // Try to load the icon from png file
                if (result == null)
                {
                    var pngIconLink = TryFindPngIcon(collectionInfo, fileInfo);
                    if (pngIconLink != null)
                    {
                        using (Stream inStream = pngIconLink.OpenRead())
                        {
                            result = System.Drawing.Bitmap.FromStream(inStream);
                        }
                    }
                }

                m_gdiImages[iconFileKey] = result;
            }

            return(result);
        }
        /// <summary>
        /// Generates a key describing the given icon information.
        /// </summary>
        internal string GetIconFileKey(IconCollectionInfo collectionInfo, IconFileInfo fileInfo)
        {
            StringBuilder keyBuilder = new StringBuilder(100);

            keyBuilder.Append($"{collectionInfo.IconAssembly.GetName().Name}");
            keyBuilder.Append(':');
            keyBuilder.Append($"{collectionInfo.IconAssemblyDefaultNamespace}.Assets.Icons.{collectionInfo.IconEnumType.Name}.{fileInfo.ImageName}");
            keyBuilder.Append('_');
            keyBuilder.Append($"{collectionInfo.IconSideWidthPixel}x{collectionInfo.IconSideWidthPixel}");
            keyBuilder.Append('_');
            keyBuilder.Append(collectionInfo.IconForeColor);
            return(keyBuilder.ToString());
        }
        /// <summary>
        /// Tries to find a default png icon in the embedded resources of the assembly
        /// where the icon enum is located.
        /// </summary>
        /// <param name="collectionInfo">Information about the icon collection.</param>
        /// <param name="fileInfo">Information about the icon file.</param>
        private AssemblyResourceLink TryFindSvgIcon(IconCollectionInfo collectionInfo, IconFileInfo fileInfo)
        {
            string resourcePath =
                $"{collectionInfo.IconAssemblyDefaultNamespace}.Assets.Icons.{collectionInfo.IconEnumType.Name}.{fileInfo.ImageName}.svg";
            AssemblyResourceLink resourceLink = new AssemblyResourceLink(
                collectionInfo.IconAssembly,
                resourcePath);

            if (!resourceLink.IsValid())
            {
                return(null);
            }

            return(resourceLink);
        }
        /// <summary>
        /// Tries to find an svg icon in the embedded resources of the assembly
        /// where the icon enum is located.
        /// </summary>
        /// <param name="collectionInfo">Information about the icon collection.</param>
        /// <param name="fileInfo">Information about the icon file.</param>
        private AssemblyResourceLink TryFindPngIcon(IconCollectionInfo collectionInfo, IconFileInfo fileInfo)
        {
            string resourcePath = string.Empty;
            AssemblyResourceLink resourceLink = null;
            int actIconsize = collectionInfo.IconSideWidthPixel;

            do
            {
                resourcePath =
                    $"{collectionInfo.IconAssemblyDefaultNamespace}.Assets.Icons.{collectionInfo.IconEnumType.Name}.{fileInfo.ImageName}_{actIconsize}x{actIconsize}.png";
                resourceLink = new AssemblyResourceLink(
                    collectionInfo.IconAssembly,
                    resourcePath);
                if (!resourceLink.IsValid())
                {
                    resourcePath = string.Empty;
                    resourceLink = null;

                    bool found = false;
                    for (int loop = 0; loop < PNG_ICON_SIZES.Length; loop++)
                    {
                        if (PNG_ICON_SIZES[loop] < actIconsize)
                        {
                            actIconsize = PNG_ICON_SIZES[loop];
                            found       = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        actIconsize = -1;
                    }
                }
            }while ((resourceLink == null) && (actIconsize > 0));

            return(resourceLink);
        }