Rank: Advanced Member
Groups: Registered
Joined: 4/30/2019(UTC) Posts: 48   Location: Raisio Thanks: 11 times Was thanked: 3 time(s) in 2 post(s)
|
Hi,
Trying to figure out how to add a link (http URI) to an existing PDF.
I can add texts and paths, but links are somehow mysterious.
This is what I've got:
var pdfLinkAnnotation = new PdfLinkAnnotation(pdfPage); pdfLinkAnnotation.Rectangle = boundingBox; pdfLinkAnnotation.Contents = text; pdfPage.Annots.Add(pdfLinkAnnotation);
And I see a link added to PDF (the cursor turns to finger over that box), but I cannot specify URI, cannot specify how it should look (background, border, etc.).
Can anyone help?
Thanks!
|
|
|
|
|
|
Rank: Administration
Groups: Administrators
Joined: 1/5/2016(UTC) Posts: 1,138
Thanks: 10 times Was thanked: 133 time(s) in 130 post(s)
|
To set the URI for the annotation, you must create an Action dictionary and fill it in accordance with the documentation. For a simple link to a web page, you can use the code below. Code:
var linkAnnot = new PdfLinkAnnotation(annots.Page);
linkAnnot.Rectangle = new FS_RECTF(10, 790, 160, 760);
linkAnnot.Dictionary["A"] = PdfTypeDictionary.Create();
linkAnnot.Dictionary["A"].As<PdfTypeDictionary>()["S"] = PdfTypeName.Create("URI");
linkAnnot.Dictionary["A"].As<PdfTypeDictionary>()["URI"] = PdfTypeString.Create("https://patagames.com");
annots.Add(linkAnnot);
Since this annotation does not have an appearance stream, it will be invisible and can be used to make link under existing content on the page. Instead, you can create an annotation that will have an appearance stream and will be visible on the screen. Please see the code below. Code:
PdfCommon.Initialize();
var doc = PdfDocument.CreateNew(new PdfForms());
doc.Pages.InsertPageAt(0, 800, 800);
doc.Pages[0].CreateAnnotations();
var annots = doc.Pages[0].Annots;
var linkAnnot = new PdfLinkAnnotation(annots.Page);
//specify URI
linkAnnot.Dictionary["A"] = PdfTypeDictionary.Create();
linkAnnot.Dictionary["A"].As<PdfTypeDictionary>()["S"] = PdfTypeName.Create("URI");
linkAnnot.Dictionary["A"].As<PdfTypeDictionary>()["URI"] = PdfTypeString.Create("https://patagames.com");
//Link Text, border and BG
var textObj = PdfTextObject.Create("link text", 10, 750, PdfFont.CreateStock(linkAnnot.Page.Document, FontStockNames.Arial), 12);
var pathObj = PdfPathObject.Create(FillModes.Winding, true);
pathObj.Path.AppendRect(new FS_RECTF(textObj.BoundingBox.left - 5, textObj.BoundingBox.top + 5, textObj.BoundingBox.right + 5, textObj.BoundingBox.bottom - 5));
pathObj.StrokeColor = FS_COLOR.Red;
pathObj.FillColor = FS_COLOR.Yellow;
pathObj.CalcBoundingBox();
linkAnnot.CreateEmptyAppearance(AppearanceStreamModes.Normal);
linkAnnot.NormalAppearance.Add(pathObj);
linkAnnot.NormalAppearance.Add(textObj);
linkAnnot.GenerateAppearance(AppearanceStreamModes.Normal);
doc.Pages[0].Dispose();
annots.Add(linkAnnot);
pdfViewer1.Document = doc;
|
 1 user thanked Paul Rayman for this useful post.
|
|
|
|
Rank: Advanced Member
Groups: Registered
Joined: 4/30/2019(UTC) Posts: 48   Location: Raisio Thanks: 11 times Was thanked: 3 time(s) in 2 post(s)
|
Hi Paul, and thank you for your code - it worked! :) But... Originally Posted by: Paul Rayman  Since this annotation does not have an appearance stream, it will be invisible and can be used to make link under existing content on the page.
I see something else... When I add a link with the following code, the link is created but has a black rectangle around it: Code:var pdfTypeDictionary = PdfTypeDictionary.Create();
pdfTypeDictionary["S"] = PdfTypeName.Create("URI");
pdfTypeDictionary["URI"] = PdfTypeString.Create("https://google.com?" + text);
var pdfLinkAnnotation = new PdfLinkAnnotation(pdfPage) {
Rectangle = boundingBox
};
pdfLinkAnnotation.Dictionary["A"] = pdfTypeDictionary;
pdfPage.Annots.Add(pdfLinkAnnotation);
I would survive with a completely "faceless" link, or I need some way to customize its appearance. Any ideas? I found NormalAppearance and its siblings on pdfLinkAnnotation, but, again, no idea how to use those, as the code below didn't work - the black border is gone, but so is the link (the cursor is not turning to pointer anymore over the link text): Code:pdfLinkAnnotation.CreateEmptyAppearance(AppearanceStreamModes.Normal);
pdfLinkAnnotation.GenerateAppearance(AppearanceStreamModes.Normal);
UPDATE I solved the problem by adding the box that I am generating to highlight the underlying text to the pdfLinkAnnotation.NormalAppearance collection, instead of adding it to the page itself. But the question remains - is there a way to create a link without any UI that occupies a certain rectangle? One more question: is there any decent documentation (guide) for the library? The API reference is probably good as a reference, once you know what to look for, but it is very difficult to write something like you wrote starting with it. Thanks! Edited by user Wednesday, May 1, 2019 11:16:25 PM(UTC)
| Reason: Not specified
|
|
|
|
|
|
Rank: Administration
Groups: Administrators
Joined: 1/5/2016(UTC) Posts: 1,138
Thanks: 10 times Was thanked: 133 time(s) in 130 post(s)
|
try the following Code:var linkAnnot = new PdfLinkAnnotation(annots.Page);
//specify URI
linkAnnot.Dictionary["A"] = PdfTypeDictionary.Create();
linkAnnot.Dictionary["A"].As<PdfTypeDictionary>()["S"] = PdfTypeName.Create("URI");
linkAnnot.Dictionary["A"].As<PdfTypeDictionary>()["URI"] = PdfTypeString.Create("https://patagames.com");
//Disable highlighting.
linkAnnot.Dictionary["H"] = PdfTypeName.Create("N");
//Disable border
linkAnnot.Dictionary["Border"] = PdfTypeArray.Create();
linkAnnot.Dictionary["Border"].As<PdfTypeArray>().AddInteger(0);
linkAnnot.Dictionary["Border"].As<PdfTypeArray>().AddInteger(0);
linkAnnot.Dictionary["Border"].As<PdfTypeArray>().AddInteger(0);
The general annotation dictionary is described on page 606, and the annotation-reference dictionary on page 622 of the PDF specification https://www.adobe.com/co...ve/pdf_reference_1-7.pdfAs for generating the appearance stream. When the stream is absent, many viewers display annotations incorrectly. Even Adobe Reader does not fully comply with the specifications on this subject. Therefore, the use of the appearance stream is preferred. When you generate an empty appearance stream, the annotation rectangle is recalculated to zero width and height. You must explicitly point it to the area you need (as well as the BBox entry of annotation dictionary) Or you can just create invisible path like shown below Code:
//invisible path
var pathObj = PdfPathObject.Create(FillModes.None, false);
pathObj.Path.AppendRect(new FS_RECTF(10, 790, 150, 750));
pathObj.CalcBoundingBox();
Edited by user Thursday, May 2, 2019 7:28:17 PM(UTC)
| Reason: Not specified
|
 1 user thanked Paul Rayman for this useful post.
|
|
|
|
Rank: Advanced Member
Groups: Registered
Joined: 4/30/2019(UTC) Posts: 48   Location: Raisio Thanks: 11 times Was thanked: 3 time(s) in 2 post(s)
|
|
|
|
|
|
|
Rank: Newbie
Groups: Registered
Joined: 2/18/2019(UTC) Posts: 3  Location: Minnesota
|
I'm trying to figure out how to link to another page within the same PDF. I can't find any examples. I'm thinking it should be something like this: Code:
var linkAnnot2 = new PdfLinkAnnotation(theDoc.Pages[0]);
linkAnnot2.Rectangle = new Patagames.Pdf.FS_RECTF(100, 100, 100, 100);
linkAnnot2.Dictionary["A"] = PdfTypeDictionary.Create();
linkAnnot2.Dictionary["A"].As<PdfTypeDictionary>()["S"] = PdfTypeName.Create("GoTo");
var test = new PdfDestination(theDoc);
test.PageIndex = 1;
test.DestinationType = Patagames.Pdf.Enums.DestinationTypes.Fit;
linkAnnot2.Dictionary["A"].As<PdfTypeDictionary>()["D"] = test;
The last line obviously doesn't work, as you can't put a PdfDestination into a PdfBaseType field. Any suggestions?
|
|
|
|
|
|
Rank: Administration
Groups: Administrators
Joined: 1/5/2016(UTC) Posts: 1,138
Thanks: 10 times Was thanked: 133 time(s) in 130 post(s)
|
You mau use destinations class instead of low-level dictionaries. Something like this Code: ////////////////////////// PdfLinkAnnotation ///////////////////
var link = new PdfLinkAnnotation(annots.Page);
link.Rectangle = new FS_RECTF(10, 790, 160, 760);
link.Link.Destination = new PdfDestination(annots.Page.Document);
link.Link.Destination.PageIndex = 2;
link.Link.QuadPoints.Add(new FS_QUADPOINTSF(new FS_RECTF(20, 780, 150, 770)));
annots.Add(link);
|
|
|
|
|
|
Rank: Newbie
Groups: Registered
Joined: 2/18/2019(UTC) Posts: 3  Location: Minnesota
|
Awesome, thanks! Was right in front of me.
|
|
|
|
|
|
Forum Jump
You can post new topics in this forum.
You can reply to topics in this forum.
You can delete your posts in this forum.
You can edit your posts in this forum.
You cannot create polls in this forum.
You can vote in polls in this forum.
Important Information:
The Patagames Software Support Forum uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close