checking if a postscript font is installed

后端 未结 1 713
时光取名叫无心
时光取名叫无心 2021-01-27 09:56

I need a way to check if a specific postscript font is installed on a users computer. I have found many ways to check for true type fonts but none seem to work for post script.

相关标签:
1条回答
  • 2021-01-27 10:16

    So I found two ways of checking this. the first is probably the most reliable but defiantly the most involved

    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    public class Fonts
    {
        private const byte DEFAULT_CHARSET = 1;
        private const byte SHIFTJIS_CHARSET = 128;
        private const byte JOHAB_CHARSET = 130;
        private const byte EASTEUROPE_CHARSET = 238;
        private const byte DEFAULT_PITCH = 0;
        private const byte FIXED_PITCH = 1;
        private const byte VARIABLE_PITCH = 2;
        private const byte FF_DONTCARE = (0 << 4);
        private const byte FF_ROMAN = (1 << 4);
        private const byte FF_SWISS = (2 << 4);
        private const byte FF_MODERN = (3 << 4);
        private const byte FF_SCRIPT = (4 << 4);
        private const byte FF_DECORATIVE = (5 << 4);
    
        private List<FontFamily> _fonts = new List<FontFamily>();
    
        public List<FontFamily> FontFamilies
        {
            get { return _fonts; }
            set { _fonts = value; }
        }
    
        public void GetFonts()
        {
            LOGFONT lf = CreateLogFont("");
    
            IntPtr plogFont = Marshal.AllocHGlobal(Marshal.SizeOf(lf));
            Marshal.StructureToPtr(lf, plogFont, true);
    
            int ret = 0;
            try
            {
                //If anyone knows of a better way to get the pointer please let me know
                var pictureBox = new PictureBox();
                var graphic = pictureBox.CreateGraphics();
                var ptr = graphic.GetHdc();
    
                del1 = new EnumFontExDelegate(callback1);
                ret = EnumFontFamiliesEx(ptr, plogFont, del1, IntPtr.Zero, 0);
    
                System.Diagnostics.Trace.WriteLine("EnumFontFamiliesEx = " + ret.ToString());
    
                graphic.ReleaseHdc(ptr);
            }
            catch
            {
                System.Diagnostics.Trace.WriteLine("Error!");
            }
            finally
            {
                Marshal.DestroyStructure(plogFont, typeof(LOGFONT));
    
            }
        }
    
        [DllImport("gdi32.dll", CharSet = CharSet.Auto)]
        static extern int EnumFontFamiliesEx(IntPtr hdc,
                                [In] IntPtr pLogfont,
                                EnumFontExDelegate lpEnumFontFamExProc,
                                IntPtr lParam,
                                uint dwFlags);
    
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public class LOGFONT
        {
    
            public int lfHeight;
            public int lfWidth;
            public int lfEscapement;
            public int lfOrientation;
            public FontWeight lfWeight;
            [MarshalAs(UnmanagedType.U1)]
            public bool lfItalic;
            [MarshalAs(UnmanagedType.U1)]
            public bool lfUnderline;
            [MarshalAs(UnmanagedType.U1)]
            public bool lfStrikeOut;
            public FontCharSet lfCharSet;
            public FontPrecision lfOutPrecision;
            public FontClipPrecision lfClipPrecision;
            public FontQuality lfQuality;
            public FontPitchAndFamily lfPitchAndFamily;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string lfFaceName;
        }
    
        public enum FontWeight : int
        {
            FW_DONTCARE = 0,
            FW_THIN = 100,
            FW_EXTRALIGHT = 200,
            FW_LIGHT = 300,
            FW_NORMAL = 400,
            FW_MEDIUM = 500,
            FW_SEMIBOLD = 600,
            FW_BOLD = 700,
            FW_EXTRABOLD = 800,
            FW_HEAVY = 900,
        }
        public enum FontCharSet : byte
        {
            ANSI_CHARSET = 0,
            DEFAULT_CHARSET = 1,
            SYMBOL_CHARSET = 2,
            SHIFTJIS_CHARSET = 128,
            HANGEUL_CHARSET = 129,
            HANGUL_CHARSET = 129,
            GB2312_CHARSET = 134,
            CHINESEBIG5_CHARSET = 136,
            OEM_CHARSET = 255,
            JOHAB_CHARSET = 130,
            HEBREW_CHARSET = 177,
            ARABIC_CHARSET = 178,
            GREEK_CHARSET = 161,
            TURKISH_CHARSET = 162,
            VIETNAMESE_CHARSET = 163,
            THAI_CHARSET = 222,
            EASTEUROPE_CHARSET = 238,
            RUSSIAN_CHARSET = 204,
            MAC_CHARSET = 77,
            BALTIC_CHARSET = 186,
        }
        public enum FontPrecision : byte
        {
            OUT_DEFAULT_PRECIS = 0,
            OUT_STRING_PRECIS = 1,
            OUT_CHARACTER_PRECIS = 2,
            OUT_STROKE_PRECIS = 3,
            OUT_TT_PRECIS = 4,
            OUT_DEVICE_PRECIS = 5,
            OUT_RASTER_PRECIS = 6,
            OUT_TT_ONLY_PRECIS = 7,
            OUT_OUTLINE_PRECIS = 8,
            OUT_SCREEN_OUTLINE_PRECIS = 9,
            OUT_PS_ONLY_PRECIS = 10,
        }
        public enum FontClipPrecision : byte
        {
            CLIP_DEFAULT_PRECIS = 0,
            CLIP_CHARACTER_PRECIS = 1,
            CLIP_STROKE_PRECIS = 2,
            CLIP_MASK = 0xf,
            CLIP_LH_ANGLES = (1 << 4),
            CLIP_TT_ALWAYS = (2 << 4),
            CLIP_DFA_DISABLE = (4 << 4),
            CLIP_EMBEDDED = (8 << 4),
        }
        public enum FontQuality : byte
        {
            DEFAULT_QUALITY = 0,
            DRAFT_QUALITY = 1,
            PROOF_QUALITY = 2,
            NONANTIALIASED_QUALITY = 3,
            ANTIALIASED_QUALITY = 4,
            CLEARTYPE_QUALITY = 5,
            CLEARTYPE_NATURAL_QUALITY = 6,
        }
        [Flags]
        public enum FontPitchAndFamily : byte
        {
            DEFAULT_PITCH = 0,
            FIXED_PITCH = 1,
            VARIABLE_PITCH = 2,
            FF_DONTCARE = (0 << 4),
            FF_ROMAN = (1 << 4),
            FF_SWISS = (2 << 4),
            FF_MODERN = (3 << 4),
            FF_SCRIPT = (4 << 4),
            FF_DECORATIVE = (5 << 4),
        }
    
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct NEWTEXTMETRIC
        {
            public int tmHeight;
            public int tmAscent;
            public int tmDescent;
            public int tmInternalLeading;
            public int tmExternalLeading;
            public int tmAveCharWidth;
            public int tmMaxCharWidth;
            public int tmWeight;
            public int tmOverhang;
            public int tmDigitizedAspectX;
            public int tmDigitizedAspectY;
            public char tmFirstChar;
            public char tmLastChar;
            public char tmDefaultChar;
            public char tmBreakChar;
            public byte tmItalic;
            public byte tmUnderlined;
            public byte tmStruckOut;
            public byte tmPitchAndFamily;
            public byte tmCharSet;
            int ntmFlags;
            int ntmSizeEM;
            int ntmCellHeight;
            int ntmAvgWidth;
        }
        public struct FONTSIGNATURE
        {
            [MarshalAs(UnmanagedType.ByValArray)]
            int[] fsUsb;
            [MarshalAs(UnmanagedType.ByValArray)]
            int[] fsCsb;
        }
        public struct NEWTEXTMETRICEX
        {
            NEWTEXTMETRIC ntmTm;
            FONTSIGNATURE ntmFontSig;
        }
    
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct ENUMLOGFONTEX
        {
            public LOGFONT elfLogFont;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
            public string elfFullName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string elfStyle;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string elfScript;
        }
    
        public delegate int EnumFontExDelegate(ref ENUMLOGFONTEX lpelfe, ref NEWTEXTMETRICEX lpntme, int FontType, int lParam);
        public EnumFontExDelegate del1;
    
        public int callback1(ref ENUMLOGFONTEX lpelfe, ref NEWTEXTMETRICEX lpntme, int FontType, int lParam)
        {
            try
            {
                FontType fontType;
                if (FontType == 2 || FontType == 4)
                {
                    fontType = (ClientTools.Fonts.FontType)FontType;
                }
                else
                {
                    fontType = ClientTools.Fonts.FontType.Unknown;
                }
    
                FontFamilies.Add(new FontFamily(lpelfe.elfFullName, fontType));
            }
            catch (Exception e)
            {
                System.Diagnostics.Trace.WriteLine(e.ToString());
            }
            return 1;
        }
    
        public static LOGFONT CreateLogFont(string fontname)
        {
            LOGFONT lf = new LOGFONT();
            lf.lfHeight = 0;
            lf.lfWidth = 0;
            lf.lfEscapement = 0;
            lf.lfOrientation = 0;
            lf.lfWeight = 0;
            lf.lfItalic = false;
            lf.lfUnderline = false;
            lf.lfStrikeOut = false;
            lf.lfCharSet = FontCharSet.DEFAULT_CHARSET;
            lf.lfOutPrecision = 0;
            lf.lfClipPrecision = 0;
            lf.lfQuality = 0;
            lf.lfPitchAndFamily = FontPitchAndFamily.FF_DONTCARE;
            lf.lfFaceName = "";
    
    
            return lf;
        }
    }
    
    public class FontFamily
    {
        public string FontName { get; set; }
    
        public FontType FontType { get; set; }
    
        public FontFamily(string fontName, FontType fontType)
        {
            FontName = fontName;
            FontType = fontType;
        }
    }
    
    public enum FontType
    {
        Unknown = 1,
        TrueType = 4,
        PostScript = 2
    }
    

    I Borrowed most of this code from another post Enumerating active fonts in C# using DLL call to EnumFontFamiliesEx has me schtumped

    The Other way which I have found to be slightly unreliable is the registry key

    HKEY_LOCAL_MACHINE > SOFTWARE > Microsoft > Windows NT > CurrentVersion > Type 1 Installer > Type 1 Fonts
    

    although this gives you a list of post script fonts. They are not all necessarily installed properly. These keys can point to corrupted fonts that aren't actually installed

    I have found the first way of hitting the windows api as the comment suggested works the best

    0 讨论(0)
提交回复
热议问题