Search code examples
macospdfxamarin.mac

Xamarin.Mac - How to highlight the selected text in a PDF file


I'm actualy trying to add a markup annotation in a PDF with PDFKit, in Xamarin.Mac, so for OS X. So my goal is to highlight permanently, as an annotation, a selected text in the PDF File, and save it to retrieve it when I open the file later.

The thing is, I can get the current selection and store it into a variable :

PdfSelection currentSelection = m_aPdfView.CurrentSelection;

And I can create an object PdfAnnotationMarkup :

//Create the markup annotation
            var annot = new PdfAnnotationMarkup();

            //add characteristics to the annotation
            annot.Contents = currentSelectionText;
            annot.MarkupType = PdfMarkupType.Highlight;
            annot.Color = NSColor.Yellow;
            annot.ShouldDisplay = true;

But I can't find, even though I checked a lot of different documentations, how to link the two of them. There is no method giving the location of the currentSelection, or any hint to go in that direction.

Would anyone know of a way to make this possible ?

PS: I found that the subclasses of PDFAnnotation are deprecated on the Apple Developer Website , but not on the Xamarin Website, is there any way of knowing if both of them are related of entirely different ?

Thanks in advance for your help

EDIT : Here is the code I got and works perfectly. Thanks to svn's answers

            //Get the current selection on the PDF file opened in the PdfView
        PdfSelection currentSelection = m_aPdfView.CurrentSelection;

        //Check if there is an actual selection right now
        if (currentSelection != null)
        {

            currentSelection.GetBoundsForPage(currentSelection.Pages[0]);

            //Create the markup annotation
            var annot = new PdfAnnotationMarkup();

            //add characteristics to the annotation
            annot.Contents = "Test";
            annot.MarkupType = PdfMarkupType.Highlight;
            annot.Color = NSColor.Yellow;
            annot.ShouldDisplay = true;
            annot.ShouldPrint = true;
            annot.UserName = "MyName";




            //getting the current page
            PdfPage currentPage = currentSelection.Pages[0];

            //getting the bounds from the current selection and adding it to the annotation
            var locationRect = currentSelection.GetBoundsForPage(currentPage);
            getValuLabel.StringValue = locationRect.ToString();

            //converting the CGRect object into CGPoints
            CoreGraphics.CGPoint upperLeft = locationRect.Location;
            CoreGraphics.CGPoint lowerLeft = new CoreGraphics.CGPoint(locationRect.X, (locationRect.Y + locationRect.Height));
            CoreGraphics.CGPoint upperRight = new CoreGraphics.CGPoint((locationRect.X + locationRect.Width), locationRect.Y);
            CoreGraphics.CGPoint lowerRight = new CoreGraphics.CGPoint((locationRect.X + locationRect.Width), (locationRect.Y + locationRect.Height));

            //adding the CGPoints to a NSMutableArray
            NSMutableArray pointsArray = new NSMutableArray();
            pointsArray.Add(NSValue.FromCGPoint(lowerLeft));
            pointsArray.Add(NSValue.FromCGPoint(lowerRight));
            pointsArray.Add(NSValue.FromCGPoint(upperLeft));
            pointsArray.Add(NSValue.FromCGPoint(upperRight));

            //setting the quadrilateralPoints
            annot.WeakQuadrilateralPoints = pointsArray;


            //add the annotation to the PDF file current page
            currentPage.AddAnnotation(annot);
            //Tell the PdfView to update the display
            m_aPdfView.NeedsDisplay = true;

Solution

  • A selection can span multiple pages. To get the location of a selection use:

    var locationRect = currentSelection.GetBoundsForPage(currentSelection.Pages[0]);
    

    You should be able to instantiate PdfAnnotationMarkup with bounds but the xamarin implementation does not expose that constuctor. But is does expose a bounds property

    var annot = new PdfAnnotationMarkup();
    annot.bounds = locationRect;
    

    I have not tested this.