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); } }