Document Solutions for PDF
Features / Annotations / Appearance Streams
In This Topic
    Appearance Streams
    In This Topic

    Annotations have their own set of appearance properties like border, color, shape etc. However, it is not necessary that all PDF viewers render the exact same appearance of an annotation. Hence, the need of appearance streams. They allow you to represent annotations visually as a set of drawing commands so that the viewer knows how to render an annotation precisely.

    An annotation may have following appearances associated with their states:

    An annotation may have one or several appearance streams associated with it. An appearance stream is basically a FormXObject which is a rectangular area with graphics and anything drawn on that graphics is displayed when the annotation is in a normal, rollover or down state.

    DsPdf provides an AppearanceStreams class which has Normal, Rollover and Down properties corresponding to their states. The type of these properties is Appearance and it provides access to the Default FormXObject, and a dictionary of FormXObject which is associated with specific states.

    However, to handle annotations generating rich text such as FreeTextAnnotation and LineAnnotation, the GcPdfDocument class provides a boolean property BuildRichTextAppearanceStreams which is set to false, by default. For such annotations, DsPdf does not generate appearance streams for them by default. When the BuildRichTextAppearanceStreams property is set to true, the DsPdf library generates appearance streams for such annotations and renders the rich text of these annotations as plain text.

    In addition, the AnnotationBase class provides RemoveAppearance() method to remove all appearance streams associated with the annotations. The method disables the generation of appearance streams when the document is saved. This helps in reducing the file size of exported PDF document.

    The following code illustrates how to add an appearance stream to a stamp annotation in a PDF document and then, shows how to remove the same.

    C#
    Copy Code
    var doc = new GcPdfDocument();
    // Load an existing PDF to which we will add a stamp annotation
    var jsFile = Path.Combine("Resources", "PDFs", "The-Rich-History-of-JavaScript.pdf");
    
    using (var fs = new FileStream(jsFile, FileMode.Open, FileAccess.Read))
    {
        doc.Load(fs);
        var rect = new RectangleF(PointF.Empty, doc.Pages[0].Size);
        // Create a FormXObject to use as the stamp appearance
        var fxo = new FormXObject(doc, rect);
        // Get an image from the resources, and draw it on the FormXObject's graphics
        using (var image = Image.FromFile(Path.Combine("Resources", "ImagesBis", "draft-copy-450x72.png")))
        {
            var center = new Vector2(fxo.Bounds.Width / 2, fxo.Bounds.Height / 2);
            fxo.Graphics.Transform =
                Matrix3x2.CreateRotation((float)(-55 * Math.PI) / 180f, center) *
                Matrix3x2.CreateScale(6, center);
            fxo.Graphics.DrawImage(image, fxo.Bounds, null, ImageAlign.CenterImage);
            // Loop over pages, add a stamp to each page
            foreach (var page in doc.Pages)
            {
                // Create a StampAnnotation over the whole page
                var stamp = new StampAnnotation()
                {
                    Icon = StampAnnotationIcon.Draft.ToString(),
                    Name = "draft",
                    Page = page,
                    Rect = rect,
                    UserName = "Jaime Smith"
                };
                // Add a custom appearance stream by re-using the same FormXObject on all pages
                stamp.AppearanceStreams.Normal.Default = fxo;
            }
    
            // Remove appearance stream for first annotation of the first page
            var p = doc.Pages[0];
            var an = p.Annotations[0];
            an.RemoveAppearance();
            doc.Save(stream);
        }
    }
    

    The following code illustrates setting BuildRichTextAppearanceStreams to true for FreeTextAnnotation that generates rich text:

    C#
    Copy Code
    GcPdfDocument.BuildRichTextAppearanceStreams = true;
    var doc = new GcPdfDocument();
    var page = doc.NewPage();
    
    // Another free text annotation, with some rich text inside:
    var freeRichAnnot = new FreeTextAnnotation()
    
    {
        Rect = new RectangleF(10, 50, 288, 72),
        LineWidth = 1,
        Color = Color.LightSalmon,
        RichText =
        "<body><p>This is another <i>free text annotation</i>, with <b><i>Rich Text</i></b> content.</p>" +
        "<p><br />Even though a <b>free text</b> annotation displays text directly on a page, " +
        "as other annotations it can be placed outside the page's bounds.</p></body>"
    };
    page.Annotations.Add(freeRichAnnot);
    // Done:
    doc.Save("Annotations.pdf");