private void ReadFormat4CMap(Stream stream, EncodingRecord er) { byte[] buffer = new byte[9]; stream.Read(buffer, 0, 8); int segCount = (IOUtils.GetShort(buffer, 0) & 0xFFFF) / 2; short[] endCount = ReadShorts(stream,segCount); stream.Read(buffer, 0, 2); short[] startCount = ReadShorts(stream, segCount); short[] idDelta = ReadShorts(stream, segCount); short[] idRangeOffset = ReadShorts(stream, segCount); int lengthRemains = er.Length - 16 - 8 * segCount; short[] glyphIds = ReadShorts(stream,lengthRemains); for (int i = 0; i < segCount; i++) { int start = startCount[i] & 0xFFFF; int end = endCount[i] & 0xFFFF; short rangeOffset = (short)(idRangeOffset[i] / 2); short delta = idDelta[i]; for (int ch = start; ch <= end; ch++) { CharacterData data = new CharacterData(); if (rangeOffset == 0) { data.GlyphIndex = (short) (ch + delta); } else { int index = ch - start + rangeOffset - (segCount - i); int glyphIndex = glyphIds[index]; if (glyphIndex != 0) { glyphIndex += delta; } data.GlyphIndex = (short) glyphIndex; } characters.Add(ch,data); } } }
private void ReadCMap(Stream stream) { TableDirectoryEntry cmap = Header.TableMap["cmap"]; if (cmap == null) { throw new Exception("No cmap table found"); } stream.Seek(cmap.Offset, SeekOrigin.Begin); byte[] buffer = new byte[9]; stream.Read(buffer, 0, 4); if (IOUtils.GetShort(buffer,0)!=0) { throw new Exception("Unknown cmap version"); } int encCount = IOUtils.GetShort(buffer, 2); List<EncodingRecord> encs = new List<EncodingRecord>(); for (int i = 0; i < encCount; i++) { EncodingRecord er = new EncodingRecord(); encs.Add(er); stream.Read(buffer, 0, 8); er.PlatformID = IOUtils.GetShort(buffer, 0); er.EncodingID = IOUtils.GetShort(buffer, 2); er.Offset = IOUtils.GetInt(buffer, 4) + cmap.Offset; } foreach (var er in encs) { stream.Seek(er.Offset, SeekOrigin.Begin); stream.Read(buffer, 0, 6); er.Format = IOUtils.GetShort(buffer, 0); er.Length = IOUtils.GetShort(buffer, 2) & 0xFFFF; er.Language = IOUtils.GetShort(buffer, 4); if (er.PlatformID == (short)PlatformId.Microsoft && er.EncodingID == 1) { // Unicode if (er.Format == 4) { ReadFormat4CMap(stream,er); } } } }