private void ReadGlyphDataTT(Stream stream)
 {
     int glyphCount = ReadGlyphCountTT(stream);
     int indexToLocFormat = ReadIndexToLocFormatTT(stream);
     TableDirectoryEntry glyf = Header.TableMap["glyf"];
     TableDirectoryEntry locations = Header.TableMap["loca"];
     int entrySize = (indexToLocFormat == 0 ? 2 : 4);
     if (locations.Length != (glyphCount + 1) * entrySize)
     {
         throw new Exception("bad 'loca' table size");
     }
     stream.Seek(locations.Offset, SeekOrigin.Begin);
     byte[] buf = new byte[locations.Length];
     stream.Read(buf,0, locations.Length);
     List<GlyphData> data = new List<GlyphData>();
     int offset = 0;
     for (int i = 0; i <= glyphCount; i++)
     {
         int glyphOffset = (indexToLocFormat == 0 ? (IOUtils.GetShort(buf, offset) & 0xFFFF) * 2 : IOUtils.GetInt(buf, offset)) + glyf.Offset;
         offset += entrySize;
         if (i > 0)
         {
             int len = glyphOffset - data[i - 1].Offset;
             if (len < 0)
             {
                 throw new Exception("negative glyph length");
             }
             if (MaxGlyphSize < len)
             {
                 MaxGlyphSize = len;
             }
             data[i - 1].Length = len;
         }
         if (i != glyphCount)
         {
             GlyphData gdata = new GlyphData();
             gdata.Offset = glyphOffset;
             data.Add(gdata);
         }
     }
     glyphs = data;
 }
        private void ReadCFF(Stream stream)
        {
            TableDirectoryEntry cff = Header.TableMap["CFF "];
            stream.Seek(cff.Offset, SeekOrigin.Begin);
            byte[] buffer = new byte[5];
            stream.Read(buffer, 0, 4);
            int offSize = buffer[3];
            if (offSize > 4 || offSize <= 0)
            {
                throw new Exception("invalid CFF index offSize");
            }
            stream.Seek(cff.Offset + (buffer[2] & 0xFF), SeekOrigin.Begin);
            object[] names = ReadIndexCFF(stream,CFF_INDEX_NAMES);
            if (names.Length > 1)
            {
                throw new Exception("CFF data contains multiple fonts");
            }
            nameCFF = names[0].ToString();
            Object[] dicts = ReadIndexCFF(stream,CFF_INDEX_DICTS);
            if (dicts.Length> 1)
            {
                throw new Exception("CFF data contains multiple font dicts");
            }
            dictCFF = (Dictionary<object, object>)dicts[0];
            Object[] strings = ReadIndexCFF(stream,CFF_INDEX_NAMES);
            stringsCFF = new StringCFF[strings.Length];
            for (int i = 0; i < strings.Length; i++)
            {
                StringCFF s = new StringCFF();
                stringsCFF[i] = s;
                s.Value = (String)strings[i];
            }
            globalSubrsCFF = ReadIndexCFF(stream,CFF_INDEX_BINARY_RANGE);
            int charstrings = Convert.ToInt32( dictCFF[new KeyCFF(KeyCFF.CHARSTRINGS)]);
            if (charstrings == 0)
            {
                throw new Exception("Invalid CFF data: no charstrings");
            }
            stream.Seek(cff.Offset + charstrings, SeekOrigin.Begin);
            Object[] glyphRanges = ReadIndexCFF(stream,CFF_INDEX_BINARY_RANGE);
            glyphs = new List<GlyphData>();
            for (int i = 0; i < glyphRanges.Length; i++)
            {
                Range range = (Range) glyphRanges[i];
                GlyphData glyph = new GlyphData();
                glyph.Length = range.Length;
                glyph.Offset = range.Offset;
                glyphs.Add(glyph);
            }
            int charset = Convert.ToInt32(dictCFF[new KeyCFF(KeyCFF.CHARSET)]);
            if (charset != 0)
            {
                stream.Seek(cff.Offset + charset, SeekOrigin.Begin);
                stream.Read(buffer, 0, 1);
                int format = buffer[0] & 0xFF;
                switch (format)
                {
                    case 2:
                        ReadCharsetFormat2CFF(stream);
                        break;
                }
            }

            if (dictCFF.ContainsKey(new KeyCFF(KeyCFF.PRIVATE)))
            {
                Object[] privatedict = (Object[])dictCFF[new KeyCFF(KeyCFF.PRIVATE)];
                int size = Convert.ToInt32(privatedict[0]);
                int offset = Convert.ToInt32(privatedict[1]);
                stream.Seek(cff.Offset + offset,SeekOrigin.Begin);
                privateDictCFF = ReadDictCFF(stream,cff.Offset + offset + size);
                stream.Seek(cff.Offset + offset + size, SeekOrigin.Begin);
                privateSubrsCFF = ReadIndexCFF(stream,CFF_INDEX_BINARY_RANGE);
            }
        }