/SpoolFileReader/Emf/EMFSpoolFile.cs
# · C# · 235 lines · 208 code · 25 blank · 2 comment · 23 complexity · 89b24f6734a722561710789653799720 MD5 · raw file
- #region References
-
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.IO;
- using System.Text;
- using SpoolFileLibrary.Reader.Winspool;
-
- #endregion
-
- namespace SpoolFileLibrary.Reader.Emf {
- internal class EmfSpoolFile : ISpoolFile {
- private readonly BinaryReader binaryReader;
- private readonly IList<IPage> pages;
- private DeviceMode deviceMode;
-
- public EmfSpoolFile(Stream stream) {
- if(stream == null) {
- throw new ArgumentNullException("stream");
- }
- stream.Seek(0, SeekOrigin.Begin);
- this.binaryReader = new BinaryReader(stream, Encoding.Unicode);
- this.pages = new List<IPage>();
- }
-
- #region ISpoolFile Members
-
- public bool Parse(bool parsePages, int scaleFactor) {
- HeaderRecord headerRecord = this.ParseHeaderRecord();
- List<DataRecord> dataRecords = this.ParseDataRecords();
- if(parsePages) {
- for(int i = 0; i < dataRecords.Count; i++) {
- var pageContentRecord = dataRecords[i] as PageContentRecord;
- if(pageContentRecord != null) {
- var memoryStream = new MemoryStream(pageContentRecord.EmfMetaFile);
- var metaFile = new Metafile(memoryStream);
- Image image = metaFile.GetThumbnailImage(metaFile.Width/scaleFactor, metaFile.Height/scaleFactor, null, IntPtr.Zero);
- var emfPage = new EmfPage(image, image.Size);
- this.pages.Add(emfPage);
- }
- var devmodeRecord = dataRecords[i] as EMRI_DEVMODERecord;
- if(devmodeRecord != null) {
- this.deviceMode = devmodeRecord.Devmode;
- }
- }
- }
- return true;
- }
-
- public SpoolFileFormat SpoolFileFormat {
- get { return Reader.SpoolFileFormat.EMF; }
- }
-
- public PrintjobLanguage PrintjobLanguage {
- get { return PrintjobLanguage.UNKNOWN; }
- }
-
- public bool Parse() {
- return this.Parse(false, 0);
- }
-
- public IList<IPage> Pages {
- get { return this.pages; }
- }
-
- public int PageCount {
- get { return this.pages.Count; }
- }
-
- public int Copies {
- get { return this.deviceMode.Copies; }
- }
-
- public bool Color {
- get { return this.deviceMode.Color; }
- }
-
- public int PaperLength {
- get { return this.deviceMode.PaperLength; }
- }
-
- public int PaperWidth {
- get { return this.deviceMode.PaperWidth; }
- }
-
- public bool Landscape {
- get { return this.deviceMode.Orientation == Orientation.Landscape; }
- }
-
- public IDeviceMode DeviceMode {
- get { return this.deviceMode; }
- }
-
- public byte[] RawData {
- get { return null; }
- }
-
- #endregion
-
- private List<DataRecord> ParseDataRecords() {
- var dataRecords = new List<DataRecord>();
- while(true) {
- long pos = this.binaryReader.BaseStream.Position;
-
- bool eof = (pos == this.binaryReader.BaseStream.Length);
- if(eof) {
- break;
- }
- uint ulID = this.binaryReader.ReadUInt32();
- if(ulID == 0x00000000) {
- //Don't know why. Sometimes 0x0 is too early.
- //So we need read it again.
- ulID = this.binaryReader.ReadUInt32();
- }
- var dataRecord = new DataRecord();
- dataRecord.ulID = ulID;
- dataRecord.cjSize = this.binaryReader.ReadUInt32();
- if(!Enum.IsDefined(typeof(RecordType), dataRecord.ulID)) {
- this.binaryReader.ReadBytes((int)dataRecord.cjSize); // Read unknown data block
- continue;
- }
- switch(dataRecord.ulID) {
- case (uint) RecordType.EMRI_METAFILE: {
- var pageContentRecord = new PageContentRecord(dataRecord);
- pageContentRecord.EmfMetaFile = this.binaryReader.ReadBytes((int) pageContentRecord.cjSize);
- dataRecords.Add(pageContentRecord);
- }
- break;
- case (uint) RecordType.EMRI_ENGINE_FONT:
- break;
- case (uint) RecordType.EMRI_DEVMODE: {
- var devmodeRecord = new EMRI_DEVMODERecord(dataRecord);
- byte[] buffer = this.binaryReader.ReadBytes((int) devmodeRecord.cjSize);
- this.deviceMode = new DeviceMode(new DEVMODE(buffer));
- devmodeRecord.Devmode = this.deviceMode;
- dataRecords.Add(devmodeRecord);
- }
- break;
- case (uint) RecordType.EMRI_TYPE1_FONT:
- break;
- case (uint) RecordType.EMRI_PRESTARTPAGE:
- break;
- case (uint) RecordType.EMRI_DESIGNVECTOR:
- break;
- case (uint) RecordType.EMRI_SUBSET_FONT:
- break;
- case (uint) RecordType.EMRI_DELTA_FONT:
- break;
- case (uint) RecordType.EMRI_FORM_METAFILE:
- break;
- case (uint) RecordType.EMRI_BW_METAFILE:
- break;
- case (uint) RecordType.EMRI_BW_FORM_METAFILE:
- break;
- case (uint) RecordType.EMRI_METAFILE_DATA: {
- var pageContentRecord = new PageContentRecord(dataRecord);
- pageContentRecord.EmfMetaFile = this.binaryReader.ReadBytes((int) dataRecord.cjSize);
- dataRecords.Add(pageContentRecord);
- }
- break;
- case (uint) RecordType.EMRI_METAFILE_EXT:
- case (uint) RecordType.EMRI_BW_METAFILE_EXT: {
- var pageOffsetRecord = new PageOffsetRecord(dataRecord);
- var offsets = new ulong[pageOffsetRecord.cjSize/sizeof(ulong)];
- for(int i = 0; i < offsets.Length; i++) {
- offsets[i] = this.binaryReader.ReadUInt64();
- }
- dataRecords.Add(pageOffsetRecord);
- }
- break;
- case (uint) RecordType.EMRI_ENGINE_FONT_EXT:
- break;
- case (uint) RecordType.EMRI_TYPE1_FONT_EXT:
- break;
- case (uint) RecordType.EMRI_DESIGNVECTOR_EXT:
- break;
- case (uint) RecordType.EMRI_SUBSET_FONT_EXT:
- break;
- case (uint) RecordType.EMRI_DELTA_FONT_EXT:
- break;
- case (uint) RecordType.EMRI_PS_JOB_DATA:
- break;
- case (uint) RecordType.EMRI_EMBED_FONT_EXT:
- break;
- }
- }
- return dataRecords;
- }
-
- private HeaderRecord ParseHeaderRecord() {
- var headerRecord = new HeaderRecord();
- headerRecord.dwVersion = this.binaryReader.ReadUInt32();
- headerRecord.cjSize = this.binaryReader.ReadUInt32();
- headerRecord.dpszDocName = this.binaryReader.ReadUInt32();
- headerRecord.dpszOutput = this.binaryReader.ReadUInt32();
-
- if(headerRecord.dpszDocName != 0) {
- this.binaryReader.BaseStream.Seek(headerRecord.dpszDocName, SeekOrigin.Begin);
- var docNameStringBuilder = new StringBuilder();
- while(this.binaryReader.PeekChar() != 0) {
- docNameStringBuilder.Append(this.binaryReader.ReadChar());
- }
- headerRecord.DocName = docNameStringBuilder.ToString();
- }
- this.Ensure32BitAlignment();
- if(headerRecord.dpszOutput != 0) {
- this.binaryReader.BaseStream.Seek(headerRecord.dpszOutput, SeekOrigin.Begin);
- var outputDeviceStringBuilder = new StringBuilder();
- while(this.binaryReader.PeekChar() != 0) {
- outputDeviceStringBuilder.Append(this.binaryReader.ReadChar());
- }
- headerRecord.OutputDevice = outputDeviceStringBuilder.ToString();
- }
- this.Ensure32BitAlignment();
- this.EnsurePosition(headerRecord.cjSize);
- return headerRecord;
- }
-
- private void EnsurePosition(uint size)
- {
- this.binaryReader.BaseStream.Seek(size, SeekOrigin.Begin);
- }
-
- private void Ensure32BitAlignment() {
- long pos = this.binaryReader.BaseStream.Position;
- long currentAlignment = pos%4;
- if(currentAlignment == 0) {
- return;
- }
- this.binaryReader.BaseStream.Seek(currentAlignment, SeekOrigin.Current);
- }
- }
- }