private PdfEmbeddedFile ( PdfDocument Document, string FileName, string PdfFileName ) : base(Document, ObjectType.Dictionary, "/Filespec") { // save file name this.FileName = FileName; // test exitance if (!File.Exists(FileName)) { throw new ApplicationException("Embedded file " + FileName + " does not exist"); } // get file length FileInfo FI = new FileInfo(FileName); if (FI.Length > int.MaxValue - 4095) { throw new ApplicationException("Embedded file " + FileName + " too long"); } int FileLength = (int)FI.Length; // translate file extension to mime type string MimeType = ExtToMime.TranslateExtToMime(FI.Extension); // create embedded file object PdfObject EmbeddedFile = new PdfObject(Document, ObjectType.Stream, "/EmbeddedFile"); // save uncompressed file length EmbeddedFile.Dictionary.AddFormat("/Params", "<</Size {0}>>", FileLength); // file data content byte array EmbeddedFile.ObjectValueArray = new byte[FileLength]; // load all the file's data FileStream DataStream = null; try { // open the file DataStream = new FileStream(FileName, FileMode.Open, FileAccess.Read); // read all the file if (DataStream.Read(EmbeddedFile.ObjectValueArray, 0, FileLength) != FileLength) { throw new Exception(); } } // loading file failed catch (Exception) { throw new ApplicationException("Invalid media file: " + FileName); } // close the file DataStream.Close(); // debug if (Document.Debug) { EmbeddedFile.ObjectValueArray = Document.TextToByteArray("*** MEDIA FILE PLACE HOLDER ***"); } // write stream EmbeddedFile.WriteObjectToPdfFile(); // file spec object type Dictionary.Add("/Type", "/Filespec"); // PDF file name if (string.IsNullOrWhiteSpace(PdfFileName)) { PdfFileName = FI.Name; } Dictionary.AddPdfString("/F", PdfFileName); Dictionary.AddPdfString("/UF", PdfFileName); // add reference Dictionary.AddFormat("/EF", "<</F {0} 0 R /UF {0} 0 R>>", EmbeddedFile.ObjectNumber); return; }
//////////////////////////////////////////////////////////////////// // Write object to PDF file //////////////////////////////////////////////////////////////////// internal override void WriteObjectToPdfFile ( BinaryWriter PdfFile ) { // look for first and last character Int32 FirstChar; Int32 LastChar; for (FirstChar = 0; FirstChar < 256 && !ActiveChar[FirstChar]; FirstChar++) { ; } if (FirstChar == 256) { return; } for (LastChar = 255; !ActiveChar[LastChar]; LastChar--) { ; } // pdf font name StringBuilder PdfFontName = new StringBuilder("/"); // for embedded font add 6 alpha characters prefix if (EmbeddedFont) { PdfFontName.Append("PFWAAA+"); Int32 Ptr1 = 6; for (Int32 Ptr2 = ResourceCode.Length - 1; Ptr2 >= 0 && Char.IsDigit(ResourceCode[Ptr2]); Ptr2--) { PdfFontName[Ptr1--] = (Char)((Int32)ResourceCode[Ptr2] + ('A' - '0')); } } // PDF readers are not happy with space in font name PdfFontName.Append(FontFamily.Name.Replace(" ", "#20")); // font name if ((DesignFont.Style & FontStyle.Bold) != 0) { if ((DesignFont.Style & FontStyle.Italic) != 0) { PdfFontName.Append(",BoldItalic"); } else { PdfFontName.Append(",Bold"); } } else if ((DesignFont.Style & FontStyle.Italic) != 0) { PdfFontName.Append(",Italic"); } // add items to dictionary AddToDictionary("/Subtype", "/TrueType"); AddToDictionary("/BaseFont", PdfFontName.ToString()); // add first and last characters AddToDictionary("/FirstChar", FirstChar.ToString()); AddToDictionary("/LastChar", LastChar.ToString()); // create font descriptor FontDescriptor = new PdfObject(Document, false, "/FontDescriptor"); // add link to font object AddToDictionary("/FontDescriptor", FontDescriptor); // font descriptor dictionary FontDescriptor.AddToDictionary("/FontName", PdfFontName.ToString()); // must be the same as BaseFont above FontDescriptor.AddToDictionary("/Flags", ((Int32)FontFlags).ToString()); FontDescriptor.AddToDictionary("/ItalicAngle", String.Format(NFI.DecSep, "{0}", (Single)PdfItalicAngle)); FontDescriptor.AddToDictionary("/FontWeight", PdfFontWeight.ToString()); FontDescriptor.AddToDictionary("/Leading", String.Format(NFI.DecSep, "{0}", (Single)FontUnitsToPdfDic(PdfLeading))); FontDescriptor.AddToDictionary("/Ascent", String.Format(NFI.DecSep, "{0}", (Single)FontUnitsToPdfDic(PdfAscent))); FontDescriptor.AddToDictionary("/Descent", String.Format(NFI.DecSep, "{0}", (Single)FontUnitsToPdfDic(-PdfDescent))); // alphabetic (non symbolic) fonts if ((FontFlags & PdfFontFlags.Symbolic) == 0) { AddToDictionary("/Encoding", "/WinAnsiEncoding"); BoundingBox Box = FontInfo.GetGlyphMetricsApi('x'); FontDescriptor.AddToDictionary("/XHeight", String.Format(NFI.DecSep, "{0}", (Single)FontUnitsToPdfDic(Box.Rect.Top))); FontDescriptor.AddToDictionary("/AvgWidth", String.Format(NFI.DecSep, "{0}", (Single)FontUnitsToPdfDic(Box.Width))); Box = FontInfo.GetGlyphMetricsApi('M'); PdfCapHeight = Box.Rect.Top; FontDescriptor.AddToDictionary("/CapHeight", String.Format(NFI.DecSep, "{0}", (Single)FontUnitsToPdfDic(Box.Rect.Top))); FontDescriptor.AddToDictionary("/StemV", String.Format(NFI.DecSep, "{0}", (Single)StemV())); } // create width object array FontWidthArray = new PdfObject(Document, false); // add link to font object AddToDictionary("/Widths", FontWidthArray); // build bounding box and width array Double Left = Double.MaxValue; Double Bottom = Double.MaxValue; Double Right = Double.MinValue; Double Top = Double.MinValue; Double MaxWidth = Double.MinValue; FontWidthArray.ContentsString = new StringBuilder("["); Int32 EolLength = 100; for (Int32 Index = FirstChar; Index <= LastChar; Index++) { Double CharWidth; // not used if (!ActiveChar[Index]) { CharWidth = 0; } // used else { // bounding box BoundingBox GM = GlyphArray[Index]; if (GM.Rect.Left < Left) { Left = GM.Rect.Left; } if (GM.Rect.Bottom < Bottom) { Bottom = GM.Rect.Bottom; } if (GM.Rect.Right > Right) { Right = GM.Rect.Right; } if (GM.Rect.Top > Top) { Top = GM.Rect.Top; } // character advance width CharWidth = GM.Width; // max width if (CharWidth > MaxWidth) { MaxWidth = CharWidth; } } // add width to width array if (FontWidthArray.ContentsString.Length > EolLength) { FontWidthArray.ContentsString.Append('\n'); EolLength = FontWidthArray.ContentsString.Length + 100; } // add width to width array FontWidthArray.ContentsString.AppendFormat(NFI.DecSep, "{0} ", FontUnitsToPdfDic(CharWidth)); } // add to font descriptor array FontDescriptor.AddToDictionary("/MaxWidth", String.Format(NFI.DecSep, "{0}", (Single)FontUnitsToPdfDic(MaxWidth))); FontDescriptor.AddToDictionary("/FontBBox", String.Format(NFI.DecSep, "[{0} {1} {2} {3}]", FontUnitsToPdfDic(Left), FontUnitsToPdfDic(Bottom), FontUnitsToPdfDic(Right), FontUnitsToPdfDic(Top))); // terminate width array FontWidthArray.ContentsString.Length--; FontWidthArray.ContentsString.Append("]"); // create font file if (EmbeddedFont) { // create font file stream PdfFontFile EmbeddedFontObj = new PdfFontFile(this); // add link to font object FontDescriptor.AddToDictionary("/FontFile2", EmbeddedFontObj); } // call base write PdfObject to file method base.WriteObjectToPdfFile(PdfFile); // exit return; }
//////////////////////////////////////////////////////////////////// // Initial Object Array //////////////////////////////////////////////////////////////////// private void ConstructorHelper ( double Width, // page width double Height, // page height double ScaleFactor, // scale factor from user units to points (i.e. 72.0 for inch) string FileName, Stream OutputStream ) { // set scale factor (user units to points) this.ScaleFactor = ScaleFactor; // set epsilon (1/300 of an inch in user units) this.Epsilon = 72.0 / (300.0 * ScaleFactor); // save page default size PageSize = new SizeD(Width, Height); // PDF document root object the Catalog object CatalogObject = new PdfObject(this, ObjectType.Dictionary, "/Catalog"); // add viewer preferences CatalogObject.Dictionary.Add("/ViewerPreferences", "<</PrintScaling/None>>"); // Parent object for all pages PagesObject = new PdfObject(this, ObjectType.Dictionary, "/Pages"); // add indirect reference to pages within the catalog object CatalogObject.Dictionary.AddIndirectReference("/Pages", PagesObject); // create trailer dictionary TrailerDict = new PdfDictionary(this); // add /Root TrailerDict.AddIndirectReference("/Root", CatalogObject); // document id DocumentID = RandomByteArray(16); // add /ID TrailerDict.AddFormat("/ID", "[{0}{0}]", ByteArrayToPdfHexString(DocumentID)); // create file using file name if (FileName != null) { // save file name this.FileName = FileName; // constructor helper PdfFile = new PdfBinaryWriter(new FileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.None)); } // write to caller's file or memory stream else { PdfFile = new PdfBinaryWriter(OutputStream); } // write PDF version number PdfFile.WriteString("%PDF-1.7\n"); // add this comment to tell compression programs that this is a binary file PdfFile.WriteString("%\u00b5\u00b5\u00b5\u00b5\n"); // exit return; }