//
        // static factory methods
        //

        #region public static TTFRef[] LoadRefs(System.IO.DirectoryInfo dir)

        /// <summary>
        /// Gets an array of all the font file references in the specified directory.
        /// If any files cannot be loaded, then it will be included as a TTFRef with it's invalid flag set, and error message set appropriately.
        /// </summary>
        /// <param name="dir"></param>
        /// <returns></returns>
        public static TTFRef[] LoadRefs(System.IO.DirectoryInfo dir)
        {
            List <TTFRef>             matched = new List <TTFRef>();
            List <System.IO.FileInfo> fis     = new List <System.IO.FileInfo>();

            fis.AddRange(dir.GetFiles("*.ttf"));
            fis.AddRange(dir.GetFiles("*.otf"));

            if (fis.Count > 0)
            {
                for (int i = 0; i < fis.Count; i++)
                {
                    TTFRef aref = LoadRef(fis[i]);
                    if (aref != null)
                    {
                        System.Diagnostics.Debug.WriteLine("Loaded Font : " + aref.GetFullName());
                        matched.Add(aref);
                    }
                }
            }

            List <System.IO.FileInfo> cols = new List <System.IO.FileInfo>();

            cols.AddRange(dir.GetFiles("*.ttc"));

            if (cols.Count > 0)
            {
                for (int i = 0; i < cols.Count; i++)
                {
                    TTFRef[] all = LoadCollectionRefs(cols[i]);
                    if (null != all)
                    {
                        foreach (var tref in all)
                        {
                            System.Diagnostics.Debug.WriteLine("Loaded Font : " + tref.GetFullName());
                            matched.Add(tref);
                        }
                    }
                }
            }


            return(matched.ToArray());
        }
        /// <summary>
        /// Loads a specific font reference using the BigEndianReader and the specified file path.
        /// If the file cannot be loaded, then it will return a TTFRef with it's invalid flag set, and error message set appropriately.
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="fullpath"></param>
        /// <returns></returns>
        public static TTFRef LoadRef(BigEndianReader reader, string fullpath)
        {
            TTFRef loaded;

            try
            {
                loaded = DoLoadRef(reader, fullpath);
            }
            catch (Exception ex)
            {
                TTFRef invalid = new TTFRef(fullpath);
                invalid.IsValid      = false;
                invalid.ErrorMessage = ex.Message;
                invalid.FamilyName   = "INVALID FONT FILE";
                loaded = invalid;
            }

            return(loaded);
        }
        /// <summary>
        /// Performs the actual reading and loading of the file with the BigEndian reader
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="fullpath"></param>
        /// <returns></returns>
        private static TTFRef DoLoadRef(BigEndianReader reader, string fullpath)
        {
            TrueTypeHeader head;

            if (TrueTypeHeader.TryReadHeader(reader, out head) == false)
            {
                return(null);
            }

            TrueTypeTableEntryList list = new TrueTypeTableEntryList();
            bool hasOs2   = false;
            bool hasFHead = false;
            bool hasName  = false;

            for (int i = 0; i < head.NumberOfTables; i++)
            {
                TrueTypeTableEntry dir = new TrueTypeTableEntry();
                dir.Read(reader);
                list.Add(dir);
                if (dir.Tag == TrueTypeTableNames.WindowsMetrics)
                {
                    hasOs2 = true;
                }
                else if (dir.Tag == TrueTypeTableNames.FontHeader)
                {
                    hasFHead = true;
                }
                else if (dir.Tag == TrueTypeTableNames.NamingTable)
                {
                    hasName = true;
                }
            }


            TrueTypeTableFactory fact = (head.Version as TrueTypeVersionReader).GetTableFactory();


            SubTables.NamingTable ntable = null;

            if (hasName)
            {
                ntable = fact.ReadTable(TrueTypeTableNames.NamingTable, list, reader) as SubTables.NamingTable;
            }
            else
            {
                throw new ArgumentNullException("The required '" + TrueTypeTableNames.NamingTable + "' is not present in this font file. The OpenType file is corrupt");
            }


            //if (fhead == null)
            //    throw new ArgumentNullException("The required '" + FontHeaderTable + "' is not present in this font file. The OpenType file is corrupt");



            TTFRef    ttfref = new TTFRef(fullpath);
            NameEntry entry;
            int       FamilyNameID = 1;

            if (ntable.Names.TryGetEntry(FamilyNameID, out entry))
            {
                ttfref.FamilyName = entry.ToString();
            }

            if (hasOs2)
            {
                SubTables.OS2Table os2table = fact.ReadTable(TrueTypeTableNames.WindowsMetrics, list, reader) as SubTables.OS2Table;
                ttfref.FontRestrictions = os2table.FSType;
                ttfref.FontWidth        = os2table.WidthClass;
                ttfref.FontWeight       = os2table.WeightClass;
                ttfref.FontSelection    = os2table.Selection;
            }
            else if (hasFHead)
            {
                SubTables.FontHeader fhead = fact.ReadTable(TrueTypeTableNames.FontHeader, list, reader) as SubTables.FontHeader;
                var mac = fhead.MacStyle;
                ttfref.FontRestrictions = FontRestrictions.InstallableEmbedding;
                ttfref.FontWeight       = WeightClass.Normal;

                if ((mac & FontStyleFlags.Condensed) > 0)
                {
                    ttfref.FontWidth = WidthClass.Condensed;
                }

                else if ((mac & FontStyleFlags.Extended) > 0)
                {
                    ttfref.FontWidth = WidthClass.Expanded;
                }

                ttfref.FontSelection = 0;
                if ((mac & FontStyleFlags.Italic) > 0)
                {
                    ttfref.FontSelection |= FontSelection.Italic;
                }

                if ((mac & FontStyleFlags.Bold) > 0)
                {
                    ttfref.FontSelection |= FontSelection.Bold;
                    ttfref.FontWeight     = WeightClass.Bold;
                }
                if ((mac & FontStyleFlags.Outline) > 0)
                {
                    ttfref.FontSelection |= FontSelection.Outlined;
                }

                if ((mac & FontStyleFlags.Underline) > 0)
                {
                    ttfref.FontSelection |= FontSelection.Underscore;
                }
            }
            else
            {
                throw new ArgumentNullException("The required '" + TrueTypeTableNames.WindowsMetrics + "' or '" + TrueTypeTableNames.FontHeader + " are not present in this font file. The OpenType file is corrupt");
            }


            return(ttfref);
        }