├── PdfFileWriter ├── PdfPage.cs ├── PdfFileWriter.csproj.user ├── PdfFileWriter.sln ├── Properties │ └── AssemblyInfo.cs ├── PdfLayer.cs ├── PdfExtGState.cs ├── PdfImageControl.cs ├── PdfBinaryWriter.cs ├── PdfXObject.cs ├── PdfWebLink.cs ├── PdfShadingFunction.cs ├── PdfRectangle.cs ├── CreateMetafile.cs ├── PdfFileWriter.csproj ├── PdfInfo.cs ├── ImageSizePos.cs ├── PdfLayers.cs ├── PdfAnnotation.cs ├── PdfEmbeddedFile.cs ├── AnnotAction.cs ├── LocationMarker.cs ├── PdfAxialShading.cs ├── ArcToBezier.cs ├── PdfPrintDocument.cs ├── PdfRadialShading.cs ├── PdfChart.cs ├── PdfTableStyle.cs ├── PdfBookmark.cs ├── PdfTilingPattern.cs ├── PdfDictionary.cs ├── PdfDisplayMedia.cs └── PdfFontFileClasses.cs └── README.md /PdfFileWriter/PdfPage.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tossnet/PdfFileWriter/master/PdfFileWriter/PdfPage.cs -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PdfFileWriter 2 | # Version 1.25.0 2019/07/15 3 | The PDF File Writer C# class library PdfFileWriter allows you to create PDF files directly from your .net application. The library shields you from the details of the PDF file structure. 4 | 5 | Version 1.25.0 enhancements: Support for font collections and for non-ASCII font names. This mainly applies to Japanese, Chinese and Korean fonts. 6 | 7 | For documentation and further information visit PDF File Writer C# Class Library (Version 1.25.0) 8 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfFileWriter.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | ShowAllFiles 13 | 14 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfFileWriter.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual C# Express 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PdfFileWriter", "PdfFileWriter.csproj", "{7B531568-9C87-4CC5-917D-28C43BCF5B38}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {7B531568-9C87-4CC5-917D-28C43BCF5B38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {7B531568-9C87-4CC5-917D-28C43BCF5B38}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {7B531568-9C87-4CC5-917D-28C43BCF5B38}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {7B531568-9C87-4CC5-917D-28C43BCF5B38}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /PdfFileWriter/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PdfFileWriter")] 9 | [assembly: AssemblyDescription("PDF File Writer C# Class Library")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Uzi Granot")] 12 | [assembly: AssemblyProduct("PdfFileWriter Version 1.25.0")] 13 | [assembly: AssemblyCopyright("Copyright © 2013-2019 Uzi Granot. All rights reserved.")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("27b9fc16-eb56-4ccf-aa84-723735483d25")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.25.0")] 36 | [assembly: AssemblyFileVersion("1.1.25.0")] 37 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfLayer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace PdfFileWriter 8 | { 9 | /// 10 | /// Lock/unlock layer enumeration 11 | /// 12 | public enum LockLayer 13 | { 14 | /// 15 | /// Unlock layer (default) 16 | /// 17 | Unlocked, 18 | 19 | /// 20 | /// Lock layer 21 | /// 22 | Locked, 23 | } 24 | 25 | /// 26 | /// Layer state 27 | /// 28 | public enum LayerState 29 | { 30 | /// 31 | /// Layer state is ON 32 | /// 33 | On, 34 | 35 | /// 36 | /// Layer state is OFF 37 | /// 38 | Off, 39 | } 40 | 41 | /// 42 | /// PdfLayer class 43 | /// 44 | public class PdfLayer : PdfObject, IComparable 45 | { 46 | /// 47 | /// Layer name 48 | /// 49 | public string Name {get; private set;} 50 | 51 | /// 52 | /// Layer locked or unlocked 53 | /// 54 | public LockLayer Locked {get; set;} 55 | 56 | /// 57 | /// Initial layer state (on or off) 58 | /// 59 | public LayerState State {get; set;} 60 | 61 | /// 62 | /// Layer is a radio button 63 | /// 64 | public string RadioButton {get; set;} 65 | 66 | internal PdfLayers LayersParent; 67 | 68 | /// 69 | /// Layer constructor 70 | /// 71 | /// Layers parent 72 | /// Layer's name 73 | public PdfLayer 74 | ( 75 | PdfLayers LayersParent, 76 | string Name 77 | ) : base(LayersParent.Document, ObjectType.Dictionary, "/OCG") 78 | { 79 | // save arguments 80 | this.Name = Name; 81 | 82 | // save layers parent 83 | this.LayersParent = LayersParent; 84 | 85 | // create resource code 86 | ResourceCode = Document.GenerateResourceNumber('O'); 87 | 88 | // add layer name to the dictionary 89 | Dictionary.AddPdfString("/Name", Name); 90 | 91 | // add to the list of all layers 92 | LayersParent.LayerList.Add(this); 93 | 94 | // exit 95 | return; 96 | } 97 | 98 | /// 99 | /// CompareTo for IComparabler 100 | /// 101 | /// Other layer 102 | /// Compare result 103 | public int CompareTo 104 | ( 105 | PdfLayer Other 106 | ) 107 | { 108 | int Cmp = string.Compare(RadioButton, Other.RadioButton); 109 | if(Cmp != 0) return Cmp; 110 | return ObjectNumber - Other.ObjectNumber; 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfExtGState.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfExtGState 7 | // External graphics state dictionary. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | using System.Collections.Generic; 28 | 29 | namespace PdfFileWriter 30 | { 31 | internal class PdfExtGState : PdfObject, IComparable 32 | { 33 | internal string Key; 34 | internal string Value; 35 | 36 | // search constructor 37 | internal PdfExtGState 38 | ( 39 | string Key, 40 | string Value 41 | ) 42 | { 43 | // save value 44 | this.Key = Key; 45 | this.Value = Value; 46 | 47 | // exit 48 | return; 49 | } 50 | 51 | // object constructor 52 | internal PdfExtGState 53 | ( 54 | PdfDocument Document, 55 | string Key, 56 | string Value 57 | ) : base(Document, ObjectType.Dictionary, "/ExtGState") 58 | { 59 | // save value 60 | this.Key = Key; 61 | this.Value = Value; 62 | 63 | // create resource code 64 | ResourceCode = Document.GenerateResourceNumber('G'); 65 | return; 66 | } 67 | 68 | internal static PdfExtGState CreateExtGState 69 | ( 70 | PdfDocument Document, 71 | string Key, 72 | string Value 73 | ) 74 | { 75 | if(Document.ExtGStateArray == null) Document.ExtGStateArray = new List(); 76 | 77 | // search list for a duplicate 78 | int Index = Document.ExtGStateArray.BinarySearch(new PdfExtGState(Key, Value)); 79 | 80 | // this value is a duplicate 81 | if(Index >= 0) return Document.ExtGStateArray[Index]; 82 | 83 | // new blend object 84 | PdfExtGState ExtGState = new PdfExtGState(Document, Key, Value); 85 | 86 | // save new string in array 87 | Document.ExtGStateArray.Insert(~Index, ExtGState); 88 | 89 | // update dictionary 90 | ExtGState.Dictionary.Add(Key, Value); 91 | 92 | // exit 93 | return ExtGState; 94 | } 95 | 96 | /// 97 | /// Compare two PdfExtGState objects. 98 | /// 99 | /// Other object. 100 | /// Compare result. 101 | public int CompareTo 102 | ( 103 | PdfExtGState Other 104 | ) 105 | { 106 | int Cmp = string.Compare(this.Key, Other.Key); 107 | if(Cmp != 0) return Cmp; 108 | return string.Compare(this.Value, Other.Value); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfImageControl.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfImageControl 7 | // PDF Image control. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | using System.Drawing; 28 | using System.Drawing.Imaging; 29 | using System.IO; 30 | using System.Text; 31 | 32 | namespace PdfFileWriter 33 | { 34 | /// 35 | /// PdfImageControl is obolete. See latest documentation 36 | /// 37 | public class PdfImageControl 38 | { 39 | #pragma warning disable 1591 40 | private const bool ObsoleteError = false; 41 | private const string ObsoleteMsg = "This PdfImageControl class is obsolete. See latest documentation."; 42 | 43 | [Obsolete(ObsoleteMsg, ObsoleteError)] 44 | public Rectangle CropRect; 45 | 46 | [Obsolete(ObsoleteMsg, ObsoleteError)] 47 | public RectangleF CropPercent; 48 | 49 | [Obsolete(ObsoleteMsg, ObsoleteError)] 50 | public bool ReverseBW; 51 | 52 | [Obsolete(ObsoleteMsg, ObsoleteError)] 53 | public double Resolution; 54 | 55 | [Obsolete(ObsoleteMsg, ObsoleteError)] 56 | public SaveImageAs SaveAs; 57 | 58 | [Obsolete(ObsoleteMsg, ObsoleteError)] 59 | public const int DefaultQuality = -1; 60 | 61 | [Obsolete(ObsoleteMsg, ObsoleteError)] 62 | public PdfImageControl() 63 | { 64 | CropRect = Rectangle.Empty; 65 | CropPercent = RectangleF.Empty; 66 | ReverseBW = false; 67 | _GrayToBWCutoff = 50; 68 | Resolution = 0.0; 69 | _ImageQuality = DefaultQuality; 70 | SaveAs = SaveImageAs.Jpeg; 71 | return; 72 | } 73 | 74 | [Obsolete(ObsoleteMsg, ObsoleteError)] 75 | public int ImageQuality 76 | { 77 | get 78 | { 79 | return _ImageQuality; 80 | } 81 | set 82 | { 83 | // set image quality 84 | if(value != DefaultQuality && (value < 0 || value > 100)) throw new ApplicationException("PdfImageControl.ImageQuality must be DefaultQuality or 0 to 100"); 85 | _ImageQuality = value; 86 | return; 87 | } 88 | } 89 | internal int _ImageQuality; 90 | 91 | [Obsolete(ObsoleteMsg, ObsoleteError)] 92 | public int GrayToBWCutoff 93 | { 94 | get 95 | { 96 | return _GrayToBWCutoff; 97 | } 98 | set 99 | { 100 | if(value < 1 || value > 99) throw new ApplicationException("PdfImageControl.GrayToBWCutoff must be 1 to 99"); 101 | _GrayToBWCutoff = value; 102 | } 103 | } 104 | internal int _GrayToBWCutoff; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfBinaryWriter.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfBinaryWriter 7 | // Extension to standard C# BinaryWriter class. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | using System.IO; 28 | using System.Text; 29 | 30 | namespace PdfFileWriter 31 | { 32 | /// 33 | /// PDF binary writer class 34 | /// 35 | /// 36 | /// Extends .NET BinaryWriter class. 37 | /// 38 | public class PdfBinaryWriter : BinaryWriter 39 | { 40 | /// 41 | /// PDF binary writer constructor 42 | /// 43 | /// File or memory stream 44 | public PdfBinaryWriter 45 | ( 46 | Stream Stream 47 | ) : base(Stream, Encoding.UTF8) {} 48 | 49 | /// 50 | /// Write String. 51 | /// 52 | /// Input string 53 | /// 54 | /// Convert each character from two bytes to one byte. 55 | /// 56 | public void WriteString 57 | ( 58 | string Str 59 | ) 60 | { 61 | // byte array 62 | byte[] ByteArray = new byte[Str.Length]; 63 | 64 | // convert content from string to binary 65 | // do not use Encoding.ASCII.GetBytes(...) 66 | for(int Index = 0; Index < ByteArray.Length; Index++) ByteArray[Index] = (byte) Str[Index]; 67 | 68 | // write to pdf file 69 | Write(ByteArray); 70 | return; 71 | } 72 | 73 | /// 74 | /// Write StringBuilder. 75 | /// 76 | /// String builder input 77 | /// 78 | /// Convert each character from two bytes to one byte. 79 | /// 80 | public void WriteString 81 | ( 82 | StringBuilder Str 83 | ) 84 | { 85 | // byte array 86 | byte[] ByteArray = new byte[Str.Length]; 87 | 88 | // convert content from string to binary 89 | // do not use Encoding.ASCII.GetBytes(...) 90 | for(int Index = 0; Index < ByteArray.Length; Index++) ByteArray[Index] = (byte) Str[Index]; 91 | 92 | // write to pdf file 93 | Write(ByteArray); 94 | return; 95 | } 96 | 97 | /// 98 | /// Combine format string with write string. 99 | /// 100 | /// Standard format string 101 | /// Array of objects 102 | public void WriteFormat 103 | ( 104 | string FormatStr, 105 | params object[] List 106 | ) 107 | { 108 | string Str = string.Format(FormatStr, List); 109 | 110 | // byte array 111 | byte[] ByteArray = new byte[Str.Length]; 112 | 113 | // convert content from string to binary 114 | // do not use Encoding.ASCII.GetBytes(...) 115 | for(int Index = 0; Index < ByteArray.Length; Index++) ByteArray[Index] = (byte) Str[Index]; 116 | 117 | // write to pdf file 118 | Write(ByteArray); 119 | return; 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfXObject.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfXObject 7 | // PDF X Object resource class. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | using System.Drawing; 28 | 29 | namespace PdfFileWriter 30 | { 31 | /// 32 | /// PDF X object resource class 33 | /// 34 | public class PdfXObject : PdfContents 35 | { 36 | /// 37 | /// Bounding box rectangle 38 | /// 39 | public PdfRectangle Rect 40 | { 41 | get 42 | { 43 | return new PdfRectangle(BBox); 44 | } 45 | set 46 | { 47 | BBox = value; 48 | Dictionary.AddRectangle("/BBox", BBox); 49 | } 50 | } 51 | 52 | /// 53 | /// Bounding box left side 54 | /// 55 | public double Left 56 | { 57 | get 58 | { 59 | return BBox.Left; 60 | } 61 | set 62 | { 63 | BBox.Left = value; 64 | Dictionary.AddRectangle("/BBox", BBox); 65 | } 66 | } 67 | 68 | /// 69 | /// Bounding box bottom side 70 | /// 71 | public double Bottom 72 | { 73 | get 74 | { 75 | return BBox.Bottom; 76 | } 77 | set 78 | { 79 | BBox.Bottom = value; 80 | Dictionary.AddRectangle("/BBox", BBox); 81 | } 82 | } 83 | 84 | /// 85 | /// Bounding box right side 86 | /// 87 | public double Right 88 | { 89 | get 90 | { 91 | return BBox.Right; 92 | } 93 | set 94 | { 95 | BBox.Right = value; 96 | Dictionary.AddRectangle("/BBox", BBox); 97 | } 98 | } 99 | 100 | /// 101 | /// Bounding box top side 102 | /// 103 | public double Top 104 | { 105 | get 106 | { 107 | return BBox.Top; 108 | } 109 | set 110 | { 111 | BBox.Top = value; 112 | Dictionary.AddRectangle("/BBox", BBox); 113 | } 114 | } 115 | 116 | // bounding rectangle 117 | internal PdfRectangle BBox; 118 | 119 | /// 120 | /// PDF X Object constructor 121 | /// 122 | /// PDF document 123 | /// X Object width 124 | /// X Object height 125 | public PdfXObject 126 | ( 127 | PdfDocument Document, 128 | double Width = 1.0, 129 | double Height = 1.0 130 | ) : base(Document, "/XObject") 131 | { 132 | // create resource code 133 | ResourceCode = Document.GenerateResourceNumber('X'); 134 | 135 | // add subtype to dictionary 136 | Dictionary.Add("/Subtype", "/Form"); 137 | 138 | // set boundig box rectangle 139 | BBox = new PdfRectangle(0.0, 0.0, Width, Height); 140 | 141 | // bounding box 142 | Dictionary.AddRectangle("/BBox", BBox); 143 | return; 144 | } 145 | 146 | /// 147 | /// Layer control 148 | /// 149 | /// PdfLayer object 150 | public void LayerControl 151 | ( 152 | PdfObject Layer 153 | ) 154 | { 155 | Dictionary.AddIndirectReference("/OC", Layer); 156 | return; 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfWebLink.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfWebLink 7 | // PDF weblink class. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | using System.Collections.Generic; 28 | 29 | namespace PdfFileWriter 30 | { 31 | /// 32 | /// PDF Weblink class 33 | /// 34 | /// 35 | /// 36 | /// The library will make sure that all weblinks in the PDF file are unique. 37 | /// To create a weblink class you must use a static menthod. This method will 38 | /// create a new object for a new weblink. The mothod will return an 39 | /// existing object if it is a duplicate. 40 | /// 41 | /// 42 | public class PdfWebLink : PdfObject, IComparable 43 | { 44 | internal string WebLinkStr; 45 | 46 | // for search only 47 | private PdfWebLink 48 | ( 49 | string WebLinkStr 50 | ) 51 | { 52 | // save string 53 | this.WebLinkStr = WebLinkStr; 54 | 55 | // exit 56 | return; 57 | } 58 | 59 | // create new web link 60 | private PdfWebLink 61 | ( 62 | PdfDocument Document, 63 | string WebLinkStr 64 | ) : base(Document) 65 | { 66 | // save string 67 | this.WebLinkStr = WebLinkStr; 68 | 69 | // type of action uniform resource identifier 70 | Dictionary.Add("/S", "/URI"); 71 | 72 | // uniform resource identifier 73 | Dictionary.AddPdfString("/URI", WebLinkStr); 74 | 75 | // exit 76 | return; 77 | } 78 | 79 | /// 80 | /// Add a weblink 81 | /// 82 | /// PDF document 83 | /// Weblink text 84 | /// Weblink object 85 | /// 86 | /// 87 | /// The library will make sure that all weblinks in the PDF file are unique. 88 | /// To create a weblink class you must use a static menthod. This method will 89 | /// create a new object for a new weblink. The mothod will return an 90 | /// existing object if it is a duplicate. 91 | /// 92 | /// 93 | public static PdfWebLink AddWebLink 94 | ( 95 | PdfDocument Document, 96 | string WebLinkStr 97 | ) 98 | { 99 | // first time 100 | if(Document.WebLinkArray == null) Document.WebLinkArray = new List(); 101 | 102 | // search list for a duplicate 103 | int Index = Document.WebLinkArray.BinarySearch(new PdfWebLink(WebLinkStr)); 104 | 105 | // this string is a duplicate 106 | if(Index >= 0) return Document.WebLinkArray[Index]; 107 | 108 | // new link 109 | PdfWebLink WebLink = new PdfWebLink(Document, WebLinkStr); 110 | 111 | // save new string in array 112 | Document.WebLinkArray.Insert(~Index, WebLink); 113 | 114 | // exit 115 | return WebLink; 116 | } 117 | 118 | /// 119 | /// Compare two WebLinkStr objects. 120 | /// 121 | /// Other object. 122 | /// Compare result. 123 | public int CompareTo 124 | ( 125 | PdfWebLink Other 126 | ) 127 | { 128 | return string.Compare(WebLinkStr, Other.WebLinkStr); 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfShadingFunction.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfShadingFunction 7 | // Support class for both axial and radial shading resources. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | using System.Drawing; 28 | using SysMedia = System.Windows.Media; 29 | 30 | namespace PdfFileWriter 31 | { 32 | //////////////////////////////////////////////////////////////////// 33 | /// 34 | /// PDF shading function class 35 | /// 36 | /// 37 | /// PDF function to convert a number between 0 and 1 into a 38 | /// color red green and blue based on the sample color array. 39 | /// 40 | //////////////////////////////////////////////////////////////////// 41 | public class PdfShadingFunction : PdfObject 42 | { 43 | //////////////////////////////////////////////////////////////////// 44 | /// 45 | /// PDF Shading function constructor 46 | /// 47 | /// Document object parent of this function. 48 | /// Array of colors. 49 | //////////////////////////////////////////////////////////////////// 50 | public PdfShadingFunction 51 | ( 52 | PdfDocument Document, // PDF document object 53 | Color[] ColorArray // Array of colors. Minimum 2. 54 | ) : base(Document, ObjectType.Stream) 55 | { 56 | // build dictionary 57 | Constructorhelper(ColorArray.Length); 58 | 59 | // add color array to contents stream 60 | foreach(Color Color in ColorArray) 61 | { 62 | ObjectValueList.Add(Color.R); // red 63 | ObjectValueList.Add(Color.G); // green 64 | ObjectValueList.Add(Color.B); // blue 65 | } 66 | return; 67 | } 68 | 69 | /// 70 | /// PDF Shading function constructor 71 | /// 72 | /// Document object parent of this function. 73 | /// System.Windows.Media gradient brush 74 | public PdfShadingFunction 75 | ( 76 | PdfDocument Document, 77 | SysMedia.GradientBrush Brush 78 | ) : base(Document, ObjectType.Stream) 79 | { 80 | // build dictionary 81 | Constructorhelper(Brush.GradientStops.Count); 82 | 83 | // add color array to contents stream 84 | foreach(System.Windows.Media.GradientStop Stop in Brush.GradientStops) 85 | { 86 | ObjectValueList.Add(Stop.Color.R); // red 87 | ObjectValueList.Add(Stop.Color.G); // green 88 | ObjectValueList.Add(Stop.Color.B); // blue 89 | } 90 | return; 91 | } 92 | 93 | private void Constructorhelper 94 | ( 95 | int Length 96 | ) 97 | { 98 | // test for error 99 | if(Length < 2) throw new ApplicationException("Shading function color array must have two or more items"); 100 | 101 | // the shading function is a sampled function 102 | Dictionary.Add("/FunctionType", "0"); 103 | 104 | // input variable is between 0 and 1 105 | Dictionary.Add("/Domain", "[0 1]"); 106 | 107 | // output variables are red, green and blue color components between 0 and 1 108 | Dictionary.Add("/Range", "[0 1 0 1 0 1]"); 109 | 110 | // each color components in the stream is 8 bits 111 | Dictionary.Add("/BitsPerSample", "8"); 112 | 113 | // number of colors in the stream must be two or more 114 | Dictionary.AddFormat("/Size", "[{0}]", Length); 115 | return; 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfRectangle.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfRectangle 7 | // PDF rectangle class. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | 28 | namespace PdfFileWriter 29 | { 30 | //////////////////////////////////////////////////////////////////// 31 | /// 32 | /// PDF rectangle in double precision class 33 | /// 34 | /// 35 | /// Note: Microsoft rectangle is left, top, width and height. 36 | /// PDF rectangle is left, bottom, right and top. 37 | /// PDF numeric precision is double and Microsoft is Single. 38 | /// 39 | //////////////////////////////////////////////////////////////////// 40 | public class PdfRectangle 41 | { 42 | /// 43 | /// Gets or sets Left side. 44 | /// 45 | public double Left {get; set;} 46 | 47 | /// 48 | /// Gets or sets bottom side. 49 | /// 50 | public double Bottom {get; set;} 51 | 52 | /// 53 | /// Gets or sets right side. 54 | /// 55 | public double Right {get; set;} 56 | 57 | /// 58 | /// Gets or sets top side. 59 | /// 60 | public double Top {get; set;} 61 | 62 | /// 63 | /// Default constructor. 64 | /// 65 | public PdfRectangle() {} 66 | 67 | /// 68 | /// Constructor 69 | /// 70 | /// Left side 71 | /// Bottom side 72 | /// Right side 73 | /// Top side 74 | public PdfRectangle 75 | ( 76 | double Left, 77 | double Bottom, 78 | double Right, 79 | double Top 80 | ) 81 | { 82 | this.Left = Left; 83 | this.Bottom = Bottom; 84 | this.Right = Right; 85 | this.Top = Top; 86 | return; 87 | } 88 | 89 | /// 90 | /// Copy constructor 91 | /// 92 | /// Source rectangle 93 | public PdfRectangle 94 | ( 95 | PdfRectangle Rect 96 | ) 97 | { 98 | this.Left = Rect.Left; 99 | this.Bottom = Rect.Bottom; 100 | this.Right = Rect.Right; 101 | this.Top = Rect.Top; 102 | return; 103 | } 104 | 105 | /// 106 | /// Constructor for margin 107 | /// 108 | /// Single value for all sides 109 | public PdfRectangle 110 | ( 111 | double AllTheSame 112 | ) 113 | { 114 | Left = AllTheSame; 115 | Bottom = AllTheSame; 116 | Right = AllTheSame; 117 | Top = AllTheSame; 118 | return; 119 | } 120 | 121 | /// 122 | /// Constructor for margin 123 | /// 124 | /// Left and right value 125 | /// Top and bottom value 126 | public PdfRectangle 127 | ( 128 | double Hor, 129 | double Vert 130 | ) 131 | { 132 | Left = Hor; 133 | Bottom = Vert; 134 | Right = Hor; 135 | Top = Vert; 136 | return; 137 | } 138 | 139 | /// 140 | /// Gets width 141 | /// 142 | public double Width 143 | { 144 | get 145 | { 146 | return Right - Left; 147 | } 148 | } 149 | 150 | /// 151 | /// Gets height 152 | /// 153 | public double Height 154 | { 155 | get 156 | { 157 | return Top - Bottom; 158 | } 159 | } 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /PdfFileWriter/CreateMetafile.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // CreateMetafile 7 | // Create Metafile with graphics object. 8 | // It was used to test the PdfObject class with Metafile image. 9 | // 10 | // Uzi Granot 11 | // Version: 1.0 12 | // Date: April 1, 2013 13 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 14 | // 15 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 16 | // application are free software. 17 | // They is distributed under the Code Project Open License (CPOL). 18 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 19 | // the distribution specify the license agreement and other 20 | // conditions and notes. You must read this document and agree 21 | // with the conditions specified in order to use this software. 22 | // 23 | // For version history please refer to PdfDocument.cs 24 | // 25 | ///////////////////////////////////////////////////////////////////// 26 | 27 | using System; 28 | using System.Drawing; 29 | using System.Drawing.Drawing2D; 30 | using System.Drawing.Imaging; 31 | using System.IO; 32 | using System.Runtime.InteropServices; 33 | 34 | namespace PdfFileWriter 35 | { 36 | /// 37 | /// Create image metafile class 38 | /// 39 | public class CreateMetafile : IDisposable 40 | { 41 | /// 42 | /// Gets image metafile. 43 | /// 44 | public Metafile Metafile {get; protected set;} 45 | 46 | /// 47 | /// Gets graphics object form image metafile. 48 | /// 49 | public Graphics Graphics {get; protected set;} 50 | 51 | /// 52 | /// Create image metafile constructor 53 | /// 54 | /// Image width in pixels. 55 | /// Image height in pixels. 56 | public CreateMetafile 57 | ( 58 | int Width, 59 | int Height 60 | ) 61 | { 62 | using (MemoryStream Stream = new MemoryStream()) 63 | { 64 | using (Graphics MemoryGraphics = Graphics.FromHwndInternal(IntPtr.Zero)) 65 | { 66 | IntPtr deviceContextHandle = MemoryGraphics.GetHdc(); 67 | Metafile = new Metafile(Stream, deviceContextHandle, new RectangleF(0, 0, Width, Height), MetafileFrameUnit.Pixel, EmfType.EmfPlusOnly); 68 | MemoryGraphics.ReleaseHdc(); 69 | } 70 | } 71 | 72 | Graphics = Graphics.FromImage(Metafile); 73 | 74 | // Set everything to high quality 75 | Graphics.SmoothingMode = SmoothingMode.HighQuality; 76 | Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; 77 | Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; 78 | Graphics.CompositingQuality = CompositingQuality.HighQuality; 79 | Graphics.PageUnit = GraphicsUnit.Pixel; 80 | return; 81 | } 82 | 83 | [DllImport("gdi32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)] 84 | private static extern IntPtr CopyEnhMetaFile(IntPtr MetaFileHandle, IntPtr FileName); 85 | 86 | /// 87 | /// Save image metafile 88 | /// 89 | /// File name 90 | public void SaveMetafile 91 | ( 92 | string FileName 93 | ) 94 | { 95 | // Get a handle to the metafile 96 | IntPtr MetafileHandle = Metafile.GetHenhmetafile(); 97 | 98 | // allocate character table buffer in global memory (two bytes per char) 99 | IntPtr CharBuffer = Marshal.AllocHGlobal(2 * FileName.Length + 2); 100 | 101 | // move file name inclusing terminating zer0 to the buffer 102 | for(int Index = 0; Index < FileName.Length; Index++) Marshal.WriteInt16(CharBuffer, 2 * Index, (short) FileName[Index]); 103 | Marshal.WriteInt16(CharBuffer, 2 * FileName.Length, 0); 104 | 105 | // Export metafile to an image file 106 | CopyEnhMetaFile(MetafileHandle, CharBuffer); 107 | 108 | // free local buffer 109 | Marshal.FreeHGlobal(CharBuffer); 110 | return; 111 | } 112 | 113 | [DllImport("gdi32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)] 114 | private static extern IntPtr DeleteEnhMetaFile(IntPtr MetaFileHandle); 115 | 116 | /// 117 | /// Delete image metafile. 118 | /// 119 | public void DeleteMetafile() 120 | { 121 | // Get a handle to the metafile 122 | IntPtr MetafileHandle = Metafile.GetHenhmetafile(); 123 | 124 | // Delete the metafile from memory 125 | DeleteEnhMetaFile(MetafileHandle); 126 | return; 127 | } 128 | 129 | /// 130 | /// Dispose object 131 | /// 132 | public void Dispose() 133 | { 134 | if(Graphics != null) 135 | { 136 | Graphics.Dispose(); 137 | Graphics = null; 138 | } 139 | if(Metafile != null) 140 | { 141 | Metafile.Dispose(); 142 | Metafile = null; 143 | } 144 | return; 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfFileWriter.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {7B531568-9C87-4CC5-917D-28C43BCF5B38} 9 | Library 10 | Properties 11 | PdfFileWriter 12 | PdfFileWriter 13 | v4.6.2 14 | 512 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | bin\Debug\PdfFileWriter.XML 26 | false 27 | 28 | 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | bin\Release\PdfFileWriter.XML 36 | false 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | Component 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 108 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfInfo.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfInfo 7 | // PDF document information dictionary. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | 28 | namespace PdfFileWriter 29 | { 30 | /// 31 | /// PDF document information dictionary 32 | /// 33 | public class PdfInfo : PdfObject 34 | { 35 | /// 36 | /// Constructor for PdfInfo class 37 | /// 38 | /// Main document class 39 | /// PdfInfo object 40 | /// 41 | /// The constructor initialize the /Info dictionary with 4 key value pairs. 42 | /// 43 | /// Creation date set to current local system date 44 | /// Modification date set to current local system date 45 | /// Creator is PdfFileWriter C# Class Library Version No 46 | /// Producer is PdfFileWriter C# Class Library Version No 47 | /// 48 | /// 49 | public static PdfInfo CreatePdfInfo 50 | ( 51 | PdfDocument Document 52 | ) 53 | { 54 | // create a new default info object 55 | if(Document.InfoObject == null) 56 | { 57 | // create and add info object to trailer dictionary 58 | Document.InfoObject = new PdfInfo(Document); 59 | Document.TrailerDict.AddIndirectReference("/Info", Document.InfoObject); 60 | } 61 | 62 | // exit with either existing object or a new one 63 | return Document.InfoObject; 64 | } 65 | 66 | /// 67 | /// Protected constructor 68 | /// 69 | /// Main document object 70 | protected PdfInfo 71 | ( 72 | PdfDocument Document 73 | ) : base(Document, ObjectType.Dictionary) 74 | { 75 | // set creation and modify dates 76 | DateTime LocalTime = DateTime.Now; 77 | CreationDate(LocalTime); 78 | ModDate(LocalTime); 79 | 80 | // set creator and producer 81 | Creator("PdfFileWriter C# Class Library Version " + PdfDocument.RevisionNumber); 82 | Producer("PdfFileWriter C# Class Library Version " + PdfDocument.RevisionNumber); 83 | return; 84 | } 85 | 86 | /// 87 | /// Sets document creation date and time 88 | /// 89 | /// Creation date and time 90 | public void CreationDate 91 | ( 92 | DateTime Date 93 | ) 94 | { 95 | Dictionary.AddPdfString("/CreationDate", string.Format("D:{0}", Date.ToString("yyyyMMddHHmmss"))); 96 | return; 97 | } 98 | 99 | /// 100 | /// Sets document last modify date and time 101 | /// 102 | /// Modify date and time 103 | public void ModDate 104 | ( 105 | DateTime Date 106 | ) 107 | { 108 | Dictionary.AddPdfString("/ModDate", string.Format("D:{0}", Date.ToString("yyyyMMddHHmmss"))); 109 | return; 110 | } 111 | 112 | /// 113 | /// Sets document title 114 | /// 115 | /// Title 116 | public void Title 117 | ( 118 | string Title 119 | ) 120 | { 121 | Dictionary.AddPdfString("/Title", Title); 122 | return; 123 | } 124 | 125 | /// 126 | /// Sets document author 127 | /// 128 | /// Author 129 | public void Author 130 | ( 131 | string Author 132 | ) 133 | { 134 | Dictionary.AddPdfString("/Author", Author); 135 | return; 136 | } 137 | 138 | /// 139 | /// Sets document subject 140 | /// 141 | /// Subject 142 | public void Subject 143 | ( 144 | string Subject 145 | ) 146 | { 147 | Dictionary.AddPdfString("/Subject", Subject); 148 | return; 149 | } 150 | 151 | /// 152 | /// Sets keywords associated with the document 153 | /// 154 | /// Keywords list 155 | public void Keywords 156 | ( 157 | string Keywords 158 | ) 159 | { 160 | Dictionary.AddPdfString("/Keywords", Keywords); 161 | return; 162 | } 163 | 164 | /// 165 | /// Sets the name of the application that created the document 166 | /// 167 | /// Creator 168 | public void Creator 169 | ( 170 | string Creator 171 | ) 172 | { 173 | Dictionary.AddPdfString("/Creator", Creator); 174 | return; 175 | } 176 | 177 | /// 178 | /// Sets the name of the application that produced the document 179 | /// 180 | /// Producer 181 | public void Producer 182 | ( 183 | string Producer 184 | ) 185 | { 186 | Dictionary.AddPdfString("/Producer", Producer); 187 | return; 188 | } 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /PdfFileWriter/ImageSizePos.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // ImageSizePoos 7 | // Support class for image aspect ratio calculations. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | using System.Drawing; 28 | 29 | namespace PdfFileWriter 30 | { 31 | ///////////////////////////////////////////////////////////////////// 32 | /// 33 | /// Image size and position class 34 | /// 35 | /// 36 | /// Delta X and Y are the adjustments to image position to 37 | /// meet the content alignment request. 38 | /// 39 | ///////////////////////////////////////////////////////////////////// 40 | public static class ImageSizePos 41 | { 42 | /// 43 | /// Adjust image drawing area for both aspect ratio and content alignment 44 | /// 45 | /// Image width in pixels. 46 | /// Image height in pixels. 47 | /// Drawing area rectangle 48 | /// Content alignment. 49 | /// Adjusted drawing area rectangle 50 | public static PdfRectangle ImageArea 51 | ( 52 | int ImageWidthPix, 53 | int ImageHeightPix, 54 | PdfRectangle DrawArea, 55 | ContentAlignment Alignment 56 | ) 57 | { 58 | return ImageArea(ImageWidthPix, ImageHeightPix, DrawArea.Left, DrawArea.Bottom, DrawArea.Width, DrawArea.Height, Alignment); 59 | } 60 | 61 | //////////////////////////////////////////////////////////////////// 62 | /// 63 | /// Adjust image drawing area for both aspect ratio and content alignment 64 | /// 65 | /// Image width in pixels. 66 | /// Image height in pixels. 67 | /// Drawing area left side. 68 | /// Drawing area bottom side. 69 | /// Drawing area width. 70 | /// Drawing area height. 71 | /// Content alignment. 72 | /// Adjusted drawing area rectangle 73 | //////////////////////////////////////////////////////////////////// 74 | public static PdfRectangle ImageArea 75 | ( 76 | int ImageWidthPix, 77 | int ImageHeightPix, 78 | double DrawAreaLeft, 79 | double DrawAreaBottom, 80 | double DrawAreaWidth, 81 | double DrawAreaHeight, 82 | ContentAlignment Alignment 83 | ) 84 | { 85 | double DeltaX = 0; 86 | double DeltaY = 0; 87 | double Width; 88 | double Height; 89 | 90 | // calculate height to fit aspect ratio 91 | Height = DrawAreaWidth * ImageHeightPix / ImageWidthPix; 92 | if(Height <= DrawAreaHeight) 93 | { 94 | Width = DrawAreaWidth; 95 | if(Height < DrawAreaHeight) 96 | { 97 | if(Alignment == ContentAlignment.MiddleLeft || Alignment == ContentAlignment.MiddleCenter || Alignment == ContentAlignment.MiddleRight) 98 | { 99 | DeltaY = 0.5 * (DrawAreaHeight - Height); 100 | } 101 | else if(Alignment == ContentAlignment.TopLeft || Alignment == ContentAlignment.TopCenter || Alignment == ContentAlignment.TopRight) 102 | { 103 | DeltaY = DrawAreaHeight - Height; 104 | } 105 | } 106 | } 107 | // calculate width to fit aspect ratio 108 | else 109 | { 110 | Width = DrawAreaHeight * ImageWidthPix / ImageHeightPix; 111 | Height = DrawAreaHeight; 112 | if(Width < DrawAreaWidth) 113 | { 114 | if(Alignment == ContentAlignment.TopCenter || Alignment == ContentAlignment.MiddleCenter || Alignment == ContentAlignment.BottomCenter) 115 | { 116 | DeltaX = 0.5 * (DrawAreaWidth - Width); 117 | } 118 | else if(Alignment == ContentAlignment.TopRight || Alignment == ContentAlignment.MiddleRight || Alignment == ContentAlignment.BottomRight) 119 | { 120 | DeltaX = DrawAreaWidth - Width; 121 | } 122 | } 123 | } 124 | 125 | // position rectangle 126 | return new PdfRectangle(DrawAreaLeft + DeltaX, DrawAreaBottom + DeltaY, DrawAreaLeft + DeltaX + Width, DrawAreaBottom + DeltaY + Height); 127 | } 128 | 129 | //////////////////////////////////////////////////////////////////// 130 | /// 131 | /// Calculate best fit to preserve aspect ratio 132 | /// 133 | /// Image width in pixels. 134 | /// Image height in pixels. 135 | /// Drawing area width. 136 | /// Drawing area height. 137 | /// Image size in user units. 138 | //////////////////////////////////////////////////////////////////// 139 | public static SizeD ImageSize 140 | ( 141 | int ImageWidthPix, 142 | int ImageHeightPix, 143 | double DrawAreaWidth, 144 | double DrawAreaHeight 145 | ) 146 | { 147 | SizeD OutputSize = new SizeD(); 148 | OutputSize.Height = DrawAreaWidth * ImageHeightPix / ImageWidthPix; 149 | if(OutputSize.Height <= DrawAreaHeight) 150 | { 151 | OutputSize.Width = DrawAreaWidth; 152 | } 153 | else 154 | { 155 | OutputSize.Width = DrawAreaHeight * ImageWidthPix / ImageHeightPix; 156 | OutputSize.Height = DrawAreaHeight; 157 | } 158 | return OutputSize; 159 | } 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfLayers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace PdfFileWriter 8 | { 9 | /// 10 | /// Layers list mode enumeration 11 | /// 12 | public enum ListMode 13 | { 14 | /// 15 | /// List all layers 16 | /// 17 | AllPages, 18 | 19 | /// 20 | /// List layers for visible pages 21 | /// 22 | VisiblePages, 23 | } 24 | 25 | /// 26 | /// PdfLayers control class 27 | /// 28 | public class PdfLayers : PdfObject 29 | { 30 | /// 31 | /// Layers name 32 | /// 33 | public string Name {get; set;} 34 | 35 | /// 36 | /// Layers list mode 37 | /// 38 | public ListMode ListMode {get; set;} 39 | 40 | internal List LayerList; 41 | internal List OrderList; 42 | 43 | /// 44 | /// Layers constructor 45 | /// 46 | /// PDF Document 47 | /// Layers name 48 | public PdfLayers 49 | ( 50 | PdfDocument Document, 51 | string Name 52 | ) : base(Document) 53 | { 54 | // Make sure it is done only once 55 | if(Document.Layers != null) throw new ApplicationException("PdfLayers is already defined"); 56 | 57 | // save arguments 58 | this.Name = Name; 59 | 60 | // save this object within the document object 61 | Document.Layers = this; 62 | 63 | // create layers empty list for all layers 64 | LayerList = new List(); 65 | OrderList = new List(); 66 | return; 67 | } 68 | 69 | /// 70 | /// Layer's display order in layers panel 71 | /// 72 | /// Layer object 73 | public void DisplayOrder 74 | ( 75 | PdfLayer Layer 76 | ) 77 | { 78 | OrderList.Add(Layer); 79 | return; 80 | } 81 | 82 | /// 83 | /// Layer's display order group start marker 84 | /// 85 | /// Optional group name 86 | public void DisplayOrderStartGroup 87 | ( 88 | string GroupName = "" 89 | ) 90 | { 91 | OrderList.Add(GroupName); 92 | return; 93 | } 94 | 95 | /// 96 | /// Layer's display order group end marker 97 | /// 98 | public void DisplayOrderEndGroup() 99 | { 100 | OrderList.Add(0); 101 | return; 102 | } 103 | 104 | // add layers object to document catalog 105 | internal void CreateDictionary() 106 | { 107 | // build array of all layers 108 | StringBuilder AllLayers = new StringBuilder("["); 109 | StringBuilder LockedLayers = new StringBuilder("["); 110 | List RadioButtons = new List(); 111 | foreach(PdfLayer Layer in LayerList) 112 | { 113 | AllLayers.AppendFormat("{0} 0 R ", Layer.ObjectNumber); 114 | if(Layer.Locked == LockLayer.Locked) LockedLayers.AppendFormat("{0} 0 R ", Layer.ObjectNumber); 115 | if(!string.IsNullOrWhiteSpace(Layer.RadioButton)) RadioButtons.Add(Layer); 116 | } 117 | AllLayers.Length--; 118 | AllLayers.Append("]"); 119 | 120 | // add all layers array to the dictionary 121 | Dictionary.Add("/OCGs", AllLayers.ToString()); 122 | 123 | // create default /D dictionary 124 | PdfDictionary DefaultDict = new PdfDictionary(Document); 125 | 126 | // name 127 | DefaultDict.AddPdfString("/Name", Name); 128 | 129 | // list mode 130 | DefaultDict.AddName("/ListMode", ListMode.ToString()); 131 | 132 | // build array of locked layers 133 | LockedLayers.Length--; 134 | if(LockedLayers.Length != 0) 135 | { 136 | LockedLayers.Append("]"); 137 | DefaultDict.Add("/Locked", LockedLayers.ToString()); 138 | } 139 | 140 | // add array to OCPD 141 | if(OrderList.Count == 0) 142 | { 143 | DefaultDict.Add("/Order", AllLayers.ToString()); 144 | } 145 | else 146 | { 147 | StringBuilder OrderArray = new StringBuilder("["); 148 | foreach(object Item in OrderList) 149 | { 150 | if(Item.GetType() == typeof(PdfLayer)) 151 | { 152 | OrderArray.AppendFormat("{0} 0 R ", ((PdfLayer) Item).ObjectNumber); 153 | } 154 | else if(Item.GetType() == typeof(string)) 155 | { 156 | if(OrderArray[OrderArray.Length - 1] == ' ') OrderArray.Length--; 157 | OrderArray.Append("["); 158 | if((string) Item != "") OrderArray.Append(Document.TextToPdfString((string) Item, this)); 159 | } 160 | else if(Item.GetType() == typeof(int) && ((int) Item) == 0) 161 | { 162 | if(OrderArray[OrderArray.Length - 1] == ' ') OrderArray.Length--; 163 | OrderArray.Append("]"); 164 | } 165 | } 166 | if(OrderArray[OrderArray.Length - 1] == ' ') OrderArray.Length--; 167 | OrderArray.Append("]"); 168 | DefaultDict.Add("/Order", OrderArray.ToString()); 169 | } 170 | 171 | // radio buttons 172 | if(RadioButtons.Count > 1) 173 | { 174 | RadioButtons.Sort(); 175 | StringBuilder RBArray = new StringBuilder("["); 176 | int End = RadioButtons.Count; 177 | int Ptr1; 178 | for(int Ptr = 0; Ptr < End; Ptr = Ptr1) 179 | { 180 | // count how many layers have the same radio button name 181 | for(Ptr1 = Ptr + 1; Ptr1 < End; Ptr1++) 182 | { 183 | if(string.Compare(RadioButtons[Ptr].RadioButton, RadioButtons[Ptr1].RadioButton) != 0) break; 184 | } 185 | 186 | // single radio button, ignore as far as radio button property 187 | if(Ptr1 - Ptr < 2) continue; 188 | 189 | // build array of layers with the same radio button name 190 | RBArray.Append("["); 191 | int Ptr3 = -1; 192 | for(int Ptr2 = Ptr; Ptr2 < Ptr1; Ptr2++) 193 | { 194 | RBArray.AppendFormat("{0} 0 R ", RadioButtons[Ptr2].ObjectNumber); 195 | if(RadioButtons[Ptr2].State == LayerState.On) 196 | { 197 | if(Ptr3 < 0) 198 | { 199 | Ptr3 = Ptr2; 200 | } 201 | else 202 | { 203 | RadioButtons[Ptr2].State = LayerState.Off; 204 | } 205 | } 206 | } 207 | RBArray.Length--; 208 | RBArray.Append("]"); 209 | } 210 | if(RBArray.Length > 1) 211 | { 212 | RBArray.Append("]"); 213 | DefaultDict.Add("/RBGroups", RBArray.ToString()); 214 | } 215 | } 216 | 217 | StringBuilder OffLayers = new StringBuilder("["); 218 | foreach(PdfLayer Layer in LayerList) 219 | { 220 | if(Layer.State == LayerState.Off) OffLayers.AppendFormat("{0} 0 R ", Layer.ObjectNumber); 221 | } 222 | 223 | // build array of all initially off 224 | OffLayers.Length--; 225 | if(OffLayers.Length != 0) 226 | { 227 | OffLayers.Append("]"); 228 | DefaultDict.Add("/OFF", OffLayers.ToString()); 229 | } 230 | 231 | // add default dictionary 232 | Dictionary.AddDictionary("/D", DefaultDict); 233 | return; 234 | } 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfAnnotation.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfAnnotation 7 | // PDF Annotation class. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | using System.Collections.Generic; 28 | 29 | namespace PdfFileWriter 30 | { 31 | /// 32 | /// PDF Annotation class 33 | /// 34 | public class PdfAnnotation : PdfObject 35 | { 36 | /// 37 | /// Layer control 38 | /// 39 | public PdfLayer LayerControl = null; 40 | 41 | internal PdfPage AnnotPage; 42 | internal PdfRectangle AnnotRect; 43 | internal AnnotAction AnnotAction; 44 | 45 | /// 46 | /// PdfAnnotation constructor 47 | /// 48 | /// Page object 49 | /// Annotation rectangle 50 | /// Annotation action 51 | internal PdfAnnotation 52 | ( 53 | PdfPage AnnotPage, 54 | PdfRectangle AnnotRect, 55 | AnnotAction AnnotAction 56 | ) : base(AnnotPage.Document) 57 | { 58 | // save arguments 59 | this.AnnotPage = AnnotPage; 60 | this.AnnotRect = AnnotRect; 61 | this.AnnotAction = AnnotAction; 62 | 63 | // annotation subtype 64 | Dictionary.Add("/Subtype", AnnotAction.Subtype); 65 | 66 | // area rectangle on the page 67 | Dictionary.AddRectangle("/Rect", AnnotRect); 68 | 69 | // annotation flags. value of 4 = Bit position 3 print 70 | Dictionary.Add("/F", "4"); 71 | 72 | // border style dictionary. If /BS with /W 0 is not specified, the annotation will have a thin border 73 | Dictionary.Add("/BS", "<>"); 74 | 75 | // web link 76 | if(AnnotAction.GetType() == typeof(AnnotWebLink)) 77 | { 78 | Dictionary.AddIndirectReference("/A", PdfWebLink.AddWebLink(Document, ((AnnotWebLink) AnnotAction).WebLinkStr)); 79 | } 80 | 81 | // jump to destination 82 | else if(AnnotAction.GetType() == typeof(AnnotLinkAction)) 83 | { 84 | if(Document.LinkAnnotArray == null) Document.LinkAnnotArray = new List(); 85 | Document.LinkAnnotArray.Add(this); 86 | } 87 | 88 | // display video or play sound 89 | else if(AnnotAction.GetType() == typeof(AnnotDisplayMedia)) 90 | { 91 | PdfDisplayMedia DisplayMedia = ((AnnotDisplayMedia) AnnotAction).DisplayMedia; 92 | 93 | // action reference dictionary 94 | Dictionary.AddIndirectReference("/A", DisplayMedia); 95 | 96 | // add page reference 97 | Dictionary.AddIndirectReference("/P", AnnotPage); 98 | 99 | // add annotation reference 100 | DisplayMedia.Dictionary.AddIndirectReference("/AN", this); 101 | } 102 | 103 | // file attachment 104 | else if(AnnotAction.GetType() == typeof(AnnotFileAttachment)) 105 | { 106 | // add file attachment reference 107 | AnnotFileAttachment File = (AnnotFileAttachment) AnnotAction; 108 | Dictionary.AddIndirectReference("/FS", File.EmbeddedFile); 109 | 110 | if(File.Icon != FileAttachIcon.NoIcon) 111 | { 112 | // icon 113 | Dictionary.AddName("/Name", File.Icon.ToString()); 114 | } 115 | else 116 | { 117 | // no icon 118 | PdfXObject XObject = new PdfXObject(Document, AnnotRect.Right, AnnotRect.Top); 119 | Dictionary.AddFormat("/AP", "<>", XObject.ObjectNumber); 120 | } 121 | } 122 | 123 | // sticky notes 124 | else if(AnnotAction.GetType() == typeof(AnnotStickyNote)) 125 | { 126 | // short cut 127 | AnnotStickyNote StickyNote = (AnnotStickyNote) AnnotAction; 128 | 129 | // icon 130 | Dictionary.AddName("/Name", StickyNote.Icon.ToString()); 131 | 132 | // action reference dictionary 133 | Dictionary.AddPdfString("/Contents", StickyNote.Note); 134 | } 135 | 136 | // add annotation object to page dictionary 137 | PdfKeyValue KeyValue = AnnotPage.Dictionary.GetValue("/Annots"); 138 | if(KeyValue == null) 139 | { 140 | AnnotPage.Dictionary.AddFormat("/Annots", "[{0} 0 R]", ObjectNumber); 141 | } 142 | 143 | else 144 | { 145 | AnnotPage.Dictionary.Add("/Annots", ((string) KeyValue.Value).Replace("]", string.Format(" {0} 0 R]", ObjectNumber))); 146 | } 147 | 148 | // exit 149 | return; 150 | } 151 | 152 | /// 153 | /// Gets a copy of the annotation rectangle 154 | /// 155 | public PdfRectangle AnnotationRect 156 | { 157 | get 158 | { 159 | return new PdfRectangle(AnnotRect); 160 | } 161 | } 162 | 163 | /// 164 | /// Activate annotation when page becomes visible. 165 | /// 166 | /// Activate or not-activate annotation. 167 | public void ActivateActionWhenPageIsVisible 168 | ( 169 | bool Activate 170 | ) 171 | { 172 | // applicable to screen action 173 | if(AnnotAction.GetType() == typeof(AnnotDisplayMedia)) 174 | { 175 | // play video when page becomes visible 176 | if(Activate) Dictionary.AddFormat("/AA", "<>", ((AnnotDisplayMedia) AnnotAction).DisplayMedia.ObjectNumber); 177 | else Dictionary.Remove("/AA"); 178 | } 179 | return; 180 | } 181 | 182 | /// 183 | /// Display border around annotation rectangle. 184 | /// 185 | /// Border width 186 | public void DisplayBorder 187 | ( 188 | double BorderWidth 189 | ) 190 | { 191 | // see page 611 section 8.4 192 | Dictionary.AddFormat("/BS", "<>", ToPt(BorderWidth)); 193 | return; 194 | } 195 | 196 | /// 197 | /// Annotation rectangle appearance 198 | /// 199 | /// PDF X Object 200 | public void Appearance 201 | ( 202 | PdfXObject AppearanceDixtionary 203 | ) 204 | { 205 | Dictionary.AddFormat("/AP", "<>", AppearanceDixtionary.ObjectNumber); 206 | return; 207 | } 208 | 209 | //////////////////////////////////////////////////////////////////// 210 | // Write object to PDF file 211 | //////////////////////////////////////////////////////////////////// 212 | internal override void WriteObjectToPdfFile() 213 | { 214 | // layer control 215 | if(LayerControl != null) Dictionary.AddIndirectReference("/OC", LayerControl); 216 | 217 | // call PdfObject routine 218 | base.WriteObjectToPdfFile(); 219 | 220 | // exit 221 | return; 222 | } 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfEmbeddedFile.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfEmbeddedFile 7 | // PDF embedded file class. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | using System.IO; 28 | using System.Collections.Generic; 29 | 30 | namespace PdfFileWriter 31 | { 32 | /// 33 | /// PDF Embedded file class 34 | /// 35 | public class PdfEmbeddedFile : PdfObject, IComparable 36 | { 37 | /// 38 | /// Gets file name 39 | /// 40 | public string FileName {get; private set;} 41 | 42 | /// 43 | /// Gets Mime type 44 | /// 45 | /// 46 | /// 47 | /// The PDF embedded file translates the file extension into mime type string. 48 | /// If the translation fails the MimeType is set to null. 49 | /// 50 | /// 51 | public string MimeType {get; private set;} 52 | 53 | private PdfEmbeddedFile() {} 54 | 55 | private PdfEmbeddedFile 56 | ( 57 | PdfDocument Document, 58 | string FileName, 59 | string PdfFileName 60 | ) : base(Document, ObjectType.Dictionary, "/Filespec") 61 | { 62 | // save file name 63 | this.FileName = FileName; 64 | 65 | // test exitance 66 | if(!File.Exists(FileName)) throw new ApplicationException("Embedded file " + FileName + " does not exist"); 67 | 68 | // get file length 69 | FileInfo FI = new FileInfo(FileName); 70 | if(FI.Length > int.MaxValue - 4095) throw new ApplicationException("Embedded file " + FileName + " too long"); 71 | int FileLength = (int) FI.Length; 72 | 73 | // translate file extension to mime type string 74 | MimeType = ExtToMime.TranslateExtToMime(FI.Extension); 75 | 76 | // create embedded file object 77 | PdfObject EmbeddedFile = new PdfObject(Document, ObjectType.Stream, "/EmbeddedFile"); 78 | 79 | // save uncompressed file length 80 | EmbeddedFile.Dictionary.AddFormat("/Params", "<>", FileLength); 81 | 82 | // file data content byte array 83 | EmbeddedFile.ObjectValueArray = new byte[FileLength]; 84 | 85 | // load all the file's data 86 | FileStream DataStream = null; 87 | try 88 | { 89 | // open the file 90 | DataStream = new FileStream(FileName, FileMode.Open, FileAccess.Read); 91 | 92 | // read all the file 93 | if(DataStream.Read(EmbeddedFile.ObjectValueArray, 0, FileLength) != FileLength) throw new Exception(); 94 | } 95 | 96 | // loading file failed 97 | catch(Exception) 98 | { 99 | throw new ApplicationException("Invalid media file: " + FileName); 100 | } 101 | 102 | // close the file 103 | DataStream.Close(); 104 | 105 | // debug 106 | if(Document.Debug) EmbeddedFile.ObjectValueArray = Document.TextToByteArray("*** MEDIA FILE PLACE HOLDER ***"); 107 | 108 | // write stream 109 | EmbeddedFile.WriteObjectToPdfFile(); 110 | 111 | // file spec object type 112 | Dictionary.Add("/Type", "/Filespec"); 113 | 114 | // PDF file name 115 | if(string.IsNullOrWhiteSpace(PdfFileName)) PdfFileName = FI.Name; 116 | Dictionary.AddPdfString("/F", PdfFileName); 117 | Dictionary.AddPdfString("/UF", PdfFileName); 118 | 119 | // add reference 120 | Dictionary.AddFormat("/EF", "<>", EmbeddedFile.ObjectNumber); 121 | return; 122 | } 123 | 124 | private PdfEmbeddedFile 125 | ( 126 | string FileName 127 | ) 128 | { 129 | // save file name 130 | this.FileName = FileName; 131 | return; 132 | } 133 | 134 | /// 135 | /// PDF embedded file class constructor 136 | /// 137 | /// Current document 138 | /// File name 139 | /// PDF file name (see remarks) 140 | /// PdfEmbeddedFile object 141 | /// 142 | /// 143 | /// FileName is the name of the source file on the hard disk. 144 | /// PDFFileName is the name of the as saved within the PDF document file. 145 | /// If PDFFileName is not given or it is set to null, the class takes 146 | /// the hard disk's file name without the path. 147 | /// 148 | /// 149 | public static PdfEmbeddedFile CreateEmbeddedFile 150 | ( 151 | PdfDocument Document, 152 | string FileName, 153 | string PdfFileName = null 154 | ) 155 | { 156 | // first time 157 | if(Document.EmbeddedFileArray == null) Document.EmbeddedFileArray = new List(); 158 | 159 | // search list for a duplicate 160 | int Index = Document.EmbeddedFileArray.BinarySearch(new PdfEmbeddedFile(FileName)); 161 | 162 | // this is a duplicate 163 | if(Index >= 0) return Document.EmbeddedFileArray[Index]; 164 | 165 | // new object 166 | PdfEmbeddedFile EmbeddedFile = new PdfEmbeddedFile(Document, FileName, PdfFileName); 167 | 168 | // save new string in array 169 | Document.EmbeddedFileArray.Insert(~Index, EmbeddedFile); 170 | 171 | // exit 172 | return EmbeddedFile; 173 | } 174 | 175 | /// 176 | /// Compare two PdfEmbededFile objects 177 | /// 178 | /// Other argument 179 | /// Compare result 180 | public int CompareTo 181 | ( 182 | PdfEmbeddedFile Other 183 | ) 184 | { 185 | return string.Compare(this.FileName, Other.FileName, true); 186 | } 187 | } 188 | 189 | internal class ExtToMime : IComparable 190 | { 191 | internal string Ext; 192 | internal string Mime; 193 | 194 | internal ExtToMime 195 | ( 196 | string Ext, 197 | string Mime 198 | ) 199 | { 200 | this.Ext = Ext; 201 | this.Mime = Mime; 202 | return; 203 | } 204 | 205 | internal static string TranslateExtToMime 206 | ( 207 | string Ext 208 | ) 209 | { 210 | int Index = Array.BinarySearch(ExtToMimeArray, new ExtToMime(Ext, null)); 211 | return Index >= 0 ? ExtToMimeArray[Index].Mime : null; 212 | } 213 | 214 | /// 215 | /// Compare ExtToMime records 216 | /// 217 | /// Other record 218 | /// 219 | public int CompareTo 220 | ( 221 | ExtToMime Other 222 | ) 223 | { 224 | return string.Compare(this.Ext, Other.Ext, true); 225 | } 226 | 227 | private static ExtToMime[] ExtToMimeArray = 228 | { 229 | new ExtToMime(".avi", "video/avi"), // Covers most Windows-compatible formats including .avi and .divx 230 | new ExtToMime(".divx", "video/avi"), // Covers most Windows-compatible formats including .avi and .divx 231 | new ExtToMime(".mpg", "video/mpeg"), // MPEG-1 video with multiplexed audio; Defined in RFC 2045 and RFC 2046 232 | new ExtToMime(".mpeg", "video/mpeg"), // MPEG-1 video with multiplexed audio; Defined in RFC 2045 and RFC 2046 233 | new ExtToMime(".mp4", "video/mp4"), // MP4 video; Defined in RFC 4337 234 | new ExtToMime(".mov", "video/quicktime"), // QuickTime video .mov 235 | new ExtToMime(".wav", "audio/wav"), // audio 236 | new ExtToMime(".wma", "audio/x-ms-wma"), // audio 237 | new ExtToMime(".mp3", "audio/mpeg"), // audio 238 | }; 239 | 240 | static ExtToMime() 241 | { 242 | Array.Sort(ExtToMimeArray); 243 | return; 244 | } 245 | } 246 | } 247 | -------------------------------------------------------------------------------- /PdfFileWriter/AnnotAction.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // AnnotAction 7 | // Annotation action classes 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | 28 | namespace PdfFileWriter 29 | { 30 | /// 31 | /// File attachement icon 32 | /// 33 | public enum FileAttachIcon 34 | { 35 | /// 36 | /// Graph 37 | /// 38 | Graph, 39 | 40 | /// 41 | /// Paperclip 42 | /// 43 | Paperclip, 44 | 45 | /// 46 | /// PushPin (default) 47 | /// 48 | PushPin, 49 | 50 | /// 51 | /// Tag 52 | /// 53 | Tag, 54 | 55 | /// 56 | /// no icon 57 | /// 58 | NoIcon, 59 | } 60 | 61 | /// 62 | /// Sticky note icon 63 | /// 64 | public enum StickyNoteIcon 65 | { 66 | /// 67 | /// Comment (note: no icon) 68 | /// 69 | Comment, 70 | /// 71 | /// Key 72 | /// 73 | Key, 74 | /// 75 | /// Note (default) 76 | /// 77 | Note, 78 | /// 79 | /// Help 80 | /// 81 | Help, 82 | /// 83 | /// New paragraph 84 | /// 85 | NewParagraph, 86 | /// 87 | /// Paragraph 88 | /// 89 | Paragraph, 90 | /// 91 | /// Insert 92 | /// 93 | Insert, 94 | } 95 | 96 | /// 97 | /// Annotation action base class 98 | /// 99 | public class AnnotAction 100 | { 101 | /// 102 | /// Gets the PDF PdfAnnotation object subtype 103 | /// 104 | public string Subtype {get; internal set;} 105 | 106 | internal AnnotAction 107 | ( 108 | string Subtype 109 | ) 110 | { 111 | this.Subtype = Subtype; 112 | return; 113 | } 114 | 115 | internal virtual bool IsEqual 116 | ( 117 | AnnotAction Other 118 | ) 119 | { 120 | throw new ApplicationException("AnnotAction IsEqual not implemented"); 121 | } 122 | 123 | internal static bool IsEqual 124 | ( 125 | AnnotAction One, 126 | AnnotAction Two 127 | ) 128 | { 129 | if(One == null && Two == null) return true; 130 | if(One == null && Two != null || One != null && Two == null || One.GetType() != Two.GetType()) return false; 131 | return One.IsEqual(Two); 132 | } 133 | } 134 | 135 | /// 136 | /// Web link annotation action 137 | /// 138 | public class AnnotWebLink : AnnotAction 139 | { 140 | /// 141 | /// Gets or sets web link string 142 | /// 143 | public string WebLinkStr {get; set;} 144 | 145 | /// 146 | /// Web link constructor 147 | /// 148 | /// Web link string 149 | public AnnotWebLink 150 | ( 151 | string WebLinkStr 152 | ) : base("/Link") 153 | { 154 | this.WebLinkStr = WebLinkStr; 155 | return; 156 | } 157 | 158 | internal override bool IsEqual 159 | ( 160 | AnnotAction Other 161 | ) 162 | { 163 | return WebLinkStr == ((AnnotWebLink) Other).WebLinkStr; 164 | } 165 | } 166 | 167 | /// 168 | /// Link to location marker within the document 169 | /// 170 | public class AnnotLinkAction : AnnotAction 171 | { 172 | /// 173 | /// Gets or sets the location marker name 174 | /// 175 | public string LocMarkerName {get; set;} 176 | 177 | /// 178 | /// Go to annotation action constructor 179 | /// 180 | /// Location marker name 181 | public AnnotLinkAction 182 | ( 183 | string LocMarkerName 184 | ) : base("/Link") 185 | { 186 | this.LocMarkerName = LocMarkerName; 187 | return; 188 | } 189 | 190 | internal override bool IsEqual 191 | ( 192 | AnnotAction Other 193 | ) 194 | { 195 | return this.LocMarkerName == ((AnnotLinkAction) Other).LocMarkerName; 196 | } 197 | } 198 | 199 | /// 200 | /// Display video or play sound class 201 | /// 202 | public class AnnotDisplayMedia : AnnotAction 203 | { 204 | /// 205 | /// Gets or sets PdfDisplayMedia object 206 | /// 207 | public PdfDisplayMedia DisplayMedia {get; set;} 208 | 209 | /// 210 | /// Display media annotation action constructor 211 | /// 212 | /// PdfDisplayMedia 213 | public AnnotDisplayMedia 214 | ( 215 | PdfDisplayMedia DisplayMedia 216 | ) : base("/Screen") 217 | { 218 | this.DisplayMedia = DisplayMedia; 219 | return; 220 | } 221 | 222 | internal override bool IsEqual 223 | ( 224 | AnnotAction Other 225 | ) 226 | { 227 | return this.DisplayMedia.MediaFile.FileName == ((AnnotDisplayMedia) Other).DisplayMedia.MediaFile.FileName; 228 | } 229 | } 230 | 231 | /// 232 | /// Save or view embedded file 233 | /// 234 | public class AnnotFileAttachment : AnnotAction 235 | { 236 | /// 237 | /// Gets or sets embedded file 238 | /// 239 | public PdfEmbeddedFile EmbeddedFile {get; set;} 240 | 241 | /// 242 | /// Gets or sets associated icon 243 | /// 244 | public FileAttachIcon Icon; 245 | 246 | /// 247 | /// File attachement constructor 248 | /// 249 | /// Embedded file 250 | /// Icon enumeration 251 | public AnnotFileAttachment 252 | ( 253 | PdfEmbeddedFile EmbeddedFile, 254 | FileAttachIcon Icon 255 | ) : base("/FileAttachment") 256 | { 257 | this.EmbeddedFile = EmbeddedFile; 258 | this.Icon = Icon; 259 | return; 260 | } 261 | 262 | /// 263 | /// File attachement constructor (no icon) 264 | /// 265 | /// Embedded file 266 | public AnnotFileAttachment 267 | ( 268 | PdfEmbeddedFile EmbeddedFile 269 | ) : base("/FileAttachment") 270 | { 271 | this.EmbeddedFile = EmbeddedFile; 272 | Icon = FileAttachIcon.NoIcon; 273 | return; 274 | } 275 | 276 | internal override bool IsEqual 277 | ( 278 | AnnotAction Other 279 | ) 280 | { 281 | AnnotFileAttachment FileAttach = (AnnotFileAttachment) Other; 282 | return EmbeddedFile.FileName == FileAttach.EmbeddedFile.FileName && Icon == FileAttach.Icon; 283 | } 284 | } 285 | 286 | /// 287 | /// Display sticky note 288 | /// 289 | public class AnnotStickyNote : AnnotAction 290 | { 291 | internal string Note; 292 | 293 | internal StickyNoteIcon Icon; 294 | 295 | /// 296 | /// Sticky note annotation action constructor 297 | /// 298 | /// Sticky note text 299 | /// Sticky note icon 300 | public AnnotStickyNote 301 | ( 302 | string Note, 303 | StickyNoteIcon Icon 304 | ) : base("/Text") 305 | { 306 | this.Note = Note; 307 | this.Icon = Icon; 308 | return; 309 | } 310 | 311 | internal override bool IsEqual 312 | ( 313 | AnnotAction Other 314 | ) 315 | { 316 | AnnotStickyNote StickyNote = (AnnotStickyNote) Other; 317 | return Note == StickyNote.Note && Icon == StickyNote.Icon; 318 | } 319 | } 320 | } 321 | -------------------------------------------------------------------------------- /PdfFileWriter/LocationMarker.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // Location marker 7 | // Internal class for managing document's location markers. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | using System.Text; 28 | using System.Collections.Generic; 29 | 30 | namespace PdfFileWriter 31 | { 32 | /// 33 | /// Location marker scope 34 | /// 35 | public enum LocMarkerScope 36 | { 37 | /// 38 | /// Location marker is local 39 | /// 40 | LocalDest, 41 | 42 | /// 43 | /// Location marker is global and local 44 | /// 45 | NamedDest, 46 | } 47 | 48 | /// 49 | /// Named destination fit constants 50 | /// 51 | public enum DestFit 52 | { 53 | /// 54 | /// Fit entire page. No arguments. 55 | /// 56 | /// 57 | /// Display the page designated by page, with its contents magnified 58 | /// just enough to fit the entire page within the window both horizontally 59 | /// and vertically. If the required horizontal and vertical magnification 60 | /// factors are different, use the smaller of the two, centering the page 61 | /// within the window in the other dimension. 62 | /// 63 | Fit, 64 | 65 | /// 66 | /// Display the page with top coordinate at top of the window. One argument. 67 | /// 68 | /// 69 | /// Display the page designated by page, with the vertical coordinate top 70 | /// positioned at the top edge of the window and the contents of the page 71 | /// magnified just enough to fit the entire width of the page within the 72 | /// window. A null value for top specifies that the current value of that 73 | /// parameter is to be retained unchanged. 74 | /// 75 | FitH, 76 | 77 | /// 78 | /// Display the page with left coordinate at left side of the window. One argument. 79 | /// 80 | /// 81 | /// Display the page designated by page, with the horizontal coordinate left 82 | /// positioned at the left edge of the window and the contents of the page 83 | /// magnified just enough to fit the entire height of the page within the 84 | /// window. A null value for left specifies that the current value of that 85 | /// parameter is to be retained unchanged. 86 | /// 87 | FitV, 88 | 89 | /// 90 | /// Display the page within rectangle. Four argument. 91 | /// 92 | /// 93 | /// Display the page designated by page, with its contents magnified just enough 94 | /// to fit the rectangle specified by the coordinates left, bottom, right, and 95 | /// topentirely within the window both horizontally and vertically. If the required 96 | /// horizontal and vertical magnification factors are different, use the smaller 97 | /// of the two, centering the rectangle within the window in the other dimension. 98 | /// A null value for any of the parameters may result in unpredictable behavior. 99 | /// 100 | FitR, 101 | 102 | /// 103 | /// Fit entire page including boundig box. No arguments. 104 | /// 105 | /// 106 | /// Display the page designated by page, with its contents magnified just enough 107 | /// to fit its bounding box entirely within the window both horizontally and 108 | /// vertically. If the required horizontal and vertical magnification factors are 109 | /// different, use the smaller of the two, centering the bounding box within the 110 | /// window in the other dimension. 111 | /// 112 | FitB, 113 | 114 | /// 115 | /// Display the page with top coordinate at top of the window. One argument. 116 | /// 117 | /// 118 | /// Display the page designated by page, with the vertical coordinate top positioned 119 | /// at the top edge of the window and the contents of the page magnified just enough 120 | /// to fit the entire width of its bounding box within the window. A null value for 121 | /// top specifies that the current value of that parameter is to be retained unchanged. 122 | /// 123 | FitBH, 124 | 125 | /// 126 | /// Display the page with left coordinate at left side of the window. One argument. 127 | /// 128 | /// 129 | /// Display the page designated by page, with the horizontal coordinate left positioned 130 | /// at the left edge of the window and the contents of the page magnified just enough 131 | /// to fit the entire height of its bounding box within the window. A null value for 132 | /// left specifies that the current value of that parameter is to be retained unchanged. 133 | /// 134 | FitBV, 135 | } 136 | 137 | internal class LocationMarker : IComparable 138 | { 139 | internal static string[] FitString = 140 | { 141 | "/Fit", 142 | "/FitH", 143 | "/FitV", 144 | "/FitR", 145 | "/FitB", 146 | "/FitBH", 147 | "/FitBV", 148 | }; 149 | internal static int[] FitArguments = {0, 1, 1, 4, 0, 1, 1}; 150 | 151 | internal string LocMarkerName; 152 | internal LocMarkerScope Scope; 153 | internal string DestStr; 154 | 155 | // Do not call this constructor from your code 156 | private LocationMarker 157 | ( 158 | string LocMarkerName, 159 | PdfPage LoctionMarkerPage, 160 | LocMarkerScope Scope, 161 | DestFit FitArg, 162 | params double[] SideArg 163 | ) 164 | { 165 | if(SideArg.Length != FitArguments[(int) FitArg]) throw new ApplicationException("AddDestination invalid number of arguments"); 166 | this.LocMarkerName = LocMarkerName; 167 | this.Scope = Scope; 168 | StringBuilder BuildDest = new StringBuilder(); 169 | BuildDest.AppendFormat("[{0} 0 R {1}", LoctionMarkerPage.ObjectNumber, FitString[(int) FitArg]); 170 | foreach(double Side in SideArg) BuildDest.AppendFormat(NFI.PeriodDecSep, " {0}", LoctionMarkerPage.ToPt(Side)); 171 | BuildDest.Append("]"); 172 | DestStr = BuildDest.ToString(); 173 | return; 174 | } 175 | 176 | internal LocationMarker 177 | ( 178 | string LocMarkerName 179 | ) 180 | { 181 | this.LocMarkerName = LocMarkerName; 182 | return; 183 | } 184 | 185 | /// 186 | /// Create unique location marker 187 | /// 188 | /// Location marker name (case sensitive) 189 | /// Location marker page 190 | /// Location marker scope 191 | /// Fit enumeration 192 | /// Fit optional arguments 193 | public static void Create 194 | ( 195 | string LocMarkerName, 196 | PdfPage LocMarkerPage, 197 | LocMarkerScope Scope, 198 | DestFit FitArg, 199 | params double[] SideArg 200 | ) 201 | { 202 | if(LocMarkerPage.Document.LocMarkerArray == null) LocMarkerPage.Document.LocMarkerArray = new List(); 203 | int Index = LocMarkerPage.Document.LocMarkerArray.BinarySearch(new LocationMarker(LocMarkerName)); 204 | if(Index >= 0) throw new ApplicationException("Duplicate location marker"); 205 | LocMarkerPage.Document.LocMarkerArray.Insert(~Index, new LocationMarker(LocMarkerName, LocMarkerPage, Scope, FitArg, SideArg)); 206 | return; 207 | } 208 | 209 | public int CompareTo 210 | ( 211 | LocationMarker Other 212 | ) 213 | { 214 | return string.CompareOrdinal(this.LocMarkerName, Other.LocMarkerName); 215 | } 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfAxialShading.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfAxialShading 7 | // PDF Axial shading indirect object. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | using SysMedia = System.Windows.Media; 28 | 29 | namespace PdfFileWriter 30 | { 31 | /// 32 | /// Mapping mode for axial and radial shading 33 | /// 34 | public enum MappingMode 35 | { 36 | /// 37 | /// Relative to bounding box 38 | /// 39 | Relative, 40 | /// 41 | /// Absolute 42 | /// 43 | Absolute 44 | } 45 | 46 | //////////////////////////////////////////////////////////////////// 47 | /// 48 | /// PDF axial shading resource class 49 | /// 50 | /// 51 | /// Derived class from PdfObject 52 | /// 53 | //////////////////////////////////////////////////////////////////// 54 | public class PdfAxialShading : PdfObject 55 | { 56 | private double BBoxLeft; 57 | private double BBoxBottom; 58 | private double BBoxRight; 59 | private double BBoxTop; 60 | 61 | private MappingMode Mapping; 62 | private double StartPointX; 63 | private double StartPointY; 64 | private double EndPointX; 65 | private double EndPointY; 66 | 67 | private bool ExtendShadingBefore = true; 68 | private bool ExtendShadingAfter = true; 69 | 70 | //////////////////////////////////////////////////////////////////// 71 | /// 72 | /// PDF axial shading constructor. 73 | /// 74 | /// Parent PDF document object 75 | /// Bounding box left position 76 | /// Bounding box bottom position 77 | /// Bounding box width 78 | /// Bounding box height 79 | /// Shading function 80 | //////////////////////////////////////////////////////////////////// 81 | public PdfAxialShading 82 | ( 83 | PdfDocument Document, 84 | double BBoxLeft, 85 | double BBoxBottom, 86 | double BBoxWidth, 87 | double BBoxHeight, 88 | PdfShadingFunction ShadingFunction 89 | ) : base(Document) 90 | { 91 | // create resource code 92 | ResourceCode = Document.GenerateResourceNumber('S'); 93 | 94 | // color space red, green and blue 95 | Dictionary.Add("/ColorSpace", "/DeviceRGB"); 96 | 97 | // shading type axial 98 | Dictionary.Add("/ShadingType", "2"); 99 | 100 | // add shading function to shading dictionary 101 | Dictionary.AddIndirectReference("/Function", ShadingFunction); 102 | 103 | // bounding box 104 | this.BBoxLeft = BBoxLeft; 105 | this.BBoxBottom = BBoxBottom; 106 | this.BBoxRight = BBoxLeft + BBoxWidth; 107 | this.BBoxTop = BBoxBottom + BBoxHeight; 108 | 109 | // assume the direction of color change is along x axis 110 | this.Mapping = MappingMode.Relative; 111 | this.StartPointX = 0.0; 112 | this.StartPointY = 0.0; 113 | this.EndPointX = 1.0; 114 | this.EndPointY = 0.0; 115 | return; 116 | } 117 | 118 | /// 119 | /// PDF axial shading constructor for unit bounding box 120 | /// 121 | /// Parent PDF document object 122 | /// Shading function 123 | public PdfAxialShading 124 | ( 125 | PdfDocument Document, 126 | PdfShadingFunction ShadingFunction 127 | ) : this(Document, 0.0, 0.0, 1.0, 1.0, ShadingFunction) {} 128 | 129 | /// 130 | /// PDF axial shading constructor for unit bounding box 131 | /// 132 | /// Parent PDF document object 133 | /// System.Windows.Media brush 134 | public PdfAxialShading 135 | ( 136 | PdfDocument Document, 137 | SysMedia.LinearGradientBrush MediaBrush 138 | ) : this(Document, 0.0, 0.0, 1.0, 1.0, new PdfShadingFunction(Document, MediaBrush)) 139 | { 140 | SetAxisDirection(MediaBrush.StartPoint.X, MediaBrush.StartPoint.Y, MediaBrush.EndPoint.X, MediaBrush.EndPoint.Y, 141 | MediaBrush.MappingMode == SysMedia.BrushMappingMode.RelativeToBoundingBox ? MappingMode.Relative : MappingMode.Absolute); 142 | return; 143 | } 144 | 145 | /// 146 | /// Set bounding box 147 | /// 148 | /// Bounding box left 149 | /// Bounding box bottom 150 | /// Bounding box width 151 | /// Bounding box height 152 | public void SetBoundingBox 153 | ( 154 | double BBoxLeft, 155 | double BBoxBottom, 156 | double BBoxWidth, 157 | double BBoxHeight 158 | ) 159 | { 160 | // bounding box 161 | this.BBoxLeft = BBoxLeft; 162 | this.BBoxBottom = BBoxBottom; 163 | this.BBoxRight = BBoxLeft + BBoxWidth; 164 | this.BBoxTop = BBoxBottom + BBoxHeight; 165 | return; 166 | } 167 | 168 | /// 169 | /// Set gradient axis direction 170 | /// 171 | /// Start point x 172 | /// Start point y 173 | /// End point x 174 | /// End point y 175 | /// Mapping mode (Relative or Absolute) 176 | public void SetAxisDirection 177 | ( 178 | double StartPointX, 179 | double StartPointY, 180 | double EndPointX, 181 | double EndPointY, 182 | MappingMode Mapping 183 | ) 184 | { 185 | this.StartPointX = StartPointX; 186 | this.StartPointY = StartPointY; 187 | this.EndPointX = EndPointX; 188 | this.EndPointY = EndPointY; 189 | this.Mapping = Mapping; 190 | return; 191 | } 192 | 193 | //////////////////////////////////////////////////////////////////// 194 | /// 195 | /// Sets anti-alias parameter 196 | /// 197 | /// Anti-alias true or false 198 | //////////////////////////////////////////////////////////////////// 199 | public void AntiAlias 200 | ( 201 | bool Value 202 | ) 203 | { 204 | Dictionary.AddBoolean("/AntiAlias", Value); 205 | return; 206 | } 207 | 208 | //////////////////////////////////////////////////////////////////// 209 | /// 210 | /// Extend shading beyond axis 211 | /// 212 | /// Before (true or false) 213 | /// After (true or false) 214 | //////////////////////////////////////////////////////////////////// 215 | public void ExtendShading 216 | ( 217 | bool Before, 218 | bool After 219 | ) 220 | { 221 | this.ExtendShadingBefore = Before; 222 | this.ExtendShadingAfter = After; 223 | return; 224 | } 225 | 226 | //////////////////////////////////////////////////////////////////// 227 | // Write object to PDF file 228 | //////////////////////////////////////////////////////////////////// 229 | 230 | internal override void WriteObjectToPdfFile() 231 | { 232 | // bounding box 233 | Dictionary.AddRectangle("/BBox", BBoxLeft, BBoxBottom, BBoxRight, BBoxTop); 234 | 235 | // absolute axis direction 236 | if(Mapping == MappingMode.Absolute) 237 | { 238 | Dictionary.AddRectangle("/Coords", StartPointX, StartPointY, EndPointX, EndPointY); 239 | } 240 | // relative axit direction 241 | else 242 | { 243 | double RelStartPointX = BBoxLeft * (1.0 - StartPointX) + BBoxRight * StartPointX; 244 | double RelStartPointY = BBoxBottom * (1.0 - StartPointY) + BBoxTop * StartPointY; 245 | double RelEndPointX = BBoxLeft * (1.0 - EndPointX) + BBoxRight * EndPointX; 246 | double RelEndPointY = BBoxBottom * (1.0 - EndPointY) + BBoxTop * EndPointY; 247 | Dictionary.AddRectangle("/Coords", RelStartPointX, RelStartPointY, RelEndPointX, RelEndPointY); 248 | } 249 | 250 | // extend shading 251 | Dictionary.AddFormat("/Extend", "[{0} {1}]", ExtendShadingBefore ? "true" : "false", ExtendShadingAfter ? "true" : "false"); 252 | 253 | // call PdfObject base routine 254 | base.WriteObjectToPdfFile(); 255 | 256 | // exit 257 | return; 258 | } 259 | } 260 | } 261 | -------------------------------------------------------------------------------- /PdfFileWriter/ArcToBezier.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // ArcToBezier 7 | // Convert eliptical arc to Bezier segments. 8 | // 9 | /////////////////////////////////////////////////////////////////////// 10 | // The PDF File Writer library was enhanced to allow drawing of graphic 11 | // artwork using Windows Presentation Foundation (WPF) classes. 12 | // These enhancements were proposed by Elena Malnati elena@yelleaf.com. 13 | // I would like to thank her for providing me with the source code 14 | // to implement them. Further I would like to thank Joe Cridge for 15 | // his contribution of code to convert elliptical arc to Bezier curve. 16 | // The source code was modified to be consistent in style to the rest 17 | // of the library. Developers of Windows Forms application can benefit 18 | // from all of these enhancements 19 | // For further information visit www.joecridge.me/bezier.pdf. 20 | // Also visit http://p5js.org/ for some coolness 21 | /////////////////////////////////////////////////////////////////////// 22 | // 23 | // Uzi Granot 24 | // Version: 1.0 25 | // Date: April 1, 2013 26 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 27 | // 28 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 29 | // application are free software. 30 | // They is distributed under the Code Project Open License (CPOL). 31 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 32 | // the distribution specify the license agreement and other 33 | // conditions and notes. You must read this document and agree 34 | // with the conditions specified in order to use this software. 35 | // 36 | // For version history please refer to PdfDocument.cs 37 | // 38 | ///////////////////////////////////////////////////////////////////// 39 | 40 | using System; 41 | 42 | namespace PdfFileWriter 43 | { 44 | /// 45 | /// Arc type for DrawArc method 46 | /// 47 | public enum ArcType 48 | { 49 | /// 50 | /// Small arc drawn in counter clock wise direction 51 | /// 52 | SmallCounterClockWise, 53 | 54 | /// 55 | /// Small arc drawn in clock wise direction 56 | /// 57 | SmallClockWise, 58 | 59 | /// 60 | /// Large arc drawn in counter clock wise direction 61 | /// 62 | LargeCounterClockWise, 63 | 64 | /// 65 | /// Large arc drawn in clock wise direction 66 | /// 67 | LargeClockWise, 68 | } 69 | 70 | /// 71 | /// Convert eliptical arc to Bezier segments 72 | /// 73 | public static class ArcToBezier 74 | { 75 | //////////////////////////////////////////////////////////////////// 76 | /// 77 | /// Create eliptical arc 78 | /// 79 | /// Arc start point 80 | /// Arc end point 81 | /// RadiusX as width and RadiusY as height 82 | /// X axis rotation angle in radians 83 | /// Arc type enumeration 84 | /// Array of points. 85 | //////////////////////////////////////////////////////////////////// 86 | public static PointD[] CreateArc 87 | ( 88 | PointD ArcStart, 89 | PointD ArcEnd, 90 | SizeD Radius, 91 | double Rotate, 92 | ArcType Type 93 | ) 94 | { 95 | PointD[] SegArray; 96 | double ScaleX = Radius.Width / Radius.Height; 97 | 98 | // circular arc 99 | if(Math.Abs(ScaleX - 1.0) < 0.000001) 100 | { 101 | SegArray = CircularArc(ArcStart, ArcEnd, Radius.Height, Type); 102 | } 103 | // eliptical arc 104 | else if(Rotate == 0.0) 105 | { 106 | PointD ScaleStart = new PointD(ArcStart.X / ScaleX, ArcStart.Y); 107 | PointD ScaleEnd = new PointD(ArcEnd.X / ScaleX, ArcEnd.Y); 108 | SegArray = CircularArc(ScaleStart, ScaleEnd, Radius.Height, Type); 109 | foreach(PointD Seg in SegArray) Seg.X *= ScaleX; 110 | } 111 | // eliptical arc rotated 112 | else 113 | { 114 | double CosR = Math.Cos(Rotate); 115 | double SinR = Math.Sin(Rotate); 116 | PointD ScaleStart = new PointD((CosR * ArcStart.X - SinR * ArcStart.Y) / ScaleX, SinR * ArcStart.X + CosR * ArcStart.Y); 117 | PointD ScaleEnd = new PointD((CosR * ArcEnd.X - SinR * ArcEnd.Y) / ScaleX, SinR * ArcEnd.X + CosR * ArcEnd.Y); 118 | SegArray = CircularArc(ScaleStart, ScaleEnd, Radius.Height, Type); 119 | foreach(PointD Seg in SegArray) 120 | { 121 | double X = Seg.X * ScaleX; 122 | Seg.X = CosR * X + SinR * Seg.Y; 123 | Seg.Y = -SinR * X + CosR * Seg.Y; 124 | } 125 | } 126 | 127 | // replace start and end with original points to eliminate rounding errors 128 | SegArray[0].X = ArcStart.X; 129 | SegArray[0].Y = ArcStart.Y; 130 | SegArray[SegArray.Length - 1].X = ArcEnd.X; 131 | SegArray[SegArray.Length - 1].Y = ArcEnd.Y; 132 | return SegArray; 133 | } 134 | 135 | /// 136 | /// Create circular arc 137 | /// 138 | /// Arc starting point 139 | /// Arc ending point 140 | /// Arc radius 141 | /// Arc type 142 | /// Array of points. 143 | internal static PointD[] CircularArc 144 | ( 145 | PointD ArcStart, 146 | PointD ArcEnd, 147 | double Radius, 148 | ArcType Type 149 | ) 150 | { 151 | // chord line from start point to end point 152 | double ChordDeltaX = ArcEnd.X - ArcStart.X; 153 | double ChordDeltaY = ArcEnd.Y - ArcStart.Y; 154 | double ChordLength = Math.Sqrt(ChordDeltaX * ChordDeltaX + ChordDeltaY * ChordDeltaY); 155 | 156 | // test radius 157 | if(2 * Radius < ChordLength) throw new ApplicationException("Radius too small."); 158 | 159 | // line perpendicular to chord at mid point 160 | // distance from chord mid point to center of circle 161 | double ChordToCircleLen = Math.Sqrt(Radius * Radius - ChordLength * ChordLength / 4); 162 | double ChordToCircleCos = -ChordDeltaY / ChordLength; 163 | double ChordToCircleSin = ChordDeltaX / ChordLength; 164 | if(Type == ArcType.SmallClockWise || Type == ArcType.LargeCounterClockWise) 165 | { 166 | ChordToCircleCos = -ChordToCircleCos; 167 | ChordToCircleSin = -ChordToCircleSin; 168 | } 169 | 170 | // circle center 171 | double CenterX = (ArcStart.X + ArcEnd.X) / 2 + ChordToCircleLen * ChordToCircleCos; 172 | double CenterY = (ArcStart.Y + ArcEnd.Y) / 2 + ChordToCircleLen * ChordToCircleSin; 173 | 174 | // arc angle 175 | double ArcAngle = 2 * Math.Asin(ChordLength / (2 * Radius)); 176 | if(ArcAngle < 0.001) throw new ApplicationException("Angle too small"); 177 | if(Type == ArcType.LargeCounterClockWise || Type == ArcType.LargeClockWise) ArcAngle = 2 * Math.PI - ArcAngle; 178 | 179 | // segment array 180 | PointD[] SegArray; 181 | 182 | // one segment equal or less than 90 deg 183 | if(ArcAngle < Math.PI / 2 + 0.001) 184 | { 185 | double K1 = 4 * (1 - Math.Cos(ArcAngle / 2)) / (3 * Math.Sin(ArcAngle / 2)); 186 | if(Type == ArcType.LargeClockWise || Type == ArcType.SmallClockWise) K1 = -K1; 187 | SegArray = new PointD[4]; 188 | SegArray[0] = ArcStart; 189 | SegArray[1] = new PointD(ArcStart.X - K1 * (ArcStart.Y - CenterY), ArcStart.Y + K1 * (ArcStart.X - CenterX)); 190 | SegArray[2] = new PointD(ArcEnd.X + K1 * (ArcEnd.Y - CenterY), ArcEnd.Y - K1 * (ArcEnd.X - CenterX)); 191 | SegArray[3] = ArcEnd; 192 | return SegArray; 193 | } 194 | 195 | // 2, 3 or 4 segments 196 | int Segments = (int) (ArcAngle / (0.5 * Math.PI)) + 1; 197 | double SegAngle = ArcAngle / Segments; 198 | double K = 4 * (1 - Math.Cos(SegAngle / 2)) / (3 * Math.Sin(SegAngle / 2)); 199 | if(Type == ArcType.LargeClockWise || Type == ArcType.SmallClockWise) 200 | { 201 | K = -K; 202 | SegAngle = -SegAngle; 203 | } 204 | 205 | // segments array 206 | SegArray = new PointD[3 * Segments + 1]; 207 | SegArray[0] = new PointD(ArcStart.X, ArcStart.Y); 208 | 209 | // angle from cricle center to start point 210 | double SegStartX = ArcStart.X; 211 | double SegStartY = ArcStart.Y; 212 | double StartAngle = Math.Atan2(ArcStart.Y - CenterY, ArcStart.X - CenterX); 213 | 214 | // process all segments 215 | int SegEnd = SegArray.Length; 216 | for(int Seg = 1; Seg < SegEnd; Seg += 3) 217 | { 218 | double EndAngle = StartAngle + SegAngle; 219 | double SegEndX = CenterX + Radius * Math.Cos(EndAngle); 220 | double SegEndY = CenterY + Radius * Math.Sin(EndAngle); 221 | SegArray[Seg] = new PointD(SegStartX - K * (SegStartY - CenterY), SegStartY + K * (SegStartX - CenterX)); 222 | SegArray[Seg + 1] = new PointD(SegEndX + K * (SegEndY - CenterY), SegEndY - K * (SegEndX - CenterX)); 223 | SegArray[Seg + 2] = new PointD(SegEndX, SegEndY); 224 | SegStartX = SegEndX; 225 | SegStartY = SegEndY; 226 | StartAngle = EndAngle; 227 | } 228 | return SegArray; 229 | } 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfPrintDocument.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PrintPdfDocument 7 | // Create PDF document from PrintDocument page images. 8 | // Each page is saved as bitmap image. 9 | // 10 | // Uzi Granot 11 | // Version: 1.0 12 | // Date: April 1, 2013 13 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 14 | // 15 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 16 | // application are free software. 17 | // They is distributed under the Code Project Open License (CPOL). 18 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 19 | // the distribution specify the license agreement and other 20 | // conditions and notes. You must read this document and agree 21 | // with the conditions specified in order to use this software. 22 | // 23 | // For version history please refer to PdfDocument.cs 24 | // 25 | ///////////////////////////////////////////////////////////////////// 26 | 27 | using System; 28 | using System.Drawing; 29 | using System.Drawing.Printing; 30 | 31 | namespace PdfFileWriter 32 | { 33 | /// 34 | /// PDF print document class 35 | /// 36 | /// 37 | /// 38 | /// It is a derived class of PrintDocument. 39 | /// The class converts the metafile output of PrintDocument 40 | /// to an image. The image is displayed in the PDF document. 41 | /// 42 | /// 43 | /// For more information go to 2.11 Print Document Support 44 | /// 45 | /// 46 | public class PdfPrintDocument : PrintDocument 47 | { 48 | /// 49 | /// Document page crop rectangle 50 | /// 51 | /// 52 | /// Dimensions are in user units. The origin is top left corner. 53 | /// 54 | public RectangleF PageCropRect {get; set;} 55 | 56 | /// 57 | /// Image resolution in pixels per inch (default is 96) 58 | /// 59 | public double Resolution { get; set; } 60 | 61 | /// 62 | /// Save image as (default is jpeg) 63 | /// 64 | public SaveImageAs SaveAs { get; set; } 65 | 66 | /// 67 | /// Gets or sets Jpeg image quality 68 | /// 69 | public int ImageQuality 70 | { 71 | get 72 | { 73 | return _ImageQuality; 74 | } 75 | set 76 | { 77 | // set image quality 78 | if(value != PdfImage.DefaultQuality && (value < 0 || value > 100)) 79 | throw new ApplicationException("PdfImageControl.ImageQuality must be PdfImage.DefaultQuality or 0 to 100"); 80 | _ImageQuality = value; 81 | return; 82 | } 83 | } 84 | internal int _ImageQuality = PdfImage.DefaultQuality; 85 | 86 | /// 87 | /// Gray to BW cutoff level 88 | /// 89 | public int GrayToBWCutoff 90 | { 91 | get 92 | { 93 | return _GrayToBWCutoff; 94 | } 95 | set 96 | { 97 | if(value < 1 || value > 99) throw new ApplicationException("PdfImageControl.GrayToBWCutoff must be 1 to 99"); 98 | _GrayToBWCutoff = value; 99 | } 100 | } 101 | internal int _GrayToBWCutoff = 50; 102 | 103 | /// 104 | /// Current PDF document 105 | /// 106 | protected PdfDocument Document; 107 | 108 | //////////////////////////////////////////////////////////////////// 109 | /// 110 | /// PDF print document constructor 111 | /// 112 | /// Current PDF document 113 | //////////////////////////////////////////////////////////////////// 114 | public PdfPrintDocument 115 | ( 116 | PdfDocument Document 117 | ) 118 | { 119 | // save document 120 | this.Document = Document; 121 | 122 | // set default resolution to 96 pixels per inch 123 | Resolution = 96.0; 124 | 125 | // save as jpeg 126 | SaveAs = SaveImageAs.Jpeg; 127 | 128 | // create print document and preview controller objects 129 | PrintController = new PreviewPrintController(); 130 | 131 | // copy document's page size to default settings 132 | // convert page size from points to 100th of inch 133 | // do not set lanscape flag 134 | PaperSize PSize = new PaperSize(); 135 | PSize.Width = (int) (Document.PageSize.Width / 0.72 + 0.5); 136 | PSize.Height = (int) (Document.PageSize.Height / 0.72 + 0.5); 137 | DefaultPageSettings.PaperSize = PSize; 138 | 139 | // assume document is in color 140 | DefaultPageSettings.Color = true; 141 | return; 142 | } 143 | 144 | //////////////////////////////////////////////////////////////////// 145 | /// 146 | /// Gets or sets DocumentInColor flag. 147 | /// 148 | //////////////////////////////////////////////////////////////////// 149 | public bool DocumentInColor 150 | { 151 | set 152 | { 153 | DefaultPageSettings.Color = value; 154 | return; 155 | } 156 | get 157 | { 158 | return DefaultPageSettings.Color; 159 | } 160 | } 161 | 162 | //////////////////////////////////////////////////////////////////// 163 | /// 164 | /// Gets margins in 100th of an inch 165 | /// 166 | //////////////////////////////////////////////////////////////////// 167 | public Margins GetMargins 168 | { 169 | get 170 | { 171 | return DefaultPageSettings.Margins; 172 | } 173 | } 174 | 175 | //////////////////////////////////////////////////////////////////// 176 | /// 177 | /// Sets margins in user units. 178 | /// 179 | /// Left margin 180 | /// Top margin 181 | /// Right margin 182 | /// Bottom margin 183 | //////////////////////////////////////////////////////////////////// 184 | public void SetMargins 185 | ( 186 | double LeftMargin, 187 | double TopMargin, 188 | double RightMargin, 189 | double BottomMargin 190 | ) 191 | { 192 | Margins Margins = DefaultPageSettings.Margins; 193 | Margins.Left = (int) (LeftMargin * Document.ScaleFactor / 0.72 + 0.5); 194 | Margins.Top = (int) (TopMargin * Document.ScaleFactor / 0.72 + 0.5); 195 | Margins.Right = (int) (RightMargin * Document.ScaleFactor / 0.72 + 0.5); 196 | Margins.Bottom = (int) (BottomMargin * Document.ScaleFactor / 0.72 + 0.5); 197 | return; 198 | } 199 | 200 | //////////////////////////////////////////////////////////////////// 201 | /// 202 | /// Add pages to PDF document 203 | /// 204 | /// 205 | /// The PrintDoc.Print method will call BeginPrint method, 206 | /// next it will call multiple times PrintPage method and finally 207 | /// it will call EndPrint method. 208 | /// 209 | //////////////////////////////////////////////////////////////////// 210 | public void AddPagesToPdfDocument() 211 | { 212 | // print the document by calling BeginPrint, PrintPage multiple times and finally EndPrint 213 | Print(); 214 | 215 | // get printing results in the form of array of images one per page 216 | // image format is Metafile 217 | PreviewPageInfo[] PageInfo = ((PreviewPrintController) PrintController).GetPreviewPageInfo(); 218 | 219 | // page size in user units 220 | double PageWidth = Document.PageSize.Width / Document.ScaleFactor; 221 | double PageHeight = Document.PageSize.Height / Document.ScaleFactor; 222 | 223 | // add pages to pdf document 224 | for(int ImageIndex = 0; ImageIndex < PageInfo.Length; ImageIndex++) 225 | { 226 | // add page to document 227 | PdfPage Page = new PdfPage(Document); 228 | 229 | // add contents to the page 230 | PdfContents Contents = new PdfContents(Page); 231 | 232 | // page image 233 | Image PageImage = PageInfo[ImageIndex].Image; 234 | 235 | // empty pdf image 236 | PdfImage PdfImage = new PdfImage(Contents.Document); 237 | PdfImage.Resolution = Resolution; 238 | PdfImage.SaveAs = SaveAs; 239 | PdfImage.ImageQuality = ImageQuality; 240 | PdfImage.GrayToBWCutoff = GrayToBWCutoff; 241 | PdfImage.CropRect = Rectangle.Empty; 242 | PdfImage.CropPercent = RectangleF.Empty; 243 | 244 | // no crop 245 | if(PageCropRect.IsEmpty) 246 | { 247 | // convert metafile image to PdfImage 248 | PdfImage.LoadImage(PageImage); 249 | 250 | // draw the image 251 | Contents.DrawImage(PdfImage, 0.0, 0.0, PageWidth, PageHeight); 252 | } 253 | 254 | // crop 255 | else 256 | { 257 | int ImageWidth = PageImage.Width; 258 | int ImageHeight = PageImage.Height; 259 | PdfImage.CropRect.X = (int) (ImageWidth * PageCropRect.X / PageWidth + 0.5); 260 | PdfImage.CropRect.Y = (int) (ImageHeight * PageCropRect.Y / PageHeight + 0.5); 261 | PdfImage.CropRect.Width = (int) (ImageWidth * PageCropRect.Width / PageWidth + 0.5); 262 | PdfImage.CropRect.Height = (int) (ImageHeight * PageCropRect.Height / PageHeight + 0.5); 263 | 264 | // convert metafile image to PdfImage 265 | PdfImage.LoadImage(PageImage); 266 | 267 | // draw the image 268 | Contents.DrawImage(PdfImage, PageCropRect.X, PageHeight - PageCropRect.Y - PageCropRect.Height, PageCropRect.Width, PageCropRect.Height); 269 | } 270 | } 271 | return; 272 | } 273 | } 274 | } 275 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfRadialShading.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfRadialShading 7 | // PDF radial shading resource class. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | using SysMedia = System.Windows.Media; 28 | 29 | namespace PdfFileWriter 30 | { 31 | //////////////////////////////////////////////////////////////////// 32 | /// 33 | /// PDF radial shading resource class 34 | /// 35 | /// 36 | /// Derived class from PdfObject 37 | /// 38 | public class PdfRadialShading : PdfObject 39 | { 40 | private double BBoxLeft; 41 | private double BBoxBottom; 42 | private double BBoxRight; 43 | private double BBoxTop; 44 | 45 | private MappingMode Mapping; 46 | private double StartCenterX; 47 | private double StartCenterY; 48 | private double StartRadius; 49 | private double EndCenterX; 50 | private double EndCenterY; 51 | private double EndRadius; 52 | 53 | private bool ExtendShadingBefore = true; 54 | private bool ExtendShadingAfter = true; 55 | 56 | //////////////////////////////////////////////////////////////////// 57 | /// 58 | /// PDF radial shading constructor. 59 | /// 60 | /// Parent PDF document object 61 | /// Bounding box left position 62 | /// Bounding box bottom position 63 | /// Bounding box width 64 | /// Bounding box height 65 | /// Shading function 66 | //////////////////////////////////////////////////////////////////// 67 | public PdfRadialShading 68 | ( 69 | PdfDocument Document, 70 | double BBoxLeft, 71 | double BBoxBottom, 72 | double BBoxWidth, 73 | double BBoxHeight, 74 | PdfShadingFunction ShadingFunction 75 | ) : base(Document) 76 | { 77 | // create resource code 78 | ResourceCode = Document.GenerateResourceNumber('S'); 79 | 80 | // color space red, green and blue 81 | Dictionary.Add("/ColorSpace", "/DeviceRGB"); 82 | 83 | // shading type axial 84 | Dictionary.Add("/ShadingType", "3"); 85 | 86 | // add shading function to shading dictionary 87 | Dictionary.AddIndirectReference("/Function", ShadingFunction); 88 | 89 | // bounding box 90 | this.BBoxLeft = BBoxLeft; 91 | this.BBoxBottom = BBoxBottom; 92 | this.BBoxRight = BBoxLeft + BBoxWidth; 93 | this.BBoxTop = BBoxBottom + BBoxHeight; 94 | 95 | // assume the direction of color change is along x axis 96 | this.Mapping = MappingMode.Relative; 97 | this.StartCenterX = 0.5; 98 | this.StartCenterY = 0.5; 99 | this.StartRadius = 0.0; 100 | this.EndCenterX = 0.5; 101 | this.EndCenterY = 0.5; 102 | this.EndRadius = Math.Sqrt(0.5); 103 | return; 104 | } 105 | 106 | /// 107 | /// PDF radial shading constructor for one unit bounding box 108 | /// 109 | /// Parent PDF document object. 110 | /// Shading function. 111 | public PdfRadialShading 112 | ( 113 | PdfDocument Document, 114 | PdfShadingFunction ShadingFunction 115 | ) : this(Document, 0.0, 0.0, 1.0, 1.0, ShadingFunction) {} 116 | 117 | /// 118 | /// PDF radial shading constructor for one unit bounding box 119 | /// 120 | /// Parent PDF document object. 121 | /// System.Windows.Media brush 122 | /// Support for WPF media 123 | public PdfRadialShading 124 | ( 125 | PdfDocument Document, 126 | SysMedia.RadialGradientBrush MediaBrush 127 | ) : this(Document, 0.0, 0.0, 1.0, 1.0, new PdfShadingFunction(Document, MediaBrush)) 128 | { 129 | SetGradientDirection(MediaBrush.Center.X, MediaBrush.Center.Y, 0.0, 130 | MediaBrush.GradientOrigin.X, MediaBrush.GradientOrigin.Y, 0.5 * (MediaBrush.RadiusX + MediaBrush.RadiusY), 131 | MediaBrush.MappingMode == SysMedia.BrushMappingMode.RelativeToBoundingBox ? MappingMode.Relative : MappingMode.Absolute); 132 | return; 133 | } 134 | 135 | /// 136 | /// Set bounding box 137 | /// 138 | /// Bounding box left 139 | /// Bounding box bottom 140 | /// Bounding box width 141 | /// Bounding box height 142 | public void SetBoundingBox 143 | ( 144 | double BBoxLeft, 145 | double BBoxBottom, 146 | double BBoxWidth, 147 | double BBoxHeight 148 | ) 149 | { 150 | // bounding box 151 | this.BBoxLeft = BBoxLeft; 152 | this.BBoxBottom = BBoxBottom; 153 | this.BBoxRight = BBoxLeft + BBoxWidth; 154 | this.BBoxTop = BBoxBottom + BBoxHeight; 155 | return; 156 | } 157 | 158 | /// 159 | /// Set gradient direction 160 | /// 161 | /// Start circle center x position 162 | /// Start circle center y position 163 | /// Start circle center radius 164 | /// End circle center x position 165 | /// End circle center y position 166 | /// End circle center radius 167 | /// Mapping mode (relative absolute) 168 | public void SetGradientDirection 169 | ( 170 | double StartCenterX, 171 | double StartCenterY, 172 | double StartRadius, 173 | double EndCenterX, 174 | double EndCenterY, 175 | double EndRadius, 176 | MappingMode Mapping 177 | ) 178 | { 179 | this.StartCenterX = StartCenterX; 180 | this.StartCenterY = StartCenterY; 181 | this.StartRadius = StartRadius; 182 | this.EndCenterX = EndCenterX; 183 | this.EndCenterY = EndCenterY; 184 | this.EndRadius = EndRadius; 185 | this.Mapping = Mapping; 186 | return; 187 | } 188 | 189 | //////////////////////////////////////////////////////////////////// 190 | /// 191 | /// Sets anti-alias parameter 192 | /// 193 | /// Anti-alias true or false 194 | //////////////////////////////////////////////////////////////////// 195 | public void AntiAlias 196 | ( 197 | bool Value 198 | ) 199 | { 200 | Dictionary.AddBoolean("/AntiAlias", Value); 201 | return; 202 | } 203 | 204 | //////////////////////////////////////////////////////////////////// 205 | /// 206 | /// Extend shading beyond axis 207 | /// 208 | /// Before (true or false) 209 | /// After (true or false) 210 | //////////////////////////////////////////////////////////////////// 211 | public void ExtendShading 212 | ( 213 | bool Before, 214 | bool After 215 | ) 216 | { 217 | this.ExtendShadingBefore = Before; 218 | this.ExtendShadingAfter = After; 219 | return; 220 | } 221 | 222 | //////////////////////////////////////////////////////////////////// 223 | // Write object to PDF file 224 | //////////////////////////////////////////////////////////////////// 225 | 226 | internal override void WriteObjectToPdfFile() 227 | { 228 | // bounding box 229 | Dictionary.AddRectangle("/BBox", BBoxLeft, BBoxBottom, BBoxRight, BBoxTop); 230 | 231 | // absolute mapping mode 232 | if(Mapping == MappingMode.Absolute) 233 | { 234 | Dictionary.AddFormat("/Coords", "[{0} {1} {2} {3} {4} {5}]", 235 | ToPt(StartCenterX), ToPt(StartCenterY), ToPt(StartRadius), ToPt(EndCenterX), ToPt(EndCenterY), ToPt(EndRadius)); 236 | } 237 | // relative mapping mode 238 | else 239 | { 240 | double RelStartCenterX = BBoxLeft * (1.0 - StartCenterX) + BBoxRight * StartCenterX; 241 | double RelStartCenterY = BBoxBottom * (1.0 - StartCenterY) + BBoxTop * StartCenterY; 242 | double BBoxSide = Math.Min(Math.Abs(BBoxRight - BBoxLeft), Math.Abs(BBoxTop - BBoxBottom)); 243 | double RelStartRadius = BBoxSide * StartRadius; 244 | double RelEndCenterX = BBoxLeft * (1.0 - EndCenterX) + BBoxRight * EndCenterX; 245 | double RelEndCenterY = BBoxBottom * (1.0 - EndCenterY) + BBoxTop * EndCenterY; 246 | double RelEndRadius = BBoxSide * EndRadius; 247 | Dictionary.AddFormat("/Coords", "[{0} {1} {2} {3} {4} {5}]", 248 | ToPt(RelStartCenterX), ToPt(RelStartCenterY), ToPt(RelStartRadius), ToPt(RelEndCenterX), ToPt(RelEndCenterY), ToPt(RelEndRadius)); 249 | } 250 | 251 | // extend shading 252 | Dictionary.AddFormat("/Extend", "[{0} {1}]", ExtendShadingBefore ? "true" : "false", ExtendShadingAfter ? "true" : "false"); 253 | 254 | // call PdfObject base routine 255 | base.WriteObjectToPdfFile(); 256 | 257 | // exit 258 | return; 259 | } 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfChart.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfChart 7 | // Display charts in the PDF document. 8 | // Charts are displayed as images. 9 | // 10 | // Uzi Granot 11 | // Version: 1.0 12 | // Date: April 1, 2013 13 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 14 | // 15 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 16 | // application are free software. 17 | // They is distributed under the Code Project Open License (CPOL). 18 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 19 | // the distribution specify the license agreement and other 20 | // conditions and notes. You must read this document and agree 21 | // with the conditions specified in order to use this software. 22 | // 23 | // For version history please refer to PdfDocument.cs 24 | // 25 | ///////////////////////////////////////////////////////////////////// 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.Drawing; 30 | using System.Drawing.Imaging; 31 | using System.Windows.Forms.DataVisualization.Charting; 32 | using System.IO; 33 | using System.Text; 34 | 35 | namespace PdfFileWriter 36 | { 37 | /// 38 | /// Font size units for PdfChart.CreateFont method enumeration 39 | /// 40 | public enum FontSizeUnit 41 | { 42 | /// 43 | /// Pixel 44 | /// 45 | Pixel, 46 | 47 | /// 48 | /// Point 49 | /// 50 | Point, 51 | 52 | /// 53 | /// PDF document user unit 54 | /// 55 | UserUnit, 56 | 57 | /// 58 | /// Inch 59 | /// 60 | Inch, 61 | 62 | /// 63 | /// CM 64 | /// 65 | cm, 66 | 67 | /// 68 | /// MM 69 | /// 70 | mm 71 | } 72 | 73 | /// 74 | /// PDF chart resource class 75 | /// 76 | /// 77 | /// 78 | /// For more information go to 2.10 Charting Support 79 | /// 80 | /// 81 | /// For example of drawing image see 3.11. Draw Pie Chart 82 | /// 83 | /// 84 | public class PdfChart : PdfImage 85 | { 86 | /// 87 | /// Chart object (.NET). 88 | /// 89 | public Chart MSChart {get; private set;} // chart object 90 | 91 | /// 92 | /// Chart width in user units. 93 | /// 94 | public double Width {get; private set;} // width in user units 95 | 96 | /// 97 | /// Chart height in user units. 98 | /// 99 | public double Height {get; private set;} // height in user units 100 | 101 | /// 102 | /// Set output resolution 103 | /// 104 | public override double Resolution 105 | { 106 | get 107 | { 108 | return _Resolution; 109 | } 110 | set 111 | { 112 | if(value < 0) throw new ApplicationException("Resolution must be greater than zero, or zero for default"); 113 | 114 | // save resolution 115 | _Resolution = value; 116 | 117 | // take resolution from MS chart 118 | if(_Resolution == 0) 119 | { 120 | _Resolution = MSChart.RenderingDpiY; 121 | } 122 | else 123 | { 124 | MSChart.RenderingDpiY = _Resolution; 125 | } 126 | 127 | // calculate chart size in user coordinates 128 | Width = WidthPix * 72.0 / (Resolution * Document.ScaleFactor); 129 | Height = HeightPix * 72.0 / (Resolution * Document.ScaleFactor); 130 | } 131 | } 132 | 133 | //////////////////////////////////////////////////////////////////// 134 | /// 135 | /// PDF chart constructor 136 | /// 137 | /// Document object parent of this chart. 138 | /// .NET Chart object. 139 | /// 140 | /// It is the responsibility of the calling program to release 141 | /// the resources of the input chart object. After PdfChart 142 | /// is commited to the PDF file 143 | /// 144 | /// 145 | /// 146 | /// // create chart 147 | /// Chart MyChart = new Chart(); 148 | /// // build chart 149 | /// // ... 150 | /// // ... 151 | /// PdfImageControl ImageControl = new PdfImageControl(); 152 | /// ImageControl.SaveAs = SaveImageAs.IndexedImage; 153 | /// PdfChart MyPdfChart = new PdfChart(Document, MyChart, ImageControl); 154 | /// MyPdfChart.CommitToPdfFile(); 155 | /// MyChart.Dispose(); 156 | /// 157 | /// 158 | //////////////////////////////////////////////////////////////////// 159 | public PdfChart 160 | ( 161 | PdfDocument Document, 162 | Chart MSChart 163 | ) : base(Document) 164 | { 165 | // save chart 166 | this.MSChart = MSChart; 167 | WidthPix = MSChart.Width; 168 | HeightPix = MSChart.Height; 169 | 170 | // take resolution from MS chart 171 | Resolution = MSChart.RenderingDpiY; 172 | 173 | // calculate chart size in user coordinates 174 | Width = (double) WidthPix * 72.0 / (Resolution * Document.ScaleFactor); 175 | Height = (double) HeightPix * 72.0 / (Resolution * Document.ScaleFactor); 176 | 177 | // exit 178 | return; 179 | } 180 | 181 | //////////////////////////////////////////////////////////////////// 182 | /// 183 | /// Static method to create .NET Chart object. 184 | /// 185 | /// Current document object. 186 | /// Chart width in user units. 187 | /// Chart height in user units. 188 | /// Resolution in pixels per inch (optional argument). 189 | /// .NET Chart object 190 | /// 191 | /// The returned chart has the correct width and height in pixels. 192 | /// 193 | //////////////////////////////////////////////////////////////////// 194 | public static Chart CreateChart 195 | ( 196 | PdfDocument Document, 197 | double Width, 198 | double Height, 199 | double Resolution = 0.0 200 | ) 201 | { 202 | // create chart 203 | Chart MSChart = new Chart(); 204 | 205 | // save resolution 206 | if(Resolution != 0) MSChart.RenderingDpiY = Resolution; 207 | 208 | // image size in pixels 209 | MSChart.Width = (int) (MSChart.RenderingDpiY * Width * Document.ScaleFactor / 72.0 + 0.5); 210 | MSChart.Height = (int) (MSChart.RenderingDpiY * Height * Document.ScaleFactor / 72.0 + 0.5); 211 | 212 | // return chart 213 | return MSChart; 214 | } 215 | 216 | //////////////////////////////////////////////////////////////////// 217 | /// 218 | /// Helper method to create a font for chart drawing. 219 | /// 220 | /// Font family name. 221 | /// Font style. 222 | /// Font size per unit argument. 223 | /// Font size unit. 224 | /// .NET font 225 | //////////////////////////////////////////////////////////////////// 226 | public Font CreateFont 227 | ( 228 | string FontFamilyName, // font family name 229 | FontStyle FontStyle, // font style 230 | double FontSize, // as per units below 231 | FontSizeUnit Unit // unit of measure 232 | ) 233 | { 234 | // calculate size 235 | int SizeInPixels = 0; 236 | switch(Unit) 237 | { 238 | case FontSizeUnit.Pixel: 239 | SizeInPixels = (int) (FontSize + 0.5); 240 | break; 241 | 242 | case FontSizeUnit.Point: 243 | SizeInPixels = (int) (FontSize * _Resolution / 72.0 + 0.5); 244 | break; 245 | 246 | case FontSizeUnit.UserUnit: 247 | SizeInPixels = (int) (FontSize * _Resolution * Document.ScaleFactor / 72.0 + 0.5); 248 | break; 249 | 250 | case FontSizeUnit.Inch: 251 | SizeInPixels = (int) (FontSize * _Resolution + 0.5); 252 | break; 253 | 254 | case FontSizeUnit.cm: 255 | SizeInPixels = (int) (FontSize * _Resolution / 2.54 + 0.5); 256 | break; 257 | 258 | case FontSizeUnit.mm: 259 | SizeInPixels = (int) (FontSize * _Resolution / 25.4 + 0.5); 260 | break; 261 | } 262 | 263 | // create font 264 | return new Font(FontFamilyName, SizeInPixels, FontStyle, GraphicsUnit.Pixel); 265 | } 266 | 267 | /// 268 | /// Commit object to PDF file 269 | /// 270 | /// Dispose Chart object 271 | /// Activate Garbage Collector 272 | public void CommitToPdfFile 273 | ( 274 | bool DisposeChart, 275 | bool GCCollect 276 | ) 277 | { 278 | // make sure not to do it twice 279 | if(FilePosition == 0) 280 | { 281 | // call PdfObject routine 282 | WriteObjectToPdfFile(); 283 | 284 | // dispose chart 285 | if(DisposeChart) 286 | { 287 | MSChart.Dispose(); 288 | MSChart = null; 289 | } 290 | 291 | // activate garbage collector 292 | if(GCCollect) GC.Collect(); 293 | } 294 | 295 | // exit 296 | return; 297 | } 298 | 299 | //////////////////////////////////////////////////////////////////// 300 | // Write object to PDF file 301 | //////////////////////////////////////////////////////////////////// 302 | 303 | internal override void WriteObjectToPdfFile() 304 | { 305 | // convert chart to bitmap 306 | Picture = new Bitmap(WidthPix, HeightPix); 307 | MSChart.DrawToBitmap(Picture, new Rectangle(0, 0, WidthPix, HeightPix)); 308 | DisposePicture = true; 309 | 310 | // call Image class WriteObjectToPdfFile 311 | base.WriteObjectToPdfFile(); 312 | return; 313 | } 314 | } 315 | } 316 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfTableStyle.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfTableStyle 7 | // Data table style support. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | using System.Collections.Generic; 28 | using System.Drawing; 29 | using System.Text; 30 | using System.Globalization; 31 | 32 | namespace PdfFileWriter 33 | { 34 | /// 35 | /// PDF table cell or header style class 36 | /// 37 | /// 38 | /// 39 | /// For more information go to 2.12 Data Table Support 40 | /// 41 | /// 42 | public class PdfTableStyle 43 | { 44 | /// 45 | /// Gets or sets content alignment. 46 | /// 47 | /// 48 | /// Alignment property align the content within the client area of the cell. 49 | /// 50 | public ContentAlignment Alignment {get; set;} 51 | 52 | /// 53 | /// Gets or sets background color. 54 | /// 55 | /// 56 | /// If background color is not empty, the frame area of the cell will 57 | /// be painted by this color. Default is Color.Empty. 58 | /// 59 | public Color BackgroundColor {get; set;} 60 | 61 | /// 62 | /// Gets or sets barcode narrow bar width 63 | /// 64 | /// 65 | /// The width of the bar code narrow bar. 66 | /// 67 | public double BarcodeBarWidth {get; set;} 68 | 69 | /// 70 | /// Gets or sets barcode height 71 | /// 72 | /// 73 | /// The height of the barcode excluding optional text. 74 | /// 75 | public double BarcodeHeight {get; set;} 76 | 77 | /// 78 | /// Gets or sets first line indent for text box items. 79 | /// 80 | public double TextBoxFirstLineIndent {get; set;} 81 | 82 | /// 83 | /// Gets or sets text box line break factor. 84 | /// 85 | public double TextBoxLineBreakFactor {get; set;} 86 | 87 | /// 88 | /// Gets or sets extra line spacing for text box items. 89 | /// 90 | public double TextBoxLineExtraSpace {get; set;} 91 | 92 | /// 93 | /// Gets or sets minimum text lines for page break calculations. 94 | /// 95 | /// 96 | /// If TextBoxPageBreakLines is zero, the software will keep 97 | /// all of the TextBox together. If the TextBox height is too 98 | /// big to fit in the table, an exception will be raised. If 99 | /// TextBoxPageBreakLines is not zero and TextBox height is too 100 | /// big, the height of TextBoxPageBreakLines will be used 101 | /// to start a new page. The remaining lines will be printed 102 | /// on the next page or pages. 103 | /// 104 | public int TextBoxPageBreakLines {get; set;} 105 | 106 | /// 107 | /// Gets or sets extra paragraph spacing for text box items. 108 | /// 109 | public double TextBoxParagraphExtraSpace {get; set;} 110 | 111 | /// 112 | /// Gets or sets text justify within text box. 113 | /// 114 | public TextBoxJustify TextBoxTextJustify {get; set;} 115 | 116 | /// 117 | /// Gets or sets font. 118 | /// 119 | /// 120 | /// If cell's value type is barcode, a null font signal no text under the barcode. 121 | /// 122 | public PdfFont Font {get; set;} 123 | 124 | /// 125 | /// Gets or sets font size. 126 | /// 127 | public double FontSize {get; set;} 128 | 129 | /// 130 | /// Gets or sets foreground color. 131 | /// 132 | /// 133 | /// Foreground color is used for text and Barcode. 134 | /// 135 | public Color ForegroundColor {get; set;} 136 | 137 | /// 138 | /// Gets or sets format string. 139 | /// 140 | /// 141 | /// 142 | /// All basic numeric values are converted to string using: 143 | /// 144 | /// 145 | /// Value.ToString(Format, NumberFormatInfo); 146 | /// 147 | /// 148 | /// The NumberFormatInfo allows for regional formatting. 149 | /// 150 | /// 151 | /// Both Format and NumberFormatInfo are set to null by default. 152 | /// In other words by default the conversion is: 153 | /// 154 | /// 155 | /// Value.ToString(); 156 | /// 157 | /// 158 | public string Format {get; set;} 159 | 160 | /// 161 | /// Gets or sets cell's margins. 162 | /// 163 | public PdfRectangle Margin {get; set;} 164 | 165 | /// 166 | /// Gets or sets raise custom draw cell event flag. 167 | /// 168 | /// 169 | /// With this flag you can control which columns call the draw cell event handler. 170 | /// 171 | public bool RaiseCustomDrawCellEvent {get; set;} 172 | 173 | /// 174 | /// Gets or sets text draw style. 175 | /// 176 | public DrawStyle TextDrawStyle {get; set;} 177 | 178 | /// 179 | /// Gets or sets minimum cell height. 180 | /// 181 | public double MinHeight {get; set;} 182 | 183 | /// 184 | /// Gets or sets multi-line text flag. 185 | /// 186 | /// 187 | /// String value will be converted to text box value. 188 | /// 189 | public bool MultiLineText {get; set;} 190 | 191 | /// 192 | /// Gets or sets number format information. 193 | /// 194 | /// 195 | /// 196 | /// All basic numeric values are converted to string using: 197 | /// 198 | /// 199 | /// Value.ToString(Format, NumberFormatInfo); 200 | /// 201 | /// 202 | /// The NumberFormatInfo allows for regional formatting. 203 | /// 204 | /// 205 | /// Both Format and NumberFormatInfo are set to null by default. 206 | /// In other words by default the conversion is: 207 | /// 208 | /// 209 | /// Value.ToString(); 210 | /// 211 | /// 212 | public NumberFormatInfo NumberFormatInfo {get; set;} 213 | 214 | /// 215 | /// Gets font ascent for current font and font size. 216 | /// 217 | public double FontAscent 218 | { 219 | get 220 | { 221 | if(Font == null) throw new ApplicationException("PdfTableStyle: Font is not defined."); 222 | return Font.AscentPlusLeading(FontSize); 223 | } 224 | } 225 | 226 | /// 227 | /// Gets font descent for current font and font size. 228 | /// 229 | public double FontDescent 230 | { 231 | get 232 | { 233 | if(Font == null) throw new ApplicationException("PdfTableStyle: Font is not defined."); 234 | return Font.DescentPlusLeading(FontSize); 235 | } 236 | } 237 | 238 | /// 239 | /// Gets font line spacing for current font and font size. 240 | /// 241 | public double FontLineSpacing 242 | { 243 | get 244 | { 245 | if(Font == null) throw new ApplicationException("PdfTableStyle: Font is not defined."); 246 | return Font.LineSpacing(FontSize); 247 | } 248 | } 249 | 250 | /// 251 | /// PDF table style default constructor. 252 | /// 253 | /// Font 254 | public PdfTableStyle 255 | ( 256 | PdfFont Font = null 257 | ) 258 | { 259 | Alignment = ContentAlignment.TopLeft; 260 | BackgroundColor = Color.Empty; 261 | TextBoxLineBreakFactor = 0.5; 262 | TextBoxTextJustify = TextBoxJustify.Left; 263 | this.Font = Font; 264 | FontSize = 9.0; 265 | Margin = new PdfRectangle(); 266 | ForegroundColor = Color.Black; 267 | TextDrawStyle = DrawStyle.Normal; 268 | return; 269 | } 270 | 271 | /// 272 | /// PDF table style constructor based on table's default cell style. 273 | /// 274 | /// Table 275 | public PdfTableStyle 276 | ( 277 | PdfTable Table 278 | ) 279 | { 280 | Copy(Table.DefaultCellStyle); 281 | return; 282 | } 283 | 284 | /// 285 | /// PDF table style constructor as a copy of another style. 286 | /// 287 | /// Copy constructor. 288 | public PdfTableStyle 289 | ( 290 | PdfTableStyle Other 291 | ) 292 | { 293 | Copy(Other); 294 | return; 295 | } 296 | 297 | //////////////////////////////////////////////////////////////////// 298 | /// 299 | /// Copy one style to another 300 | /// 301 | /// Source style 302 | //////////////////////////////////////////////////////////////////// 303 | public void Copy 304 | ( 305 | PdfTableStyle SourceStyle 306 | ) 307 | { 308 | Alignment = SourceStyle.Alignment; 309 | BackgroundColor = SourceStyle.BackgroundColor; 310 | BarcodeBarWidth = SourceStyle.BarcodeBarWidth; 311 | BarcodeHeight = SourceStyle.BarcodeHeight; 312 | Font = SourceStyle.Font; 313 | FontSize = SourceStyle.FontSize; 314 | ForegroundColor = SourceStyle.ForegroundColor; 315 | Format = SourceStyle.Format; 316 | Margin = new PdfRectangle(SourceStyle.Margin); 317 | MinHeight = SourceStyle.MinHeight; 318 | MultiLineText = SourceStyle.MultiLineText; 319 | NumberFormatInfo = SourceStyle.NumberFormatInfo; 320 | RaiseCustomDrawCellEvent = SourceStyle.RaiseCustomDrawCellEvent; 321 | TextBoxFirstLineIndent = SourceStyle.TextBoxFirstLineIndent; 322 | TextBoxLineBreakFactor = SourceStyle.TextBoxLineBreakFactor; 323 | TextBoxLineExtraSpace = SourceStyle.TextBoxLineExtraSpace; 324 | TextBoxPageBreakLines = SourceStyle.TextBoxPageBreakLines; 325 | TextBoxParagraphExtraSpace = SourceStyle.TextBoxParagraphExtraSpace; 326 | TextBoxTextJustify = SourceStyle.TextBoxTextJustify; 327 | TextDrawStyle = SourceStyle.TextDrawStyle; 328 | return; 329 | } 330 | } 331 | } 332 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfBookmark.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfBookmark 7 | // Bookmars or document outline support. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | using System.Collections.Generic; 28 | using System.Drawing; 29 | 30 | namespace PdfFileWriter 31 | { 32 | /// 33 | /// PDF bookmark class 34 | /// 35 | /// 36 | /// For more information go to 2.9 Bookmark Support 37 | /// 38 | public class PdfBookmark : PdfObject 39 | { 40 | private bool OpenEntries; 41 | private PdfBookmark Parent; 42 | private PdfBookmark FirstChild; 43 | private PdfBookmark PrevSibling; 44 | private PdfBookmark NextSibling; 45 | private PdfBookmark LastChild; 46 | private int Count; 47 | 48 | /// 49 | /// Bookmark text style enumeration 50 | /// 51 | public enum TextStyle 52 | { 53 | /// 54 | /// Normal 55 | /// 56 | Normal = 0, 57 | 58 | /// 59 | /// Italic 60 | /// 61 | Italic = 1, 62 | 63 | /// 64 | /// Bold 65 | /// 66 | Bold = 2, 67 | 68 | /// 69 | /// Bold and italic 70 | /// 71 | BoldItalic = 3, 72 | } 73 | 74 | //////////////////////////////////////////////////////////////////// 75 | // Bookmarks (Document Outline) Root Constructor 76 | // Must be called from PdfDocument.GetBookmarksRoot() method 77 | // This constructor is called one time only 78 | //////////////////////////////////////////////////////////////////// 79 | 80 | internal PdfBookmark 81 | ( 82 | PdfDocument Document 83 | ) : base(Document) 84 | { 85 | // open first level bookmarks 86 | OpenEntries = true; 87 | 88 | // add /Outlines to catalog dictionary 89 | Document.CatalogObject.Dictionary.AddIndirectReference("/Outlines", this); 90 | return; 91 | } 92 | 93 | //////////////////////////////////////////////////////////////////// 94 | // Create bookmark item 95 | // Must be called from AddBookmark method below 96 | // This constructor is called for each bookmark 97 | //////////////////////////////////////////////////////////////////// 98 | 99 | private PdfBookmark 100 | ( 101 | PdfDocument Document, 102 | bool OpenEntries 103 | ) : base(Document) 104 | { 105 | // open first level bookmarks 106 | this.OpenEntries = OpenEntries; 107 | return; 108 | } 109 | 110 | //////////////////////////////////////////////////////////////////// 111 | /// 112 | /// Add child bookmark 113 | /// 114 | /// Bookmark title. 115 | /// Page 116 | /// Vertical position. 117 | /// Open child bookmarks attached to this one. 118 | /// Bookmark object 119 | /// 120 | /// Add bookmark as a child to this bookmark. 121 | /// This method creates a new child bookmark item attached 122 | /// to this parent 123 | /// 124 | //////////////////////////////////////////////////////////////////// 125 | public PdfBookmark AddBookmark 126 | ( 127 | string Title, // bookmark title 128 | PdfPage Page, // bookmark page 129 | double YPos, // bookmark vertical position relative to bottom left corner of the page 130 | bool OpenEntries // true is display children. false hide children 131 | ) 132 | { 133 | return AddBookmark(Title, Page, 0.0, YPos, 0.0, Color.Empty, TextStyle.Normal, OpenEntries); 134 | } 135 | 136 | //////////////////////////////////////////////////////////////////// 137 | /// 138 | /// Add child bookmark 139 | /// 140 | /// Bookmark title. 141 | /// Page 142 | /// Vertical position. 143 | /// Bookmark color. 144 | /// Bookmark text style. 145 | /// Open child bookmarks attached to this one. 146 | /// Bookmark object 147 | /// 148 | /// Add bookmark as a child to this bookmark. 149 | /// This method creates a new child bookmark item attached 150 | /// to this parent 151 | /// 152 | //////////////////////////////////////////////////////////////////// 153 | public PdfBookmark AddBookmark 154 | ( 155 | string Title, // bookmark title 156 | PdfPage Page, // bookmark page 157 | double YPos, // bookmark vertical position relative to bottom left corner of the page 158 | Color Paint, // bookmark color 159 | TextStyle TextStyle, // bookmark text style: normal, bold, italic, bold-italic 160 | bool OpenEntries // true is display children. false hide children 161 | ) 162 | { 163 | return AddBookmark(Title, Page, 0.0, YPos, 0.0, Paint, TextStyle, OpenEntries); 164 | } 165 | 166 | //////////////////////////////////////////////////////////////////// 167 | /// 168 | /// Add child bookmark 169 | /// 170 | /// Bookmark title. 171 | /// Page 172 | /// Horizontal position 173 | /// Vertical position. 174 | /// Zoom factor (1.0 is 100%. 0.0 is no change from existing zoom). 175 | /// Open child bookmarks attached to this one. 176 | /// Bookmark object 177 | /// 178 | /// Add bookmark as a child to this bookmark. 179 | /// This method creates a new child bookmark item attached 180 | /// to this parent 181 | /// 182 | //////////////////////////////////////////////////////////////////// 183 | public PdfBookmark AddBookmark 184 | ( 185 | string Title, // bookmark title 186 | PdfPage Page, // bookmark page 187 | double XPos, // bookmark horizontal position relative to bottom left corner of the page 188 | double YPos, // bookmark vertical position relative to bottom left corner of the page 189 | double Zoom, // Zoom factor. 1.0 is 100%. 0.0 is no change from existing zoom. 190 | bool OpenEntries // true is display children. false hide children 191 | ) 192 | { 193 | return AddBookmark(Title, Page, XPos, YPos, Zoom, Color.Empty, TextStyle.Normal, OpenEntries); 194 | } 195 | 196 | //////////////////////////////////////////////////////////////////// 197 | /// 198 | /// Add child bookmark 199 | /// 200 | /// Bookmark title. 201 | /// Page 202 | /// Horizontal position 203 | /// Vertical position. 204 | /// Zoom factor (1.0 is 100%. 0.0 is no change from existing zoom). 205 | /// Bookmark color. 206 | /// Bookmark text style. 207 | /// Open child bookmarks attached to this one. 208 | /// Bookmark object 209 | /// 210 | /// Add bookmark as a child to this bookmark. 211 | /// This method creates a new child bookmark item attached 212 | /// to this parent 213 | /// 214 | //////////////////////////////////////////////////////////////////// 215 | public PdfBookmark AddBookmark 216 | ( 217 | string Title, // bookmark title 218 | PdfPage Page, // bookmark page 219 | double XPos, // bookmark horizontal position relative to bottom left corner of the page 220 | double YPos, // bookmark vertical position relative to bottom left corner of the page 221 | double Zoom, // Zoom factor. 1.0 is 100%. 0.0 is no change from existing zoom. 222 | Color Paint, // bookmark color 223 | TextStyle TextStyle, // bookmark text style: normal, bold, italic, bold-italic 224 | bool OpenEntries // true is display children. false hide children 225 | ) 226 | { 227 | // create new bookmark 228 | PdfBookmark Bookmark = new PdfBookmark(Document, OpenEntries); 229 | 230 | // attach to parent 231 | Bookmark.Parent = this; 232 | 233 | // this bookmark is first child 234 | if(FirstChild == null) 235 | { 236 | FirstChild = Bookmark; 237 | LastChild = Bookmark; 238 | } 239 | 240 | // this bookmark is not first child 241 | else 242 | { 243 | LastChild.NextSibling = Bookmark; 244 | Bookmark.PrevSibling = LastChild; 245 | LastChild = Bookmark; 246 | } 247 | 248 | // the parent of this bookmark displays all children 249 | if(this.OpenEntries) 250 | { 251 | // update count 252 | Count++; 253 | for(PdfBookmark TestParent = Parent; TestParent != null && TestParent.OpenEntries; TestParent = TestParent.Parent) TestParent.Count++; 254 | } 255 | // the parent of this bookmark does not display all children 256 | else 257 | { 258 | Count--; 259 | } 260 | 261 | // build dictionary 262 | Bookmark.Dictionary.AddPdfString("/Title", Title); 263 | Bookmark.Dictionary.AddIndirectReference("/Parent", this); 264 | Bookmark.Dictionary.AddFormat("/Dest", "[{0} 0 R /XYZ {1} {2} {3}]", Page.ObjectNumber, ToPt(XPos), ToPt(YPos), Round(Zoom)); 265 | if(Paint != Color.Empty) 266 | Bookmark.Dictionary.AddFormat("/C", "[{0} {1} {2}]", Round((double) Paint.R / 255.0), Round((double) Paint.G / 255.0), Round((double) Paint.B / 255.0)); 267 | if(TextStyle != TextStyle.Normal) 268 | Bookmark.Dictionary.AddInteger("/F", (int) TextStyle); 269 | return Bookmark; 270 | } 271 | 272 | //////////////////////////////////////////////////////////////////// 273 | /// 274 | /// Gets child bookmark 275 | /// 276 | /// Array of indices 277 | /// Child bookmark or null if not found. 278 | /// 279 | /// Gets PdfBookmark object based on index. 280 | /// You can have multiple indices separated by commas 281 | /// i.e. GetChild(2, 3); 282 | /// Index is zero based. In the example we are looking first for 283 | /// the third bookmark child and then the forth bookmark of the 284 | /// next level. 285 | /// 286 | //////////////////////////////////////////////////////////////////// 287 | public PdfBookmark GetChild 288 | ( 289 | params int[] IndexArray 290 | ) 291 | { 292 | PdfBookmark Bookmark = this; 293 | PdfBookmark Child = null; 294 | for(int Level = 0; Level < IndexArray.Length; Level++, Bookmark = Child) 295 | { 296 | // get index number for level 297 | int Index = IndexArray[Level]; 298 | 299 | // find the child at this level with the given index 300 | for(Child = Bookmark.FirstChild; Index > 0 && Child != null; Child = Child.NextSibling, Index--); 301 | 302 | // not found 303 | if(Child == null) return null; 304 | } 305 | 306 | return Child; 307 | } 308 | 309 | //////////////////////////////////////////////////////////////////// 310 | // Write object to PDF file 311 | //////////////////////////////////////////////////////////////////// 312 | 313 | internal override void WriteObjectToPdfFile() 314 | { 315 | // update dictionary 316 | if(FirstChild != null) Dictionary.AddIndirectReference("/First", FirstChild); 317 | if(LastChild != null) Dictionary.AddIndirectReference("/Last", LastChild); 318 | if(Count != 0) Dictionary.AddInteger("/Count", Count); 319 | 320 | // all but root 321 | if(Parent != null) 322 | { 323 | if(PrevSibling != null) Dictionary.AddIndirectReference("/Prev", PrevSibling); 324 | if(NextSibling != null) Dictionary.AddIndirectReference("/Next", NextSibling); 325 | } 326 | 327 | // call PdfObject base routine 328 | base.WriteObjectToPdfFile(); 329 | 330 | // exit 331 | return; 332 | } 333 | } 334 | } 335 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfTilingPattern.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfTilingPattern 7 | // PDF tiling pattern resource class. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | using System.Drawing; 28 | 29 | namespace PdfFileWriter 30 | { 31 | /// 32 | /// PDF tiling type enumeration 33 | /// 34 | public enum TilingType 35 | { 36 | /// 37 | /// Constant 38 | /// 39 | Constant = 1, 40 | 41 | /// 42 | /// No distortion 43 | /// 44 | NoDistortion, 45 | 46 | /// 47 | /// Constant and fast 48 | /// 49 | ConstantAndFast, 50 | } 51 | 52 | /// 53 | /// PDF tiling pattern resource class 54 | /// 55 | /// 56 | /// 57 | /// For example of using tiling pattern see 3.3. Tiling Pattern 58 | /// 59 | /// 60 | /// or 3.8. Draw Rectangle with Rounded Corners and Filled with Brick Pattern 61 | /// 62 | /// 63 | public class PdfTilingPattern : PdfContents 64 | { 65 | //////////////////////////////////////////////////////////////////// 66 | /// 67 | /// PDF Tiling pattern constructor. 68 | /// 69 | /// Document object parent of the object. 70 | /// 71 | /// This program support only color tiling pattern: PaintType = 1. 72 | /// 73 | //////////////////////////////////////////////////////////////////// 74 | public PdfTilingPattern 75 | ( 76 | PdfDocument Document 77 | ) : base(Document, "/Pattern") 78 | { 79 | // create resource code 80 | ResourceCode = Document.GenerateResourceNumber('P'); 81 | 82 | // add items to dictionary 83 | Dictionary.Add("/PatternType", "1"); // Tiling pattern 84 | Dictionary.Add("/PaintType", "1"); // color 85 | Dictionary.Add("/TilingType", "1"); // constant 86 | Dictionary.AddFormat("/BBox", "[0 0 {0} {1}]", ToPt(1.0), ToPt(1.0)); 87 | Dictionary.AddReal("/XStep", ToPt(1.0)); 88 | Dictionary.AddReal("/YStep", ToPt(1.0)); 89 | return; 90 | } 91 | 92 | //////////////////////////////////////////////////////////////////// 93 | /// 94 | /// Set tiling type 95 | /// 96 | /// Tiling type 97 | //////////////////////////////////////////////////////////////////// 98 | public void SetTilingType 99 | ( 100 | TilingType TilingType 101 | ) 102 | { 103 | // by default the constructor set tiling type to 1 = constant 104 | Dictionary.AddInteger("/TilingType", (int) TilingType); 105 | return; 106 | } 107 | 108 | //////////////////////////////////////////////////////////////////// 109 | /// 110 | /// Set tile box 111 | /// 112 | /// Length of one side. 113 | /// 114 | /// Set square bounding box and equal step 115 | /// 116 | //////////////////////////////////////////////////////////////////// 117 | public void SetTileBox 118 | ( 119 | double Side 120 | ) 121 | { 122 | SetTileBox(Side, Side, Side, Side); 123 | return; 124 | } 125 | 126 | //////////////////////////////////////////////////////////////////// 127 | /// 128 | /// Set tile box 129 | /// 130 | /// Box width. 131 | /// Box height. 132 | /// 133 | /// Set rectangle bounding box and equal step. 134 | /// 135 | //////////////////////////////////////////////////////////////////// 136 | public void SetTileBox 137 | ( 138 | double Width, 139 | double Height 140 | ) 141 | { 142 | SetTileBox(Width, Height, Width, Height); 143 | return; 144 | } 145 | 146 | //////////////////////////////////////////////////////////////////// 147 | /// 148 | /// Set bounding box and step 149 | /// 150 | /// Box width. 151 | /// Box height. 152 | /// Horizontal step 153 | /// Vertical step 154 | /// 155 | /// Set rectangle bounding box and independent step size. 156 | /// 157 | //////////////////////////////////////////////////////////////////// 158 | public void SetTileBox 159 | ( 160 | double Width, 161 | double Height, 162 | double StepX, 163 | double StepY 164 | ) 165 | { 166 | // by default XStep == Width 167 | Dictionary.AddFormat("/BBox", "[0 0 {0} {1}]", ToPt(Width), ToPt(Height)); 168 | Dictionary.AddReal("/XStep", ToPt(StepX)); 169 | Dictionary.AddReal("/YStep", ToPt(StepY)); 170 | return; 171 | } 172 | 173 | //////////////////////////////////////////////////////////////////// 174 | /// 175 | /// Set scale 176 | /// 177 | /// Scale factor. 178 | /// 179 | /// Warning: the program replaces the transformation matrix 180 | /// with a new one [Scale 0 0 Scale 0 0]. 181 | /// 182 | //////////////////////////////////////////////////////////////////// 183 | public void SetScale 184 | ( 185 | double Scale 186 | ) 187 | { 188 | // add items to dictionary 189 | Dictionary.AddFormat("/Matrix", "[{0} 0 0 {0} 0 0]", Round(Scale)); 190 | return; 191 | } 192 | 193 | //////////////////////////////////////////////////////////////////// 194 | /// 195 | /// Set scale 196 | /// 197 | /// Horizontal scale factor. 198 | /// Vertical scale factor. 199 | /// 200 | /// Warning: the program replaces the transformation matrix 201 | /// with a new one [ScaleX 0 0 ScaleY 0 0]. 202 | /// 203 | //////////////////////////////////////////////////////////////////// 204 | public void SetScale 205 | ( 206 | double ScaleX, 207 | double ScaleY 208 | ) 209 | { 210 | // add items to dictionary 211 | Dictionary.AddFormat("/Matrix", "[{0} 0 0 {1} 0 0]", Round(ScaleX), Round(ScaleY)); 212 | return; 213 | } 214 | 215 | //////////////////////////////////////////////////////////////////// 216 | /// 217 | /// Set scale and origin 218 | /// 219 | /// Origin X 220 | /// Origin Y 221 | /// Scale X 222 | /// Scale Y 223 | /// 224 | /// Warning: the program replaces the transformation matrix 225 | /// with a new one [ScaleX 0 0 ScaleY OriginX OriginY]. 226 | /// 227 | //////////////////////////////////////////////////////////////////// 228 | public void SetScaleAndOrigin 229 | ( 230 | double OriginX, 231 | double OriginY, 232 | double ScaleX, 233 | double ScaleY 234 | ) 235 | { 236 | // add items to dictionary 237 | Dictionary.AddFormat("/Matrix", "[{0} 0 0 {1} {2} {3}]", Round(ScaleX), Round(ScaleY), ToPt(OriginX), ToPt(OriginY)); 238 | return; 239 | } 240 | 241 | //////////////////////////////////////////////////////////////////// 242 | /// 243 | /// Set pattern transformation matrix 244 | /// 245 | /// A 246 | /// B 247 | /// C 248 | /// D 249 | /// E 250 | /// F 251 | /// 252 | /// Xpage = a * Xuser + c * Yuser + e 253 | /// Ypage = b * Xuser + d * Yuser + f 254 | /// 255 | //////////////////////////////////////////////////////////////////// 256 | public void SetPatternMatrix 257 | ( 258 | double a, 259 | double b, 260 | double c, 261 | double d, 262 | double e, 263 | double f 264 | ) 265 | { 266 | // create full pattern transformation matrix 267 | Dictionary.AddFormat("/Matrix", "[{0} {1} {2} {3} {4} {5}]", Round(a), Round(b), Round(c), Round(d), ToPt(e), ToPt(f)); 268 | return; 269 | } 270 | 271 | //////////////////////////////////////////////////////////////////// 272 | /// 273 | /// Create new PdfTilingPattern class with brick pattern. 274 | /// 275 | /// Current document object. 276 | /// Scale factor. 277 | /// Stroking color. 278 | /// Non-stroking color. 279 | /// PDF tiling pattern 280 | /// 281 | /// 282 | /// The pattern is a square with one user unit side. 283 | /// 284 | /// 285 | /// The bottom half is one brick. The top half is two half bricks. 286 | /// 287 | /// 288 | /// Arguments: 289 | /// 290 | /// 291 | /// Scale the pattern to your requirements. 292 | /// 293 | /// 294 | /// Stroking color is the mortar color. 295 | /// 296 | /// 297 | /// Nonstroking color is the brick color. 298 | /// 299 | /// 300 | //////////////////////////////////////////////////////////////////// 301 | public static PdfTilingPattern SetBrickPattern 302 | ( 303 | PdfDocument Document, 304 | double Scale, 305 | Color Stroking, 306 | Color NonStroking 307 | ) 308 | { 309 | PdfTilingPattern Pattern = new PdfTilingPattern(Document); 310 | Pattern.SetScale(Scale); 311 | Pattern.SaveGraphicsState(); 312 | Pattern.SetLineWidth(0.05); 313 | Pattern.SetColorStroking(Stroking); 314 | Pattern.SetColorNonStroking(NonStroking); 315 | Pattern.DrawRectangle(0.025, 0.025, 0.95, 0.45, PaintOp.CloseFillStroke); 316 | Pattern.DrawRectangle(-0.475, 0.525, 0.95, 0.45, PaintOp.CloseFillStroke); 317 | Pattern.DrawRectangle(0.525, 0.525, 0.95, 0.45, PaintOp.CloseFillStroke); 318 | Pattern.RestoreGraphicsState(); 319 | return Pattern; 320 | } 321 | 322 | //////////////////////////////////////////////////////////////////// 323 | /// 324 | /// Create new PdfTilingPattern class with weave pattern. 325 | /// 326 | /// Current PDF document. 327 | /// Scale factor 328 | /// Background color. 329 | /// Horizontal line color. 330 | /// Vertical line color. 331 | /// PDF tiling pattern 332 | /// 333 | /// 334 | /// The pattern in a square with one user unit side. 335 | /// 336 | /// 337 | /// It is made of horizontal and vertical rectangles. 338 | /// 339 | /// 340 | //////////////////////////////////////////////////////////////////// 341 | public static PdfTilingPattern SetWeavePattern 342 | ( 343 | PdfDocument Document, 344 | double Scale, 345 | Color Background, 346 | Color Horizontal, 347 | Color Vertical 348 | ) 349 | { 350 | const double RectSide1 = 4.0 / 6.0; 351 | const double RectSide2 = 2.0 / 6.0; 352 | const double LineWidth = 0.2 / 6.0; 353 | const double HalfWidth = 0.5 * LineWidth; 354 | 355 | PdfTilingPattern Pattern = new PdfTilingPattern(Document); 356 | Pattern.SetScale(Scale); 357 | Pattern.SaveGraphicsState(); 358 | Pattern.SetTileBox(1.0); 359 | Pattern.SetColorNonStroking(Background); 360 | Pattern.DrawRectangle(0.0, 0.0, 1.0, 1.0, PaintOp.Fill); 361 | Pattern.SetLineWidth(LineWidth); 362 | Pattern.SetColorStroking(Background); 363 | 364 | Pattern.SetColorNonStroking(Horizontal); 365 | Pattern.DrawRectangle(HalfWidth, 1.0 / 6.0 + HalfWidth, RectSide1 - LineWidth, RectSide2 - LineWidth, PaintOp.CloseFillStroke); 366 | Pattern.DrawRectangle(-(3.0 / 6.0 - HalfWidth), 4.0 / 6.0 + HalfWidth, RectSide1 - LineWidth, RectSide2 - LineWidth, PaintOp.CloseFillStroke); 367 | Pattern.DrawRectangle(3.0 / 6.0 + HalfWidth, 4.0 / 6.0 + HalfWidth, RectSide1 - LineWidth, RectSide2 - LineWidth, PaintOp.CloseFillStroke); 368 | 369 | Pattern.SetColorNonStroking(Vertical); 370 | Pattern.DrawRectangle(4.0 / 6.0 + HalfWidth, HalfWidth, RectSide2 - LineWidth, RectSide1 - LineWidth, PaintOp.CloseFillStroke); 371 | Pattern.DrawRectangle(1.0 / 6.0 + HalfWidth, -(3.0 / 6.0 - HalfWidth), RectSide2 - LineWidth, RectSide1 - LineWidth, PaintOp.CloseFillStroke); 372 | Pattern.DrawRectangle(1.0 / 6.0 + HalfWidth, 3.0 / 6.0 + HalfWidth, RectSide2 - LineWidth, RectSide1 - LineWidth, PaintOp.CloseFillStroke); 373 | 374 | Pattern.RestoreGraphicsState(); 375 | return Pattern; 376 | } 377 | } 378 | } 379 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfDictionary.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // Barcode 7 | // Single diminsion barcode class. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | using System.Collections.Generic; 28 | using System.Text; 29 | 30 | namespace PdfFileWriter 31 | { 32 | internal enum ValueType 33 | { 34 | Other, 35 | String, 36 | Dictionary 37 | } 38 | 39 | /// 40 | /// PDF dictionary class 41 | /// 42 | /// 43 | /// 44 | /// Dictionary key value pair class. Holds one key value pair. 45 | /// 46 | /// 47 | public class PdfDictionary 48 | { 49 | internal List KeyValue; 50 | internal PdfObject Parent; 51 | internal PdfDocument Document; 52 | 53 | internal PdfDictionary 54 | ( 55 | PdfObject Parent 56 | ) 57 | { 58 | KeyValue = new List(); 59 | this.Parent = Parent; 60 | this.Document = Parent.Document; 61 | return; 62 | } 63 | 64 | internal PdfDictionary 65 | ( 66 | PdfDocument Document 67 | ) 68 | { 69 | KeyValue = new List(); 70 | this.Document = Document; 71 | return; 72 | } 73 | 74 | //////////////////////////////////////////////////////////////////// 75 | // Find key value pair in dictionary. 76 | // return index number or -1 if not found. 77 | //////////////////////////////////////////////////////////////////// 78 | 79 | internal int Find 80 | ( 81 | string Key // key (first character must be forward slash /) 82 | ) 83 | { 84 | // look through the dictionary 85 | for(int Index = 0; Index < KeyValue.Count; Index++) if(KeyValue[Index].Key == Key) return Index; 86 | 87 | // not found 88 | return -1; 89 | } 90 | 91 | //////////////////////////////////////////////////////////////////// 92 | // Add key value pair to dictionary. 93 | // The value is string format 94 | //////////////////////////////////////////////////////////////////// 95 | 96 | internal void Add 97 | ( 98 | string Key, // key (first character must be forward slash /) 99 | string Str 100 | ) 101 | { 102 | Add(Key, Str, ValueType.Other); 103 | return; 104 | } 105 | 106 | //////////////////////////////////////////////////////////////////// 107 | // Add key value pair to dictionary. 108 | // The value is string format 109 | //////////////////////////////////////////////////////////////////// 110 | 111 | internal void AddName 112 | ( 113 | string Key, // key (first character must be forward slash /) 114 | string Str 115 | ) 116 | { 117 | Add(Key, "/" + Str, ValueType.Other); 118 | return; 119 | } 120 | 121 | //////////////////////////////////////////////////////////////////// 122 | // Add key value pair to dictionary. 123 | // The value is string format 124 | //////////////////////////////////////////////////////////////////// 125 | 126 | internal void AddInteger 127 | ( 128 | string Key, // key (first character must be forward slash /) 129 | int Integer 130 | ) 131 | { 132 | Add(Key, Integer.ToString(), ValueType.Other); 133 | return; 134 | } 135 | 136 | //////////////////////////////////////////////////////////////////// 137 | // Add key value pair to dictionary. 138 | // The value is string format 139 | //////////////////////////////////////////////////////////////////// 140 | 141 | internal void AddReal 142 | ( 143 | string Key, // key (first character must be forward slash /) 144 | double Real 145 | ) 146 | { 147 | if(Math.Abs(Real) < 0.0001) Real = 0; 148 | Add(Key, string.Format(NFI.PeriodDecSep, "{0}", (float) Real), ValueType.Other); 149 | return; 150 | } 151 | 152 | //////////////////////////////////////////////////////////////////// 153 | // Add key value pair to dictionary. 154 | // The value is string format 155 | //////////////////////////////////////////////////////////////////// 156 | 157 | internal void AddReal 158 | ( 159 | string Key, // key (first character must be forward slash /) 160 | float Real 161 | ) 162 | { 163 | if(Math.Abs(Real) < 0.0001) Real = 0; 164 | Add(Key, string.Format(NFI.PeriodDecSep, "{0}", Real), ValueType.Other); 165 | return; 166 | } 167 | 168 | //////////////////////////////////////////////////////////////////// 169 | // Add key value pair to dictionary. 170 | // The value is string format 171 | //////////////////////////////////////////////////////////////////// 172 | 173 | internal void AddRectangle 174 | ( 175 | string Key, // key (first character must be forward slash /) 176 | PdfRectangle Rect 177 | ) 178 | { 179 | AddRectangle(Key, Rect.Left, Rect.Bottom, Rect.Right, Rect.Top); 180 | return; 181 | } 182 | 183 | //////////////////////////////////////////////////////////////////// 184 | // Add key value pair to dictionary. 185 | // The value is string format 186 | //////////////////////////////////////////////////////////////////// 187 | 188 | internal void AddRectangle 189 | ( 190 | string Key, // key (first character must be forward slash /) 191 | double Left, 192 | double Bottom, 193 | double Right, 194 | double Top 195 | ) 196 | { 197 | Add(Key, string.Format(NFI.PeriodDecSep, "[{0} {1} {2} {3}]", 198 | Parent.ToPt(Left), Parent.ToPt(Bottom), Parent.ToPt(Right), Parent.ToPt(Top))); 199 | return; 200 | } 201 | 202 | //////////////////////////////////////////////////////////////////// 203 | // Add key value pair to dictionary. 204 | // The value is string format 205 | //////////////////////////////////////////////////////////////////// 206 | 207 | internal void AddBoolean 208 | ( 209 | string Key, // key (first character must be forward slash /) 210 | bool Bool 211 | ) 212 | { 213 | Add(Key, Bool ? "true" : "false", ValueType.Other); 214 | return; 215 | } 216 | 217 | //////////////////////////////////////////////////////////////////// 218 | // Add key value pair to dictionary. 219 | // The value is string format 220 | //////////////////////////////////////////////////////////////////// 221 | 222 | internal void AddPdfString 223 | ( 224 | string Key, // key (first character must be forward slash /) 225 | string Str 226 | ) 227 | { 228 | Add(Key, Str, ValueType.String); 229 | return; 230 | } 231 | 232 | //////////////////////////////////////////////////////////////////// 233 | // Add key value pair to dictionary. 234 | // The value is string format 235 | //////////////////////////////////////////////////////////////////// 236 | 237 | internal void AddFormat 238 | ( 239 | string Key, // key (first character must be forward slash /) 240 | string FormatStr, 241 | params object[] FormatList 242 | ) 243 | { 244 | Add(Key, string.Format(NFI.PeriodDecSep, FormatStr, FormatList), ValueType.Other); 245 | return; 246 | } 247 | 248 | //////////////////////////////////////////////////////////////////// 249 | // Add key value pair to dictionary. 250 | // The value is a reference to indirect object number. 251 | //////////////////////////////////////////////////////////////////// 252 | 253 | internal void AddIndirectReference 254 | ( 255 | string Key, // key (first character must be forward slash /) 256 | PdfObject Obj // PdfObject. The method creates an indirect reference "n 0 R" to the object. 257 | ) 258 | { 259 | Add(Key, string.Format("{0} 0 R", Obj.ObjectNumber), ValueType.Other); 260 | return; 261 | } 262 | 263 | //////////////////////////////////////////////////////////////////// 264 | // Add key value pair to dictionary. 265 | // If dictionary does not exist, create it. 266 | // If key is not found, add the pair as new entry. 267 | // If key is found, replace old pair with new one. 268 | //////////////////////////////////////////////////////////////////// 269 | 270 | internal void AddDictionary 271 | ( 272 | string Key, // key (first character must be forward slash /) 273 | PdfDictionary Value // value 274 | ) 275 | { 276 | Add(Key, Value, ValueType.Dictionary); 277 | return; 278 | } 279 | 280 | //////////////////////////////////////////////////////////////////// 281 | // Add key value pair to dictionary. 282 | // If dictionary does not exist, create it. 283 | // If key is not found, add the pair as new entry. 284 | // If key is found, replace old pair with new one. 285 | //////////////////////////////////////////////////////////////////// 286 | 287 | private void Add 288 | ( 289 | string Key, // key (first character must be forward slash /) 290 | object Value, // value 291 | ValueType Type // value type 292 | ) 293 | { 294 | // search for existing key 295 | int Index = Find(Key); 296 | 297 | // not found - add new pair 298 | if(Index < 0) KeyValue.Add(new PdfKeyValue(Key, Value, Type)); 299 | 300 | // found replace value 301 | else 302 | { 303 | KeyValue[Index].Value = Value; 304 | KeyValue[Index].Type = Type; 305 | } 306 | 307 | // exit 308 | return; 309 | } 310 | 311 | //////////////////////////////////////////////////////////////////// 312 | // Get dictionary value 313 | // Return string if key is found, null if not 314 | //////////////////////////////////////////////////////////////////// 315 | 316 | internal PdfKeyValue GetValue 317 | ( 318 | string Key // key (first character must be forward slash /) 319 | ) 320 | { 321 | int Index = Find(Key); 322 | return Index >= 0 ? KeyValue[Index] : null; 323 | } 324 | 325 | //////////////////////////////////////////////////////////////////// 326 | // Remove key value pair from dictionary 327 | //////////////////////////////////////////////////////////////////// 328 | 329 | internal void Remove 330 | ( 331 | string Key // key (first character must be forward slash /) 332 | ) 333 | { 334 | int Index = Find(Key); 335 | if(Index >= 0) KeyValue.RemoveAt(Index); 336 | return; 337 | } 338 | 339 | //////////////////////////////////////////////////////////////////// 340 | // Write dictionary to PDF file 341 | // Called from WriteObjectToPdfFile to output a dictionary 342 | //////////////////////////////////////////////////////////////////// 343 | 344 | internal void WriteToPdfFile() 345 | { 346 | int EolMarker = 100; 347 | StringBuilder Str = new StringBuilder(); 348 | 349 | WriteToPdfFile(Str, ref EolMarker); 350 | 351 | // write to pdf file 352 | Document.PdfFile.WriteString(Str); 353 | return; 354 | } 355 | 356 | private void WriteToPdfFile(StringBuilder Str, ref int EolMarker) 357 | { 358 | Str.Append("<<"); 359 | 360 | // output dictionary 361 | foreach(PdfKeyValue KeyValueItem in KeyValue) 362 | { 363 | // add new line to cut down very long lines (just appearance) 364 | if(Str.Length > EolMarker) 365 | { 366 | Str.Append("\n"); 367 | EolMarker = Str.Length + 100; 368 | } 369 | 370 | // append the key 371 | Str.Append(KeyValueItem.Key); 372 | 373 | // dictionary type 374 | switch(KeyValueItem.Type) 375 | { 376 | // dictionary 377 | case ValueType.Dictionary: 378 | ((PdfDictionary) KeyValueItem.Value).WriteToPdfFile(Str, ref EolMarker); 379 | break; 380 | 381 | // PDF string special case 382 | case ValueType.String: 383 | Str.Append(Document.TextToPdfString((string) KeyValueItem.Value, Parent)); 384 | break; 385 | 386 | // all other key value pairs 387 | default: 388 | // add one space between key and value unless value starts with a clear separator 389 | char FirstChar = ((string) KeyValueItem.Value)[0]; 390 | if(FirstChar != '/' && FirstChar != '[' && FirstChar != '<' && FirstChar != '(') Str.Append(' '); 391 | 392 | // add value 393 | Str.Append(KeyValueItem.Value); 394 | break; 395 | } 396 | } 397 | 398 | // terminate dictionary 399 | Str.Append(">>\n"); 400 | return; 401 | } 402 | } 403 | 404 | internal class PdfKeyValue 405 | { 406 | internal string Key; // key first character must be forward slash ? 407 | internal object Value; // value associated with key 408 | internal ValueType Type; // value is a PDF string 409 | 410 | //////////////////////////////////////////////////////////////////// 411 | // Constructor 412 | //////////////////////////////////////////////////////////////////// 413 | 414 | internal PdfKeyValue 415 | ( 416 | string Key, // key first character must be forward slash ? 417 | object Value, // value associated with key 418 | ValueType Type // value type 419 | ) 420 | { 421 | if(Key[0] != '/') throw new ApplicationException("Dictionary key must start with /"); 422 | this.Key = Key; 423 | this.Value = Value; 424 | this.Type = Type; 425 | return; 426 | } 427 | } 428 | } 429 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfDisplayMedia.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfDisplayMedia 7 | // PDF display media class. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | 28 | namespace PdfFileWriter 29 | { 30 | /// 31 | /// Temporary file permission enumeration 32 | /// 33 | public enum TempFilePermission 34 | { 35 | /// 36 | /// Never allow PDF reader to write temporary file. 37 | /// 38 | TEMPNEVER, 39 | 40 | /// 41 | /// Allow PDF reader to write temporary file based on extract permission flag. 42 | /// 43 | TEMPEXTRACT, 44 | 45 | /// 46 | /// Allow PDF reader to write temporary file based on access permission flag. 47 | /// 48 | TEMPACCESS, 49 | 50 | /// 51 | /// Always allow PDF reader to write temporary file. 52 | /// 53 | TEMPALWAYS, 54 | } 55 | 56 | /// 57 | /// Media window position 58 | /// 59 | public enum MediaWindow 60 | { 61 | /// 62 | /// Floating window 63 | /// 64 | Floating, 65 | 66 | /// 67 | /// Full screen 68 | /// 69 | FullScreen, 70 | 71 | /// 72 | /// Hidden 73 | /// 74 | Hidden, 75 | 76 | /// 77 | /// Annotation rectangle 78 | /// 79 | Annotation, 80 | } 81 | 82 | /// 83 | /// Media image position within window 84 | /// 85 | public enum WindowPosition 86 | { 87 | /// 88 | /// Upper left 89 | /// 90 | UpperLeft, 91 | 92 | /// 93 | /// Upper center 94 | /// 95 | UpperCenter, 96 | 97 | /// 98 | /// Upper right 99 | /// 100 | UpperRight, 101 | 102 | /// 103 | /// Center left 104 | /// 105 | CenterLeft, 106 | 107 | /// 108 | /// Center 109 | /// 110 | Center, 111 | 112 | /// 113 | /// Center right 114 | /// 115 | CenterRight, 116 | 117 | /// 118 | /// Lower left 119 | /// 120 | LowerLeft, 121 | 122 | /// 123 | /// lower center 124 | /// 125 | LowerCenter, 126 | 127 | /// 128 | /// Lower right 129 | /// 130 | LowerRight, 131 | } 132 | 133 | /// 134 | /// Floating window title bar 135 | /// 136 | public enum WindowTitleBar 137 | { 138 | /// 139 | /// No title bar 140 | /// 141 | NoTitleBar, 142 | 143 | /// 144 | /// Window has title bar 145 | /// 146 | TitleBar, 147 | 148 | /// 149 | /// Window has title bar with close button 150 | /// 151 | TitleBarWithCloseButton, 152 | } 153 | 154 | /// 155 | /// Floating window resize options 156 | /// 157 | public enum WindowResize 158 | { 159 | /// 160 | /// No resize 161 | /// 162 | NoResize, 163 | 164 | /// 165 | /// Resize with correct aspect ratio 166 | /// 167 | KeepAspectRatio, 168 | 169 | /// 170 | /// Resize without aspect ratio 171 | /// 172 | NoAspectRatio, 173 | } 174 | 175 | /// 176 | /// Media operation code 177 | /// 178 | /// 179 | /// 180 | /// Operation to perform when rendition action is triggered. 181 | /// Page 669 T 8.64 S 8.5 182 | /// 183 | /// 184 | public enum MediaOperation 185 | { 186 | /// 187 | /// Play 188 | /// 189 | Play, 190 | 191 | /// 192 | /// Stop 193 | /// 194 | Stop, 195 | 196 | /// 197 | /// Pause 198 | /// 199 | Pause, 200 | 201 | /// 202 | /// Resume 203 | /// 204 | Resume, 205 | 206 | /// 207 | /// Play after pause 208 | /// 209 | PlayAfterPause, 210 | } 211 | 212 | /// 213 | /// Scale media code 214 | /// 215 | /// 216 | /// 217 | /// Value 0 to 5 How to scale the media to fit annotation area page 770 T 9.15 218 | /// 219 | /// 220 | public enum ScaleMediaCode 221 | { 222 | /// 223 | /// Keep aspect ratio and show all. 224 | /// 225 | KeepAspectRatioShowAll, 226 | 227 | /// 228 | /// Keep aspect ratio fit the one side and slice the other 229 | /// 230 | KeepAspectRatioSlice, 231 | 232 | /// 233 | /// Ignore aspect ratio and fill annotation rectangle 234 | /// 235 | FillAnotationRect, 236 | 237 | /// 238 | /// No scaling. Provide scroll if required 239 | /// 240 | NoScaleWithScroll, 241 | 242 | /// 243 | /// No scaling. Show what fits 244 | /// 245 | NoScaleSlice, 246 | 247 | /// 248 | /// Let media player handle it 249 | /// 250 | PlayerDefault, 251 | } 252 | 253 | /// 254 | /// PDF Screen annotation 255 | /// 256 | public class PdfDisplayMedia : PdfObject 257 | { 258 | /// 259 | /// Gets embedded media file class 260 | /// 261 | public PdfEmbeddedFile MediaFile {get; private set;} 262 | 263 | private PdfDictionary Rendition; 264 | private PdfDictionary MediaClip; 265 | private PdfDictionary MediaPlay; 266 | private PdfDictionary MediaPlayBE; 267 | private PdfDictionary MediaScreenParam; 268 | private PdfDictionary MediaScreenParamBE; 269 | private PdfDictionary TempFilePermissions; 270 | 271 | /// 272 | /// Display media constructor 273 | /// 274 | /// Embedded media file 275 | /// Mime type 276 | /// 277 | /// 278 | /// If mime type is null the program will try to convert file extension 279 | /// to mime type. If conversion is not available application exception will be raised. 280 | /// 281 | /// 282 | public PdfDisplayMedia 283 | ( 284 | PdfEmbeddedFile MediaFile, 285 | string MimeType = null 286 | ) : base(MediaFile.Document) 287 | { 288 | // save media file 289 | this.MediaFile = MediaFile; 290 | 291 | // save mimetype 292 | if(MimeType == null) MimeType = MediaFile.MimeType; 293 | if(string.IsNullOrWhiteSpace(MimeType)) throw new ApplicationException("MIME type is not defined"); 294 | 295 | // rendition dictionary page 759 Section 9.1.2 Table 9.1 296 | Rendition = new PdfDictionary(this); 297 | Dictionary.AddDictionary("/R", Rendition); 298 | 299 | // media clip 300 | MediaClip = new PdfDictionary(this); 301 | Rendition.AddDictionary("/C", MediaClip); 302 | 303 | // Media clip dictionary T 9.9 304 | TempFilePermissions = new PdfDictionary(this); 305 | MediaClip.AddDictionary("/P", TempFilePermissions); 306 | 307 | // media play 308 | MediaPlay = new PdfDictionary(this); 309 | Rendition.AddDictionary("/P", MediaPlay); 310 | 311 | // media play BE 312 | MediaPlayBE = new PdfDictionary(this); 313 | MediaPlay.AddDictionary("/BE", MediaPlayBE); 314 | 315 | // media screen parameters 316 | MediaScreenParam = new PdfDictionary(this); 317 | Rendition.AddDictionary("/SP", MediaScreenParam); 318 | 319 | // media screen parameters BE 320 | MediaScreenParamBE = new PdfDictionary(this); 321 | MediaScreenParam.AddDictionary("/BE", MediaScreenParamBE); 322 | 323 | // Section 8.5 page 669 table 8.64 324 | // type of action playing multimedia content 325 | Dictionary.Add("/S", "/Rendition"); 326 | 327 | // media clip data page 762 328 | Rendition.Add("/S", "/MR"); 329 | 330 | // Table 9.6 page 762 331 | MediaClip.AddPdfString("/CT", MimeType); 332 | MediaClip.AddIndirectReference("/D", MediaFile); 333 | MediaClip.Add("/S", "/MCD"); 334 | MediaClip.Add("/Type", "/MediaClip"); 335 | 336 | // Operation to perform when action is triggered. Valid options are 0 or 4 337 | // OP=0 force the Rendition dictionary to take over the annotation 338 | Dictionary.Add("/OP", "0"); 339 | 340 | // allow reader to always create temporary file (other options do not work) 341 | // Media clip dictionary T 9.10 page 766 342 | TempFilePermissions.AddPdfString("/TF", "TEMPALWAYS"); 343 | 344 | // do not display control 345 | MediaPlayBE.AddBoolean("/C", false); 346 | 347 | // repeat count of 1 348 | MediaPlayBE.Add("/RC", "1.0"); 349 | 350 | // media scale and position within annotation rectangle PDF default is 5 351 | // /F=2 strech media to fit annotation 352 | MediaPlayBE.Add("/F", "2"); 353 | 354 | // play rendition in annotation rectangle 355 | MediaScreenParamBE.Add("/W", "3"); 356 | 357 | // exit 358 | return; 359 | } 360 | 361 | /// 362 | /// Display media player controls 363 | /// 364 | /// Display/no display command 365 | public void DisplayControls 366 | ( 367 | bool Display 368 | ) 369 | { 370 | MediaPlayBE.AddBoolean("/C", Display); 371 | return; 372 | } 373 | 374 | /// 375 | /// Repeat count 376 | /// 377 | /// Count 378 | /// 379 | /// 380 | /// Count of zero means replay indefinitly. 381 | /// 382 | /// 383 | /// Negative count is an error. 384 | /// 385 | /// 386 | /// Count is a real (float) number. The PDF specification does not 387 | /// define how non integers are treated. 388 | /// 389 | /// 390 | public void RepeatCount 391 | ( 392 | float Count 393 | ) 394 | { 395 | MediaPlayBE.AddReal("/RC", Count); 396 | return; 397 | } 398 | 399 | /// 400 | /// Set media window 401 | /// 402 | /// Media window 403 | /// Floating window width 404 | /// Floating window height 405 | /// Floating window position 406 | /// Floating window title bar 407 | /// Floating window resize 408 | /// Floating window title 409 | /// 410 | /// 411 | /// All optional arguments are applicable to floating window only. 412 | /// 413 | /// 414 | public void SetMediaWindow 415 | ( 416 | MediaWindow MediaWindow, 417 | int Width = 0, 418 | int Height = 0, 419 | WindowPosition Position = WindowPosition.Center, 420 | WindowTitleBar TitleBar = WindowTitleBar.TitleBarWithCloseButton, 421 | WindowResize Resize = WindowResize.KeepAspectRatio, 422 | string Title = null 423 | ) 424 | { 425 | // set media play window code 426 | MediaScreenParamBE.AddInteger("/W", (int) MediaWindow); 427 | 428 | // all choices but floating window 429 | if(MediaWindow != MediaWindow.Floating) 430 | { 431 | MediaScreenParamBE.Remove("/F"); 432 | return; 433 | } 434 | 435 | // play rendition in floating window 436 | // Table 9.19 page 774 437 | PdfDictionary FloatingWindow = new PdfDictionary(this); 438 | MediaScreenParamBE.AddDictionary("/F", FloatingWindow); 439 | 440 | // window's dimensions 441 | if(Width == 0 || Height == 0) 442 | { 443 | Width = 320; 444 | Height = 180; 445 | } 446 | FloatingWindow.AddFormat("/D", "[{0} {1}]", Width, Height); 447 | 448 | FloatingWindow.AddInteger("/P", (int) Position); 449 | 450 | FloatingWindow.AddBoolean("/T", TitleBar != WindowTitleBar.NoTitleBar); 451 | if(TitleBar == WindowTitleBar.NoTitleBar) return; 452 | 453 | FloatingWindow.AddInteger("/R", (int) Resize); 454 | 455 | if(Title != null) 456 | { 457 | FloatingWindow.AddFormat("/TT", "[{0} {1}]", Document.TextToPdfString(string.Empty, this), Document.TextToPdfString(Title, this)); 458 | } 459 | 460 | return; 461 | } 462 | 463 | /// 464 | /// Scale media 465 | /// 466 | /// Scale media code 467 | public void ScaleMedia 468 | ( 469 | ScaleMediaCode ScaleCode 470 | ) 471 | { 472 | // media scale and position within annotation rectangle 473 | // Value 0 to 5 How to scale the media to fit annotation area page 770 T 9.15 474 | MediaPlayBE.AddInteger("/F", (int) ScaleCode); 475 | return; 476 | } 477 | 478 | /// 479 | /// Initial media operation 480 | /// 481 | /// Media operation code enumeration 482 | public void InitialMediaOperation 483 | ( 484 | MediaOperation OperationCode 485 | ) 486 | { 487 | // Operation to perform when rendition action is triggered. 488 | // Page 669 T 8.64 S 8.5 489 | Dictionary.AddInteger("/OP", (int) OperationCode); 490 | return; 491 | } 492 | 493 | /// 494 | /// Media temporary file permission 495 | /// 496 | /// Permissions flags 497 | /// 498 | /// The PDF reader must save the media file to a temporary file 499 | /// in order for the player to play it. 500 | /// 501 | public void MediaTempFilePermission 502 | ( 503 | TempFilePermission Permission 504 | ) 505 | { 506 | // allow reader to always create temporary file (other options do not work) 507 | // Media clip dictionary T 9.10 page 766 508 | TempFilePermissions.AddPdfString("/TF", Permission.ToString()); 509 | return; 510 | } 511 | } 512 | } 513 | -------------------------------------------------------------------------------- /PdfFileWriter/PdfFontFileClasses.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | // 3 | // PdfFileWriter 4 | // PDF File Write C# Class Library. 5 | // 6 | // PdfFontFileClasses 7 | // Support classes for the PdfFontFile classs. 8 | // 9 | // Uzi Granot 10 | // Version: 1.0 11 | // Date: April 1, 2013 12 | // Copyright (C) 2013-2019 Uzi Granot. All Rights Reserved 13 | // 14 | // PdfFileWriter C# class library and TestPdfFileWriter test/demo 15 | // application are free software. 16 | // They is distributed under the Code Project Open License (CPOL). 17 | // The document PdfFileWriterReadmeAndLicense.pdf contained within 18 | // the distribution specify the license agreement and other 19 | // conditions and notes. You must read this document and agree 20 | // with the conditions specified in order to use this software. 21 | // 22 | // For version history please refer to PdfDocument.cs 23 | // 24 | ///////////////////////////////////////////////////////////////////// 25 | 26 | using System; 27 | 28 | namespace PdfFileWriter 29 | { 30 | ///////////////////////////////////////////////////////////////////// 31 | // Font file header 32 | ///////////////////////////////////////////////////////////////////// 33 | 34 | internal class FontFileHeader 35 | { 36 | internal uint FileVersion; // 0x00010000 for version 1.0. 37 | internal ushort NumTables; // Number of tables. 38 | 39 | // 16 * (maximum power of 2 <= numTables) 40 | internal ushort SearchRange 41 | { 42 | get 43 | { 44 | int Mask; 45 | for(Mask = 1; Mask <= NumTables; Mask <<= 1); 46 | return (ushort) (Mask << 3); 47 | } 48 | } 49 | 50 | // Log2(maximum power of 2 <= numTables). 51 | internal ushort EntrySelector 52 | { 53 | get 54 | { 55 | int Power; 56 | for(Power = 1; (1 << Power) <= NumTables; Power++); 57 | return (ushort) (Power - 1); 58 | } 59 | } 60 | 61 | // NumTables x 16-searchRange. 62 | internal ushort RangeShift 63 | { 64 | get 65 | { 66 | return (ushort) (16 * NumTables - SearchRange); 67 | } 68 | } 69 | } 70 | 71 | ///////////////////////////////////////////////////////////////////// 72 | // Font file table record 73 | ///////////////////////////////////////////////////////////////////// 74 | 75 | internal class TableRecord 76 | { 77 | internal uint Tag; // 4 -byte identifier 78 | internal uint Checksum; // Checksum for this table 79 | internal int Offset; // Offset from beginning of TrueType font file 80 | internal int Length; // Length of this table 81 | internal byte[] Data; // table data in big endian format 82 | 83 | // constructor 84 | internal TableRecord 85 | ( 86 | uint Tag 87 | ) 88 | { 89 | this.Tag = Tag; 90 | return; 91 | } 92 | } 93 | 94 | ///////////////////////////////////////////////////////////////////// 95 | // 'cmap' encoding sub-table 96 | ///////////////////////////////////////////////////////////////////// 97 | 98 | internal class cmapSubTbl : IComparable 99 | { 100 | internal ushort PlatformID; // Platform ID. Should be 3 for windows 101 | internal ushort EncodingID; // Platform-specific encoding ID. Should be 1 for Unicode and 0 for symbol 102 | internal ushort Format; // Format number (the program supports format 0 or 4) 103 | internal uint Offset; // Byte offset from beginning of table to the sub-table for this encoding 104 | internal ushort Length; // This is the length in bytes of the sub-table. 105 | internal ushort Language; // this field is relevant to Macintosh (platform ID 1) 106 | internal ushort SegCount; // (Format 4) SegCount. 107 | internal cmapSeg[] SegArray; // (Format 4) segment array 108 | internal ushort[] GlyphArray; // glyph array translate character for format 0 or index for format 4 to glyph code 109 | 110 | // default constructor 111 | internal cmapSubTbl() {} 112 | 113 | // search constructor 114 | internal cmapSubTbl 115 | ( 116 | ushort PlatformID, 117 | ushort EncodingID, 118 | ushort Format 119 | ) 120 | { 121 | this.PlatformID = PlatformID; 122 | this.EncodingID = EncodingID; 123 | this.Format = Format; 124 | return; 125 | } 126 | 127 | // compare two sub-tables for sort and binary search 128 | public int CompareTo 129 | ( 130 | cmapSubTbl Other 131 | ) 132 | { 133 | if(this.PlatformID != Other.PlatformID) return PlatformID - Other.PlatformID; 134 | if(this.EncodingID != Other.EncodingID) return EncodingID - Other.EncodingID; 135 | return Format - Other.Format; 136 | } 137 | 138 | // 2 x segCount 139 | internal ushort SegCountX2 140 | { 141 | get 142 | { 143 | return (ushort) (2 * SegCount); 144 | } 145 | } 146 | 147 | // 2 * (maximum power of 2 <= numTables) 148 | internal ushort SearchRange 149 | { 150 | get 151 | { 152 | int Mask; 153 | for(Mask = 1; Mask <= SegCount; Mask <<= 1); 154 | return (ushort) Mask; 155 | } 156 | } 157 | 158 | // Log2(maximum power of 2 <= numTables). 159 | internal ushort EntrySelector 160 | { 161 | get 162 | { 163 | int Power; 164 | for(Power = 1; (1 << Power) <= SegCount; Power++); 165 | return (ushort) (Power - 1); 166 | } 167 | } 168 | 169 | // NumTables x 16-searchRange. 170 | internal ushort RangeShift 171 | { 172 | get 173 | { 174 | return (ushort) (2 * SegCount - SearchRange); 175 | } 176 | } 177 | } 178 | 179 | ///////////////////////////////////////////////////////////////////// 180 | // 'cmap' format 4 encoding sub-table segment record 181 | ///////////////////////////////////////////////////////////////////// 182 | 183 | internal class cmapSeg : IComparable 184 | { 185 | internal ushort StartChar; // Start character code for each segment. Array length=segCount 186 | internal ushort EndChar; // End characterCode for each segment, last=0xFFFF. Array length=segCount 187 | internal short IDDelta; // Delta for all character codes in segment. Array length=segCount 188 | internal ushort IDRangeOffset; // Offsets (in byte) into glyphIdArray or 0. Array length=segCount 189 | 190 | // search constructor 191 | internal cmapSeg 192 | ( 193 | int StartChar, 194 | int EndChar, 195 | int IDDelta, 196 | int IDRangeOffset 197 | ) 198 | { 199 | this.StartChar = (ushort) StartChar; 200 | this.EndChar = (ushort) EndChar; 201 | this.IDDelta = (short) IDDelta; 202 | this.IDRangeOffset = (ushort) IDRangeOffset; 203 | return; 204 | } 205 | 206 | // search constructor 207 | internal cmapSeg 208 | ( 209 | int EndCount 210 | ) 211 | { 212 | this.EndChar = (ushort) EndCount; 213 | return; 214 | } 215 | 216 | // compare two records for sort and binary search 217 | public int CompareTo 218 | ( 219 | cmapSeg Other 220 | ) 221 | { 222 | return EndChar - Other.EndChar; 223 | } 224 | } 225 | 226 | ///////////////////////////////////////////////////////////////////// 227 | // 'head' font file header table 228 | ///////////////////////////////////////////////////////////////////// 229 | 230 | internal class headTable 231 | { 232 | internal uint TableVersion; // 0x00010000 for version 1.0. 233 | internal uint FontRevision; // Set by font manufacturer. 234 | internal uint ChecksumAdjustment; // font file overall checksum. To compute: set it to 0, sum the entire font, then store 0xB1B0AFBA - sum. 235 | internal uint MagicNumber; // Set to 0x5F0F3CF5. 236 | internal ushort Flags; // Bit 0: Baseline for font at y=0; 237 | // Bit 1: Left sidebearing point at x=0; 238 | // Bit 2: Instructions may depend on point size; 239 | // Bit 3: Force ppem to integer values for all internal scaler math; may use fractional 240 | // ppem sizes if this bit is clear; 241 | // Bit 4: Instructions may alter advance width (the advance widths might not scale linearly); 242 | // Bits 5-10: These should be set according to Apple's specification. 243 | // However, they are not implemented in OpenType. 244 | // Bit 11: Font data is 'lossless,' as a result of having been compressed and decompressed 245 | // with the Agfa MicroType Express engine. 246 | // Bit 12: Font converted (produce compatible metrics) 247 | // Bit 13: Font optimized for ClearType™. Note, fonts that rely on embedded bitmaps (EBDT) 248 | // for rendering should not be considered optimized for ClearType, 249 | // and therefore should keep this bit cleared. 250 | // Bit 14: Reserved, set to 0 251 | // Bit 15: Reserved, set to 0 252 | internal ushort UnitsPerEm; // Valid range is from 16 to 16384. This value should be a power of 2 for fonts that have TrueType outlines. 253 | internal long TimeCreated; // Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer 254 | internal long TimeModified; // Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer 255 | internal short xMin; // For all glyph bounding boxes. 256 | internal short yMin; // For all glyph bounding boxes. 257 | internal short xMax; // For all glyph bounding boxes. 258 | internal short yMax; // For all glyph bounding boxes. 259 | internal ushort MacStyle; // Bit 0: Bold (if set to 1); 260 | // Bit 1: Italic (if set to 1) 261 | // Bit 2: Underline (if set to 1) 262 | // Bit 3: Outline (if set to 1) 263 | // Bit 4: Shadow (if set to 1) 264 | // Bit 5: Condensed (if set to 1) 265 | // Bit 6: Extended (if set to 1) 266 | // Bits 7-15: Reserved (set to 0). 267 | internal ushort LowestRecPPEM; // Smallest readable size in pixels. 268 | internal short FontDirectionHint; // Deprecated (Set to 2). 269 | // 0: Fully mixed directional glyphs; 270 | // 1: Only strongly left to right; 271 | // 2: Like 1 but also contains neutrals; 272 | // -1: Only strongly right to left; 273 | // -2: Like -1 but also contains neutrals. 1 274 | internal short IndexToLocFormat; // 0 for short offsets, 1 for long. 275 | internal short glyphDataFormat; // 0 for current format. 276 | } 277 | 278 | ///////////////////////////////////////////////////////////////////// 279 | // 'head' horizontal header table 280 | ///////////////////////////////////////////////////////////////////// 281 | 282 | internal class hheaTable 283 | { 284 | internal uint TableVersion; // 0x00010000 for version 1.0. 285 | internal short Ascender; // Typographic ascent. (Distance from baseline of highest ascender) 286 | internal short Descender; // Typographic descent. (Distance from baseline of lowest descender) 287 | internal short LineGap; // Typographic line gap. Negative LineGap values are treated as zero 288 | // in Windows 3.1, System 6, and System 7. 289 | internal ushort advanceWidthMax; // Maximum advance width value in 'hmtx' table. 290 | internal short minLeftSideBearing; // Minimum left sidebearing value in 'hmtx' table. 291 | internal short minRightSideBearing; // Minimum right sidebearing value; calculated as Min(aw - lsb - (xMax - xMin)). 292 | internal short xMaxExtent; // Max(lsb + (xMax - xMin)). 293 | internal short caretSlopeRise; // Used to calculate the slope of the cursor (rise/run); 1 for vertical. 294 | internal short caretSlopeRun; // 0 for vertical. 295 | internal short caretOffset; // The amount by which a slanted highlight on a glyph needs to be shifted 296 | // to produce the best appearance. Set to 0 for non-slanted fonts 297 | internal short Reserved1; // set to 0 298 | internal short Reserved2; // set to 0 299 | internal short Reserved3; // set to 0 300 | internal short Reserved4; // set to 0 301 | internal short metricDataFormat; // 0 for current format. 302 | internal ushort numberOfHMetrics; // Number of hMetric entries in 'hmtx' table 303 | } 304 | 305 | ///////////////////////////////////////////////////////////////////// 306 | // 'maxp' font maximum values 307 | ///////////////////////////////////////////////////////////////////// 308 | 309 | internal class maxpTable 310 | { 311 | internal uint TableVersion; // 0x00010000 for version 1.0. 312 | internal ushort numGlyphs; // The number of glyphs in the font. 313 | internal ushort maxPoints; // Maximum points in a non-composite glyph. 314 | internal ushort maxContours; // Maximum contours in a non-composite glyph. 315 | internal ushort maxCompositePoints; // Maximum points in a composite glyph. 316 | internal ushort maxCompositeContours; // Maximum contours in a composite glyph. 317 | internal ushort maxZones; // 1 if instructions do not use the twilight zone (Z0), or 318 | // 2 if instructions do use Z0; should be set to 2 in most cases. 319 | internal ushort maxTwilightPoints; // Maximum points used in Z0. 320 | internal ushort maxStorage; // Number of Storage Area locations. 321 | internal ushort maxFunctionDefs; // Number of FDEFs. 322 | internal ushort maxInstructionDefs; // Number of IDEFs. 323 | internal ushort maxStackElements; // Maximum stack depth2. 324 | internal ushort maxSizeOfInstructions; // Maximum byte count for glyph instructions. 325 | internal ushort maxComponentElements; // Maximum number of components referenced at “top level” for any composite glyph. 326 | internal ushort maxComponentDepth; // Maximum levels of recursion; 1 for simple components. 327 | } 328 | 329 | ///////////////////////////////////////////////////////////////////// 330 | // Glyph table support 331 | ///////////////////////////////////////////////////////////////////// 332 | 333 | // glyph flags for comosite glyphs 334 | internal enum CompFlag 335 | { 336 | Arg1AndArg2AreWords = 1, // bit0 If this is set, the arguments are words; otherwise, they are bytes. 337 | ArgsAreXYValues = 2, // bit1 If this is set, the arguments are xy values; otherwise, they are points. 338 | RoundXYToGrid = 4, // bit2 For the xy values if the preceding is true. 339 | WeHaveAScale = 8, // bit3 This indicates that there is a simple scale for the component. Otherwise, scale = 1.0. 340 | Reserve = 0x10, // bit4 This bit is reserved. Set it to 0. 341 | MoreComponents = 0x20, // bit5 Indicates at least one more glyph after this one. 342 | WeHaveXYScale = 0x40, // bit6 The x direction will use a different scale from the y direction. 343 | WeHave2By2 = 0x80, // bit7 There is a 2 by 2 transformation that will be used to scale the component. 344 | WeHaveInstructions = 0x100, // bit8 Following the last component are instructions for the composite character. 345 | UseMyMetrics = 0x200, // bit9 If set, this forces the aw and lsb (and rsb) for the composite to be equal 346 | // to those from this original glyph. This works for hinted and unhinted characters. 347 | OverlapCompound = 0x400, // bit10 Used by Apple in GX fonts. 348 | ScaledComponentOffset = 0x800, // bit11 Composite designed to have the component offset scaled (designed for Apple rasterizer). 349 | UnscaledComponentOffset = 0x1000, // bit12 Composite designed not to have the component offset scaled (designed for the Microsoft TrueType rasterizer). 350 | } 351 | } 352 | --------------------------------------------------------------------------------