Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/test-net-framework-samples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:

jobs:
test-samples:
runs-on: windows-2019
runs-on: windows-2022
defaults:
run:
shell: bash
Expand Down Expand Up @@ -93,7 +93,8 @@ jobs:
'Other/StreamIO/',
'Printing/PrintPDF/',
'Printing/PrintPDFGUI/',
'Security/AddDigitalSignature/',
'Security/AddDigitalSignatureCMS/',
'Security/AddDigitalSignatureRFC3161/',
'Security/AddRegexRedaction/',
'Security/Redactions/',
'Text/AddGlyphs/',
Expand Down
162 changes: 109 additions & 53 deletions ContentModification/CreateLayer/CreateLayer.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
using Datalogics.PDFL;
using System;
using System.Collections.Generic;
using System.Text;
using Datalogics.PDFL;

/*
* This sample adds an Optional Content Group (a layer) to a PDF document and
* then adds an image to that layer.
* This sample adds Optional Content Groups (layers) to a PDF document and
* then adds Content to those layers.
*
* The related ChangeLayerConfiguration program makes layers visible or invisible.
*
* You can toggle back and forth to make the layer (the duck image) visible or invisible
* in the PDF file. Open the output PDF document in a PDF Viewer, click View and select
* Show/Hide. Select Navigation Panes and Layers to display the layers in the PDF file.
* Click on the box next to the name of the layer.
* You can toggle back and forth to make a layer visible or invisible
* in a PDF Viewer.
*
*/
namespace CreateLayer
Expand All @@ -38,70 +35,129 @@ static void Main(string[] args)

Console.WriteLine("Input file: " + sInput + ", writing to " + sOutput);

Document doc = new Document(sInput);

Console.WriteLine("Opened a document.");

Page pg = doc.GetPage(0);
Image img = (pg.Content.GetElement(0) as Image);

// Containers, Forms and Annotations can be attached to an
// OptionalContentGroup; other content (like Image) can
// be made optional by placing it inside a Container
Container container = new Container();
container.Content = new Content();
container.Content.AddElement(img);
using (Document doc = new Document(sInput))
{
Console.WriteLine("Opened a document.");

using (Page pg = doc.GetPage(0))
{
Image image = (Image)pg.Content.GetElement(0);
image.Matrix = new Matrix(image.Matrix.A * .5, 0, 0, image.Matrix.D * .5, image.Matrix.H, image.Matrix.V);

Image image2 = new Image(Library.ResourceDirectory + "Sample_Input/Image.png");

Text text = new Text();
Matrix matrix = new Matrix();
Font font = new Font("Helvetica");
GraphicState graphicState = new GraphicState();
TextState textState = new TextState();

matrix.A = 42;
matrix.D = 22;
matrix.H = 72;
matrix.V = 72;

TextRun textRun = new TextRun("sample text", font, graphicState, textState, matrix);
text.AddRun(textRun);

Text text2 = new Text();

matrix.A = 30;
matrix.D = 30;
matrix.H = 72;
matrix.V = 288;

TextRun textRun2 = new TextRun("Text definition provided here", font, graphicState, textState, matrix);
text2.AddRun(textRun2);

// Containers, Forms and Annotations can be attached to an
// OptionalContentGroup; other content (like Image) can
// be made optional by placing it inside a Container
Container imageContainer = new Container();
imageContainer.Content = new Content();
imageContainer.Content.AddElement(image);

Container imageContainer2 = new Container();
imageContainer2.Content = new Content();
imageContainer2.Content.AddElement(image2);

Container textContainer = new Container();
textContainer.Content = new Content();
textContainer.Content.AddElement(text);

Container textContainer2 = new Container();
textContainer2.Content = new Content();
textContainer2.Content.AddElement(text2);

using (Document newDoc = new Document())
{
using (Page newPage = newDoc.CreatePage(Document.BeforeFirstPage, pg.MediaBox))
{
newPage.Content.AddElement(imageContainer);
newPage.Content.AddElement(imageContainer2);
newPage.Content.AddElement(textContainer);
newPage.Content.AddElement(textContainer2);

// We create new OptionalContentGroups and place them in the OptionalContentConfig.Order array
List<OptionalContentGroup> ocgs = CreateNewOptionalContentGroups(newDoc, new List<string> { "Rubber Ducky", "PNG Logo", "Example Text", "Text Definition" });

AssociateOCGWithContainer(newDoc, ocgs[0], imageContainer);
AssociateOCGWithContainer(newDoc, ocgs[1], imageContainer2);
AssociateOCGWithContainer(newDoc, ocgs[2], textContainer);
AssociateOCGWithContainer(newDoc, ocgs[3], textContainer2);

newPage.UpdateContent();

newDoc.Save(SaveFlags.Full, sOutput);
}
}
}
}
}
}

// We replace the Image with the Container
// (which now holds the image)
pg.Content.RemoveElement(0);
pg.UpdateContent();
public static List<OptionalContentGroup> CreateNewOptionalContentGroups(Document doc, List<string> names)
{
List<OptionalContentGroup> ocgs = new List<OptionalContentGroup>();

pg.Content.AddElement(container);
pg.UpdateContent();
OptionalContentGroup ocg = new OptionalContentGroup(doc, names[0]);
OptionalContentGroup ocg2 = new OptionalContentGroup(doc, names[1]);
OptionalContentGroup ocg3 = new OptionalContentGroup(doc, names[2]);
OptionalContentGroup ocg4 = new OptionalContentGroup(doc, names[3]);

// We create a new OptionalContentGroup and place it in the
// OptionalContentConfig.Order array
OptionalContentGroup ocg = CreateNewOptionalContentGroup(doc, "Rubber Ducky");
ocgs.Add(ocg);
ocgs.Add(ocg2);
ocgs.Add(ocg3);
ocgs.Add(ocg4);

// Now we associate the Container with the OptionalContentGroup
// via an OptionalContentMembershipDict. Note that we MUST
// update the Page's content afterwards.
AssociateOCGWithContainer(doc, ocg, container);
pg.UpdateContent();
// Add it to the Order array -- this is required so that it will appear in the 'Layers' panel in a PDF Viewer.
OptionalContentOrderArray order_list = doc.DefaultOptionalContentConfig.Order;

doc.Save(SaveFlags.Full, sOutput);
}
}
OptionalContentOrderArray grouping = new OptionalContentOrderArray(doc, "Image Grouping");
grouping.Add(new OptionalContentOrderLeaf(ocg));
grouping.Add(new OptionalContentOrderLeaf(ocg2));

// Create an OptionalContentGroup with a given name, and add it to the
// default OptionalContentConfig's Order array.
public static OptionalContentGroup CreateNewOptionalContentGroup(Document doc, string name)
{
// Create an OptionalContentGroup
OptionalContentGroup ocg = new OptionalContentGroup(doc, name);
OptionalContentOrderArray grouping2 = new OptionalContentOrderArray(doc, "Text Grouping");
grouping2.Add(new OptionalContentOrderLeaf(ocg3));
grouping2.Add(new OptionalContentOrderLeaf(ocg4));

// Add it to the Order array -- this is required so that the OptionalContentGroup
// will appear in the 'Layers' control panel in a PDF Viewer. It will appear in
// the control panel with the name given in the OptionalContentGroup constructor.
OptionalContentOrderArray order_list = doc.DefaultOptionalContentConfig.Order;
order_list.Insert(order_list.Length, new OptionalContentOrderLeaf(ocg));
order_list.Insert(order_list.Length, grouping);
order_list.Insert(order_list.Length, grouping2);

return ocg;
return ocgs;
}

// Associate a Container with an OptionalContentGroup via an OptionalContentMembershipDict.
// This function associates a Containter with a single OptionalContentGroup and uses
// This function associates a Container with a single OptionalContentGroup and uses
// a VisibilityPolicy of AnyOn.
public static void AssociateOCGWithContainer(Document doc, OptionalContentGroup ocg, Container cont)
{
// Create an OptionalContentMembershipDict. The options here are appropriate for a
// 'typical' usage; other options can be used to create an 'inverting' layer
// (i.e. 'Display this content when the layer is turned OFF'), or to make the
// Container's visibility depend on several OptionalContentGroups
OptionalContentMembershipDict ocmd = new OptionalContentMembershipDict(doc, new OptionalContentGroup[] {ocg}, VisibilityPolicy.AnyOn);
OptionalContentMembershipDict ocmd = new OptionalContentMembershipDict(doc, new OptionalContentGroup[] { ocg }, VisibilityPolicy.AnyOn);

// Associate the Container with the OptionalContentMembershipDict
cont.OptionalContentMembershipDict = ocmd;
}
}
Expand Down
8 changes: 7 additions & 1 deletion Samples.sln
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegexTextSearch", "Text\Reg
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TextExtract", "Text\TextExtract\TextExtract.csproj", "{11C4A647-3DDA-41A5-855C-E14EDF1BFFDE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddDigitalSignature", "Security\AddDigitalSignature\AddDigitalSignature.csproj", "{AB753937-DF3D-4B06-B475-D3B597D32BC5}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddDigitalSignatureCMS", "Security\AddDigitalSignatureCMS\AddDigitalSignatureCMS.csproj", "{AB753937-DF3D-4B06-B475-D3B597D32BC5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddDigitalSignatureRFC3161", "Security\AddDigitalSignatureRFC3161\AddDigitalSignatureRFC3161.csproj", "{74FA984E-AB89-475A-9077-9D612DE12AEC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -548,6 +550,10 @@ Global
{AB753937-DF3D-4B06-B475-D3B597D32BC5}.Debug|x64.Build.0 = Debug|x64
{AB753937-DF3D-4B06-B475-D3B597D32BC5}.Release|x64.ActiveCfg = Release|x64
{AB753937-DF3D-4B06-B475-D3B597D32BC5}.Release|x64.Build.0 = Release|x64
{74FA984E-AB89-475A-9077-9D612DE12AEC}.Debug|x64.ActiveCfg = Debug|x64
{74FA984E-AB89-475A-9077-9D612DE12AEC}.Debug|x64.Build.0 = Debug|x64
{74FA984E-AB89-475A-9077-9D612DE12AEC}.Release|x64.ActiveCfg = Release|x64
{74FA984E-AB89-475A-9077-9D612DE12AEC}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@

/*
*
* This sample program demonstrates the use of AddDigitalSignature.
* This sample program demonstrates the use of AddDigitalSignature for CMS signature type.
*
* Copyright (c) 2025, Datalogics, Inc. All rights reserved.
*
*/
namespace AddDigitalSignature
namespace AddDigitalSignatureCMS
{
class AddDigitalSignature
class AddDigitalSignatureCMS
{
static void Main(string[] args)
{
Console.WriteLine("AddDigitalSignature Sample:");
Console.WriteLine("AddDigitalSignatureCMS Sample:");

using (new Library())
{
Console.WriteLine("Initialized the library.");

String sInput = Library.ResourceDirectory + "Sample_Input/SixPages.pdf";
String sLogo = Library.ResourceDirectory + "Sample_Input/ducky_alpha.tif";
String sOutput = "DigSig-out.pdf";
String sOutput = "DigSigCMS-out.pdf";

String sDERCert = Library.ResourceDirectory + "Sample_Input/Credentials/DER/RSA_certificate.der";
String sDERKey = Library.ResourceDirectory + "Sample_Input/Credentials/DER/RSA_privKey.der";
Expand Down Expand Up @@ -55,6 +55,10 @@ static void Main(string[] args)
sigDoc.SetNonPfxSignerCert(sDERCert, 0, CredentialStorageFmt.OnDisk);
sigDoc.SetNonPfxPrivateKey(sDERKey, 0, CredentialStorageFmt.OnDisk);

// Set the signature type to be used.
// The available types are defined in the SignatureType enum. Default CMS.
sigDoc.DocSignType = SignatureType.CMS;

// Setup the signer information
// (Logo image is optional)
sigDoc.SetSignerInfo(sLogo, 0.5F, "John Doe", "Chicago, IL", "Approval", "Datalogics, Inc.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<Platform Condition=" '$(Platform)' == '' ">x64</Platform>
<ProjectGuid>{AB753937-DF3D-4B06-B475-D3B597D32BC5}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>AddDigitalSignature</RootNamespace>
<AssemblyName>AddDigitalSignature</AssemblyName>
<RootNamespace>AddDigitalSignatureCMS</RootNamespace>
<AssemblyName>AddDigitalSignatureCMS</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
Expand Down Expand Up @@ -45,7 +45,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AddDigitalSignature.cs" />
<Compile Include="AddDigitalSignatureCMS.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.13.35818.85
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddDigitalSignature", "AddDigitalSignature.csproj", "{3790CE63-DB43-4F16-8226-BDFEFA25BCDD}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddDigitalSignatureCMS", "AddDigitalSignatureCMS.csproj", "{3790CE63-DB43-4F16-8226-BDFEFA25BCDD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
64 changes: 64 additions & 0 deletions Security/AddDigitalSignatureRFC3161/AddDigitalSignatureRFC3161.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Text;
using Datalogics.PDFL;

/*
*
* This sample program demonstrates the use of AddDigitalSignature for RFC3161 timestamp signature type.
*
* Copyright (c) 2025, Datalogics, Inc. All rights reserved.
*
*/
namespace AddDigitalSignatureRFC3161
{
class AddDigitalSignatureRFC3161
{
static void Main(string[] args)
{
Console.WriteLine("AddDigitalSignatureRFC3161 Sample:");

using (new Library())
{
Console.WriteLine("Initialized the library.");

String sInput = Library.ResourceDirectory + "Sample_Input/CreateAcroForm2h.pdf";

String sOutput = "DigSigRFC3161-out.pdf";

if (args.Length > 0)
sInput = args[0];

if (args.Length > 1)
sOutput = args[1];

Console.WriteLine("Input file: " + sInput);
Console.WriteLine("Writing to output: " + sOutput);

using (Document doc = new Document(sInput))
{
using (Datalogics.PDFL.SignDoc sigDoc = new Datalogics.PDFL.SignDoc())
{
// Setup Sign params
sigDoc.FieldID = SignatureFieldID.SearchForFirstUnsignedField;

// Set signing attributes
sigDoc.DigestCategory = DigestCategory.Sha256;

// Set the signature type to be used, RFC3161/TimeStamp.
// The available types are defined in the SignatureType enum. Default CMS.
sigDoc.DocSignType = SignatureType.RFC3161;

// Setup Save params
sigDoc.OutputPath = sOutput;

// Finally, sign and save the document
sigDoc.AddDigitalSignature(doc);

Console.WriteLine();
}
}
}
}
}
}
Loading
Loading