Quantcast
Channel: PDF tips & tricks
Viewing all articles
Browse latest Browse all 125

How to add free text annotation with custom appearance to PDF page

$
0
0

Introduction


PDF specification defines many annotation types suitable for various purposes, just to name a few: Link annotation, Text annotation, Line, Square and Polygon annotations, Watermark annotation, Free Text annotation etc.

Annotations are divided to different subtypes to highlight their primary usage, e.g. Markup annotations are used for literally doc’s text markup, while Widget annotations are used to represent the appearance of fields and to manage user interactions in PDF forms. Some annotations are neither Markup, nor Widgets like Link annotation for example.

In previous article we had shown how to programmatically add annotations of many types to PDF document. In this article we’d like to concentrate on Free Text annotation and demonstrate how to create a custom appearance (“view”) for it. Annotations of this type are often being used for adding text notes to PDF pages, and while the default appearance is a good way to go in many cases, custom appearance can add some unique styling to your generated documents.

The code


///<summary>
/// This program demonstrates how to create custom appearance for FreeText annotation
/// using generated <see cref="FixedContent"/>.
///</summary>
classProgram
{
    staticvoid Main(string[] args)
    {
        using (Stream inputStream = File.Open("../../docs/input.pdf",
     FileMode.Open, FileAccess.ReadWrite),
            outputStream = newFileStream("out.pdf", FileMode.Create, FileAccess.ReadWrite))
        {
            // create new document
            using (FixedDocument document = newFixedDocument(inputStream))
            {
                Page page = document.Pages[0];

                // register image resource to be used as background 
                // for custom cloud annotation
                document.ResourceManager.RegisterResource(
                    newApitron.PDF.Kit.FixedLayout.Resources.XObjects.Image(
      "cloud", "../../images/cloud.png", true));

                // add two identical annotations to demonstrate normal 
                // and rollover appearance
                page.Annotations.Add(
                    CreateRectangularFreeTextAnnotation(
                        "Free text annotation created using Apitron PDF Kit"
                         50, 550, 200, 40));

                page.Annotations.Add(
                    CreateRectangularFreeTextAnnotation(
                        "Free text annotation created using Apitron PDF Kit"
                        50, 490, 200, 40));

                // add image based annotation looking like a cloud
                page.Annotations.Add(
      CreateCloudFreeTextAnnotation("Hmm...I'm also a FreeText annotation...",
                    350, 550, 200, 200));

                // save changed copy of the document
                document.Save(outputStream);                  
            }
        }

        Process.Start("out.pdf");
    }


You can see that we add three annotations here – two identical rectangular annotations to demonstrate the difference between normal and rollover states, and one “cloud”-shaped annotation based on an image. The rest of the code can be seen below and the complete code sample can be found in our githubrepository.


    privatestaticAnnotationCreateRectangularFreeTextAnnotation(string text, 
        double x, double y,
 double width, double height)
    {                     
        // create PDF annotation object
        FreeTextAnnotation annotation =
            newFreeTextAnnotation(
                newBoundary(x, y, x + width, y + height),
                AnnotationFlags.ReadOnly);

        annotation.Title = "Apitron";
        annotation.Intent = IntentStyle.FreeText;

        // set custom appearance for normal and rollover states.
        // if you remove the read-only flag from the annotation,
        // Adobe reader will change this appearance to new when clicked.
        // If custom appearance is set, it's used instead of default.           
        annotation.Appearance.Normal = CreateNormalAppearance(text, width, height);
        annotation.Appearance.Rollover = CreateRolloverAppearance(text, width, height);

       
 // set properties affecting default appearance to be used as fallback
        annotation.FontSize = 12;
        annotation.BorderEffect = newAnnotationBorderEffect(
AnnotationBorderEffectStyle.NoEffect, 0);
        annotation.Contents = string.Format("{0} - default",text);
        // text and border color
        annotation.TextColor = RgbColors.Red.Components;
        // set  background here if needed
        annotation.Color = RgbColors.Green.Components;                            

        return annotation;           
    }      
                     
    ///<summary>
    /// Creates a fixed content object that contains
    /// drawing instructions for normal annotation state.       
    ///</summary>       
    privatestaticFixedContent CreateNormalAppearance(string text, double width, 
        double height)
    {
        // create fixed content object, set its unique ID using guid.
        // this object will be implicitly added to page resources using this ID.
        FixedContent fixedContent = newFixedContent(Guid.NewGuid().ToString("N"),
newBoundary(0, 0, width, height));

        // use text block from flow layout API subset,
        // to quickly draw text in a fixed content container.
        TextBlock textBlock = newTextBlock(string.Format("{0} - normal", text));
        textBlock.Border = Border.Solid;
        textBlock.BorderColor = RgbColors.Blue;
        textBlock.Display = Display.Block;
        textBlock.Color = RgbColors.White;
        textBlock.Width = width;
        textBlock.Height = height;
        textBlock.Background = RgbColors.Green;

        fixedContent.Content.AppendContentElement(textBlock, width, height);
        return fixedContent;
    }

    ///<summary>
    /// Creates a fixed content object that contains
    /// drawing instructions for rollover annotation state.       
    ///</summary>          
    privatestaticFixedContent CreateRolloverAppearance(string text, 
        double width, double height)
    {
        // create fixed content object, set its unique ID using guid.
        // this object will be implicitly added to page resources using this ID.
        FixedContent fixedContent = newFixedContent(Guid.NewGuid().ToString("N"),
newBoundary(0, 0, width, height));

        // use text block from flow layout API subset,
        // to quickly draw text in a fixed content container.
        TextBlock textBlock = newTextBlock(string.Format("{0} - rollover", text));
        textBlock.Border = Border.Solid;
        textBlock.BorderColor = RgbColors.Blue;
        textBlock.Display = Display.Block;
        textBlock.Color = RgbColors.Green;
        textBlock.Width = width;
        textBlock.Height = height;
        textBlock.Background = RgbColors.Yellow;

        fixedContent.Content.AppendContentElement(textBlock, width, height);
        return fixedContent;
    }  

    ///<summary>
    /// Creates a fixed content object that contains
    /// drawing instructions cloud-shaped annotation based on image.   
    ///</summary>
    privatestaticAnnotation CreateCloudFreeTextAnnotation(string text, double x, double y,
double width, double height)
    {
        FreeTextAnnotation annotation = newFreeTextAnnotation(
newBoundary(x, y, x + width, y + height),
                AnnotationFlags.ReadOnly);

        annotation.Title = "Apitron";
        annotation.Intent = IntentStyle.FreeText;

        // set custom normal appearance,
        // if you change the annotation to be editable,
        // then Adobe reader will change this appearance to new when clicked              
        annotation.Appearance.Normal = CreateNormalCloudAppearance(text, width, height);
        return annotation;
    }

    ///<summary>
    /// Creates a fixed content object that contains
    /// drawing instructions for normal annotation state.
    ///</summary>       
    privatestaticFixedContent CreateNormalCloudAppearance(string text,double width,
        double height)
    {
        // create fixed content object, set its unique ID using guid.
        // this object will be implicitly added to page resources using this ID.
        FixedContent fixedContent = newFixedContent(Guid.NewGuid().ToString("N"),
newBoundary(0, 0, width, height));

        // append image using its resource id defined in program entry fn.
        fixedContent.Content.AppendImage("cloud", 0, 0, width, height);
        TextBlock textBlock = newTextBlock(text);
        textBlock.Color = RgbColors.Black;

        fixedContent.Content.Translate(40, -65);
        fixedContent.Content.AppendContentElement(textBlock, width, height);
        return fixedContent;
    }
}


Resulting document looks as follows:

Pic. 1 PDF document with Free Text annotations added using Apitron PDF Kit

Pic. 1 PDF document with Free Text annotations added using Apitron PDF Kit

Summary


If you need a powerful tool for working with PDF documents – Apitron PDF Kit for .NET library is a perfect choice. It contains only managed code, so it works with any CLR implementation including MONO and can be used to create XAMARIN apps as well (e.g. you can target iOS and Android easily).

The cross-platform nature of the product allows you to create apps for Windows, Windows Store and Windows Phone (including Windows 10), Silverlight, ASP.NET, Azure-hosted web and worker roles, and also any system where .NET apps can run.

Viewing all articles
Browse latest Browse all 125

Trending Articles