/// <summary>
        /// Loads a font package from the given file.
        /// </summary>
        /// <returns>0 = success, 1 = bad header version, 2 = font count is zero</returns>
        public int Load(string filename)
        {
            FileStream   fs = new FileStream(filename, FileMode.Open);
            BinaryReader br = new BinaryReader(fs);

            ms = new MemoryStream(br.ReadBytes((int)br.BaseStream.Length));
            fs.Close();
            br = new BinaryReader(ms);

            br.BaseStream.Position = 0;

            //Make sure this is a font package
            var fileMagic = br.ReadUInt32();

            if (fileMagic != 0xC0000003)
            {
                ms.Close();
                br.Close();
                return(1);
            }

            int fontCount = br.ReadInt32();

            if (fontCount <= 0)
            {
                ms.Close();
                br.Close();
                return(2);
            }

            maxFontCount = 16;

            //check to see if package belongs to Halo 4
            var maxcounthack = br.ReadInt32();

            if (maxcounthack == 1048)
            {
                maxFontCount = 64;
            }

            //get the font headers info
            br.BaseStream.Position -= 4;
            for (int i = 0; i < maxFontCount; i++)
            {
                FontEntries.Add(new FontHeaderInfo()
                {
                    offset     = br.ReadInt32(),
                    size       = br.ReadInt32(),
                    startBlock = br.ReadInt16(),
                    blockCount = br.ReadInt16()
                });
            }

            //read engine ordering
            for (int i = 0; i < maxFontCount; i++)
            {
                OrderList.Add(br.ReadInt32());
            }

            int headerTableOffset = br.ReadInt32();
            int headerTableSize   = br.ReadInt32();

            BlockRangesOffset = br.ReadInt32();
            int blockCount = br.ReadInt32();

            br.BaseStream.Position = BlockRangesOffset;

            for (int i = 0; i < blockCount; i++)
            {
                var startchar = br.ReadUInt16();
                var startfont = br.ReadInt16();

                var endchar = br.ReadUInt16();
                var endfont = br.ReadInt16();

                charDatum start = new charDatum()
                {
                    characterCode = startchar, fontIndex = startfont
                };
                charDatum end = new charDatum()
                {
                    characterCode = endchar, fontIndex = endfont
                };

                BlockRange range = new BlockRange()
                {
                    startIndex = start, endIndex = end
                };

                BlockRanges.Add(range);
            }

            //read data blocks

            //set position for hax to check for h4b
            br.BaseStream.Position = 0x8000;

            ChunkSize = 0x8000;

            if (maxFontCount == 64 & br.ReadInt16() != 8)            //blocks seem to have a short value of 8 as some header or version
            {
                ChunkSize = 0xC000;
            }

            for (int i = 0; i < blockCount; i++)
            {
                Block dataBlock = new Block();
                dataBlock.Read(br, ChunkSize + (i * ChunkSize));

                Blocks.Add(dataBlock);
            }

            //read font headers and find its characters
            for (int i = 0; i < fontCount; i++)
            {
                var tempfont = new PackageFont();
                br.BaseStream.Position = FontEntries[i].offset;
                tempfont.ReadHeader(br);

                for (int bl = FontEntries[i].startBlock; bl < (FontEntries[i].startBlock + FontEntries[i].blockCount); bl++)
                {
                    for (int ch = 0; ch < Blocks[bl].charCount; ch++)
                    {
                        if (Blocks[bl].charTable[ch].index.fontIndex == i)
                        {
                            var tempchar = new FontCharacter(Blocks[bl].charTable[ch].index.characterCode, Blocks[bl].charData[ch]);

                            tempfont.Characters.Add(tempchar);
                        }
                    }
                }
                Fonts.Add(tempfont);
            }

            br.Close();
            ms.Close();
            return(0);
        }
        private int LoadFile(string filename)
        {
            List <int>           CharacterPointers = new List <int>();
            List <CharacterData> CharacterEntries  = new List <CharacterData>();

            List <int> kernlist = new List <int>();

            FileStream   fs = new FileStream(filename, FileMode.Open);
            BinaryReader br = new BinaryReader(fs);

            ms = new MemoryStream(br.ReadBytes((int)br.BaseStream.Length));
            fs.Close();
            br = new BinaryReader(ms);

            br.BaseStream.Position = 0x200;

            //Make sure this is a font file
            var fileMagic = br.ReadUInt32();

            if (fileMagic != 0xF0000001)
            {
                ms.Close();
                br.Close();
                return(1);
            }

            PackageFont tempfont = new PackageFont();

            tempfont.Name = filename.Substring(filename.LastIndexOf("\\") + 1);

            tempfont.HeaderVersion = (int)fileMagic;
            tempfont.ReadH2Header(br);

            br.BaseStream.Position = 0x3AC;

            int unk7 = br.ReadInt32();
            int unk8 = br.ReadInt32();

            int characterdataoffset = 0x40400 + (tempfont.CharacterCount * 0x10);

            //read characters
            for (int i = 0; i < tempfont.CharacterCount; i++)
            {
                CharacterData tempchar = new CharacterData();
                tempchar.Read(br, 0x40400 + (i * 0x10), true);

                br.BaseStream.Position = tempchar.OffsetH2;

                tempchar.compressedData = br.ReadBytes(tempchar.dataSize);

                CharacterEntries.Add(tempchar);
            }

            //read character indexes and match things up
            for (int i = 0; i < 65536; i++)
            {
                br.BaseStream.Position = 0x400 + (i * 4);

                int charindex = br.ReadInt32();

                FontCharacter tempfchar = new FontCharacter((ushort)i, CharacterEntries[charindex]);

                if (CharacterPointers.Contains(charindex))
                {
                    tempfchar.isdupe = true;
                }
                else
                {
                    CharacterPointers.Add(charindex);
                }

                tempfont.Characters.Add(tempfchar);
                tempfchar = null;
            }

            tempfont.H2File = filename;
            Fonts.Add(tempfont);


            br.Close();
            ms.Close();
            return(0);
        }