123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- //using System.Runtime.InteropServices;
- using System.IO;
- using System;
- #pragma warning disable CS3001, CS3002, CS3003, CS1591
- namespace FastReport.Fonts
- {
- public class FontStream : IDisposable
- {
- private readonly byte[] _buffer;
- private bool _leaveOpen;
- private bool _disposedValue;
- private readonly Stream _stream;
- private string _fast_name;
- /// <summary>
- /// Creates a new instance of the <see cref="FontStream"/> class.
- /// </summary>
- /// <param name="stream">TrueType raw data stream</param>
- /// <param name="leaveOpen">Keep open raw data stream after disposing FontStream</param>
- public FontStream(Stream stream, bool leaveOpen = false)
- {
- this._stream = stream;
- this._buffer = new byte[16];
- this._leaveOpen = leaveOpen;
- // Trace.WriteLine.WriteLine("FontStream constructor");
- }
- public bool CanRead => _stream.CanRead;
- public bool CanSeek => _stream.CanSeek;
- public long Length => _stream.Length;
- public long Position
- {
- get => _stream.Position;
- set => _stream.Position = value;
- }
- /// <summary>
- /// FastName of font stream
- /// </summary>
- internal string StreamFontFastName
- {
- get => _fast_name;
- set => _fast_name = value;
- }
- internal bool LeaveOpen
- {
- set => _leaveOpen = value;
- }
- public long Seek(long offset, SeekOrigin origin)
- {
- return _stream.Seek(offset, origin);
- }
- internal void Read(byte[] data, int length)
- {
- _stream.Read(data, 0, length);
- }
- internal void Write(byte[] data, int length)
- {
- _stream.Write(data, 0, length);
- }
- protected virtual void Dispose(bool disposing)
- {
- #if SAVE_COPY_OF_SUBSETTET_FONT_TO_FILE
- if (_stream.CanWrite)
- {
- _stream.Position = 0;
- FileStream debug = File.OpenWrite("FONT-" + DateTime.Now.Ticks + ".ttf");
- if (debug != null && debug.CanWrite)
- {
- _stream.CopyTo(debug);
- debug.Close();
- }
- }
- #endif
- if (!_disposedValue)
- {
- if (!_leaveOpen)
- _stream.Dispose();
- _disposedValue = true;
- }
- }
- public void Dispose()
- {
- // DO NOT CHANGE THIS CODE! If you need clenup code - put it into "Dispose(bool disposing)" method.
- Dispose(disposing: true);
- GC.SuppressFinalize(this);
- }
- private void ReadInternal(int size)
- {
- int n;
- if (size == 1)
- {
- n = _stream.ReadByte();
- if (n == -1)
- throw new EndOfStreamException();
- _buffer[0] = (byte)n;
- return;
- }
- int bytesRead = 0;
- do
- {
- n = _stream.Read(_buffer, bytesRead, size - bytesRead);
- if (n == 0)
- {
- throw new EndOfStreamException();
- }
- bytesRead += n;
- } while (bytesRead < size);
- }
- public uint ReadUInt32()
- {
- ReadInternal(4);
- if (BitConverter.IsLittleEndian)
- return (uint)(_buffer[3] | _buffer[2] << 8 | _buffer[1] << 16 | _buffer[0] << 24);
- else
- return (uint)(_buffer[0] | _buffer[1] << 8 | _buffer[2] << 16 | _buffer[3] << 24);
- }
- internal void WriteUInt32(uint word)
- {
- byte[] holder = new byte[4];
- if (BitConverter.IsLittleEndian)
- {
- holder[3] = (byte)(word);
- holder[2] = (byte)(word >> 8);
- holder[1] = (byte)(word >> 16);
- holder[0] = (byte)(word >> 24);
- }
- else
- {
- holder[0] = (byte)(word);
- holder[1] = (byte)(word >> 8);
- holder[2] = (byte)(word >> 16);
- holder[3] = (byte)(word >> 24);
- }
- _stream.Write(holder, 0, 4);
- }
- public int ReadInt32()
- {
- ReadInternal(4);
- if (BitConverter.IsLittleEndian)
- return (int)(_buffer[3] | _buffer[2] << 8 | _buffer[1] << 16 | _buffer[0] << 24);
- else
- return (int)(_buffer[0] | _buffer[1] << 8 | _buffer[2] << 16 | _buffer[3] << 24);
- }
- public byte ReadByte()
- {
- int b = _stream.ReadByte();
- if (b == -1)
- throw new EndOfStreamException();
- return (byte)b;
- }
- public virtual sbyte ReadSByte()
- {
- ReadInternal(1);
- return (sbyte)(_buffer[0]);
- }
- public ushort ReadUInt16()
- {
- ReadInternal(2);
- if (BitConverter.IsLittleEndian)
- return (ushort)(_buffer[1] | _buffer[0] << 8);
- else
- return (ushort)(_buffer[0] | _buffer[1] << 8);
- }
- public short ReadInt16()
- {
- ReadInternal(2);
- if (BitConverter.IsLittleEndian)
- return (short)(_buffer[1] | _buffer[0] << 8);
- else
- return (short)(_buffer[0] | _buffer[1] << 8);
- }
- public ulong ReadUInt64()
- {
- uint hi, lo;
- ReadInternal(8);
- if (BitConverter.IsLittleEndian)
- {
- lo = (uint)(_buffer[7] | _buffer[6] << 8 | _buffer[5] << 16 | _buffer[4] << 24);
- hi = (uint)(_buffer[3] | _buffer[2] << 8 | _buffer[1] << 16 | _buffer[0] << 24);
- }
- else
- {
- lo = (uint)(_buffer[0] | _buffer[1] << 8 | _buffer[2] << 16 | _buffer[3] << 24);
- hi = (uint)(_buffer[4] | _buffer[5] << 8 | _buffer[6] << 16 | _buffer[7] << 24);
- }
- return ((ulong)hi) << 32 | lo;
- }
- public virtual long ReadInt64()
- {
- uint hi, lo;
- ReadInternal(8);
- if (BitConverter.IsLittleEndian)
- {
- lo = (uint)(_buffer[7] | _buffer[6] << 8 | _buffer[5] << 16 | _buffer[4] << 24);
- hi = (uint)(_buffer[3] | _buffer[2] << 8 | _buffer[1] << 16 | _buffer[0] << 24);
- }
- else
- {
- lo = (uint)(_buffer[0] | _buffer[1] << 8 | _buffer[2] << 16 | _buffer[3] << 24);
- hi = (uint)(_buffer[4] | _buffer[5] << 8 | _buffer[6] << 16 | _buffer[7] << 24);
- }
- return (long)((ulong)hi) << 32 | lo;
- }
- internal void WriteUInt16(ushort data16)
- {
- byte[] data8 = new byte[2];
- if (BitConverter.IsLittleEndian)
- {
- data8[1] = (byte)(data16);
- data8[0] = (byte)(data16 >> 8);
- }
- else
- {
- data8[0] = (byte)(data16);
- data8[1] = (byte)(data16 >> 8);
- }
- _stream.Write(data8, 0, 2);
- }
- internal void WriteInt16(short ascender)
- {
- WriteUInt16((ushort)ascender);
- }
- internal void WriteByte(byte data8)
- {
- _stream.WriteByte(data8);
- }
- internal void WriteUInt64(ulong data64)
- {
- Byte[] bytes = BitConverter.GetBytes(data64);
- if (BitConverter.IsLittleEndian)
- Array.Reverse(bytes);
- _stream.Write(bytes, 0, 8);
- }
- internal void WriteInt32(uint data4)
- {
- WriteUInt32((uint)data4);
- }
- }
- }
- #pragma warning restore
|