public PdfDocumentWriter(Stream stream, PdfDocumentOptions options = null)
        {
            // Initialize collections and object references:
            this.Xref = new List<long>();
            this.Fonts = new Dictionary<string, PdfObjectRef>();
            this.XObjects = new Dictionary<string, PdfObjectRef>();
            this.XObjectsRev = new Dictionary<PdfObjectRef, string>();
            this.ImageRatios = new Dictionary<PdfObjectRef, double>();
            this.CatalogRef = NewObjectRef();
            this.PagesRef = NewObjectRef();
            this.ResourcesRef = NewObjectRef();
            this.InfoRef = NewObjectRef();

            // Wrap the given stream in a Position-logging stream and build a StreamWriter:
            this.InnerWriter = new StreamWriter(new PositionStream(stream), Encoding.ASCII);

            // Make sure options are set:
            this.Options = options ?? new PdfDocumentOptions();

            // Write document introduction:
            this.WriteIntro();
        }
 /// <summary>
 /// Draws an image (convenience method).
 /// Assumes default naming of object references is used.
 /// </summary>
 public void DrawImageByRef2(double x1, double y1, double x2, double y2, PdfObjectRef imageRef)
 {
     this.DrawImageByName2(x1, y1, x2, y2, imageRef.ToDefaultName());
 }
 /// <summary>
 /// Draws an image (convenience method).
 /// Assumes default naming of object references is used.
 /// </summary>
 public void DrawImageByRef(double x, double y, double width, double height, PdfObjectRef imageRef)
 {
     this.DrawImageByName(x, y, width, height, imageRef.ToDefaultName());
 }
 /// <summary>
 /// Adds the object referenced by the given object reference to this page.
 /// </summary>
 public virtual void WriteObjectRef(PdfObjectRef objRef)
 {
     Content.Add(objRef);
 }
        /// <summary>
        /// Writes a PdfObject to this document given its object reference.
        /// </summary>
        public virtual void WriteObject(PdfObject obj, PdfObjectRef objRef)
        {
            if (obj is PdfScriptObject)
            {
                foreach (var font in ((PdfScriptObject)obj).ReferencedFonts)
                    RegisterFont(font);
            }

            Xref[objRef.ObjectId-1] = this.Position;

            var builder = new StringBuilder();
            builder.Append(objRef.ObjectId + " " + objRef.GenerationId + " obj\n");
            if (obj.Data != null || obj.Stream != null)
            {
                builder.Append("<<\n");
                if (obj.Data != null)
                {
                    foreach (var pair in obj.Data)
                    {
                        builder.Append('/');
                        builder.Append(pair.Key);
                        builder.Append(' ');
                        builder.Append(pair.Value.ToString());
                        builder.Append('\n');
                    }
                }
                if (obj.Stream == null)
                {
                    builder.Append(">>\n");
                }
                else if (obj.Stream is PdfBinaryStream)
                {
                    var s = ((PdfBinaryStream)obj.Stream);
                    builder.Append("/Length ");
                    builder.Append(s.Length);
                    builder.Append("\n/Filter [");
                    builder.Append(s.Filter);
                    builder.Append("]\n>>\n");
                    builder.Append("stream\n");

                    this.WriteRaw(builder.ToString());
                    builder.Length = 0;
                    this.WriteRaw(s.Content, 0, s.Content.Length);

                    builder.Append("\nendstream\n");
                }
                else
                {
                    byte[] bytes;
                    if ((obj.Stream is PdfTextStream) && (this.Options.TextFilter != null))
                    {
                        bytes = this.Options.TextFilter.EncodeString(((PdfTextStream)obj.Stream).Content.ToString());
                        builder.Append("/Filter [");
                        builder.Append(this.Options.TextFilter.Name);
                        builder.Append("]\n");
                    }
                    else
                    {
                        bytes = Encoding.Default.GetBytes(((PdfTextStream)obj.Stream).Content.ToString());
                    }
                    builder.Append("/Length ");
                    builder.Append(bytes.Length);
                    builder.Append('\n');

                    builder.Append(">>\n");

                    builder.Append("stream\n");

                    this.WriteRaw(builder.ToString());
                    builder.Length = 0;
                    this.WriteRaw(bytes, 0, bytes.Length);

                    builder.Append("\nendstream\n");
                }
            }
            builder.Append("endobj\n");

            this.WriteRaw(builder.ToString());
        }
 /// <summary>
 /// Returns the height the previoulsy added image should have, when rendered with the given width, in order to have
 /// the same aspect ration.
 /// </summary>
 /// <param name="imageRef">Reference to the image previoulsy added.</param>
 /// <param name="forWidth">Width to render the image with.</param>
 public double GetImageHeight(PdfObjectRef imageRef, double forWidth)
 {
     return this.ImageRatios[imageRef] * forWidth;
 }
 public double GetImageAspectRatio(PdfObjectRef imageRef)
 {
     return this.ImageRatios[imageRef];
 }
 /// <summary>
 /// Retrieves the name of a previously added XObject.
 /// </summary>
 public string GetNameOfXObject(PdfObjectRef objRef)
 {
     return this.XObjectsRev[objRef];
 }
 protected void RegisterXObject(PdfObjectRef objRef, string name)
 {
     XObjects[name] = objRef;
     XObjectsRev[objRef] = name;
 }