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;
        }
Example #3
0
        ////////////////////////////////////////////////////////////////////
        // 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;
        }