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
6 changes: 6 additions & 0 deletions Signature/Add_ESign/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>

</startup>
</configuration>
9 changes: 9 additions & 0 deletions Signature/Add_ESign/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Application x:Class="PDFViewer_WPF.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PDFViewer_WPF"
StartupUri="MainWindow.xaml">
<Application.Resources>

</Application.Resources>
</Application>
17 changes: 17 additions & 0 deletions Signature/Add_ESign/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;

namespace PDFViewer_WPF
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}
Binary file added Signature/Add_ESign/Data/Ink signature.pdf
Binary file not shown.
Binary file added Signature/Add_ESign/Data/John.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Signature/Add_ESign/Data/PDF.pfx
Binary file not shown.
13 changes: 13 additions & 0 deletions Signature/Add_ESign/MainWindow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Window xmlns:syncfusion="http://schemas.syncfusion.com/wpf" xmlns:PdfViewer="clr-namespace:Syncfusion.Windows.PdfViewer;assembly=Syncfusion.PdfViewer.WPF" x:Class="WPF_Sample_FW.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_Sample_FW"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<PdfViewer:PdfViewerControl Name="PDFViewer" PageClicked="PDFViewer_PageClicked"/>

</Grid>
</Window>
199 changes: 199 additions & 0 deletions Signature/Add_ESign/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
using Syncfusion.Pdf;
using Syncfusion.Pdf.Graphics;
using Syncfusion.Pdf.Security;
using Syncfusion.Windows.PdfViewer;
using System;
using System.Drawing;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Path = System.Windows.Shapes.Path;
using Bitmap = System.Drawing.Bitmap;

namespace WPF_Sample_FW
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
string filePath = "../../../Data/";
bool addSignature = false;
public MainWindow()
{
InitializeComponent();
PDFViewer.Load(filePath + "Ink signature.pdf");
PDFViewer.Loaded += PDFViewer_Loaded;
PDFViewer.ZoomMode = ZoomMode.FitPage;
}

private void PDFViewer_Loaded(object sender, RoutedEventArgs e)
{
// Find the default toolbar from the PDFViewer control template.
DocumentToolbar toolbar = PDFViewer.Template.FindName("PART_Toolbar", PDFViewer) as DocumentToolbar;

// Find the stack panel inside the toolbar where buttons are arranged.
StackPanel stackPanel = (StackPanel)toolbar.Template.FindName("PART_ToolbarStack", toolbar);

// Get the last stack panel in the toolbar stack (usually contains default buttons).
StackPanel stack = stackPanel.Children[stackPanel.Children.Count - 1] as StackPanel;

// Get the first button from the stack to copy its style and icon.
Button button = stack.Children[0] as Button;
Path oldStylePath = button.Content as Path;

Button eSignButton = GetButton(oldStylePath, button);

// Add the new eSign button to the toolbar stack.
stackPanel.Children.Add(eSignButton);
}

private void eSignButton_Click(object sender, RoutedEventArgs e)
{
addSignature = true;
}

private Button GetButton(System.Windows.Shapes.Path oldPath, Button button)
{
// Create a new custom button for eSign functionality.
Button eSignButton = new Button();

// Create a new Path object to use as the icon for the eSign button.
Path path = new Path();
path.Data = System.Windows.Media.Geometry.Parse("M218.17 424.14c-2.95-5.92-8.09-6.52-10.17-6.52s-7.22.59-10.02 6.19l-7.67 15.34c-6.37 12.78-25.03 11.37-29.48-2.09L144 386.59l-10.61 31.88c-5.89 17.66-22.38 29.53-41 29.53H80c-8.84 0-16-7.16-16-16s7.16-16 16-16h12.39c4.83 0 9.11-3.08 10.64-7.66l18.19-54.64c3.3-9.81 12.44-16.41 22.78-16.41s19.48 6.59 22.77 16.41l13.88 41.64c19.75-16.19 54.06-9.7 66 14.16 1.89 3.78 5.49 5.95 9.36 6.26v-82.12l128-127.09V160H248c-13.2 0-24-10.8-24-24V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24v-40l-128-.11c-16.12-.31-30.58-9.28-37.83-23.75zM384 121.9c0-6.3-2.5-12.4-7-16.9L279.1 7c-4.5-4.5-10.6-7-17-7H256v128h128v-6.1zm-96 225.06V416h68.99l161.68-162.78-67.88-67.88L288 346.96zm280.54-179.63l-31.87-31.87c-9.94-9.94-26.07-9.94-36.01 0l-27.25 27.25 67.88 67.88 27.25-27.25c9.95-9.94 9.95-26.07 0-36.01z");

// Copy the fill color from the existing button's icon.
path.Fill = oldPath.Fill;

// Set the icon as the content of the new button.
eSignButton.Content = path;

// Match the icon's size and layout to the original button.
path.Stretch = Stretch.Uniform;
path.Height = oldPath.Height;
path.Width = oldPath.Width;

// Match the button's background and layout properties to the original button.
eSignButton.Height = button.Height;
eSignButton.Width = button.Width;
eSignButton.Margin = button.Margin;
eSignButton.Style = button.Style;
// Attach the click event handler for eSign functionality.
eSignButton.Click += eSignButton_Click;

return eSignButton;
}

private void PDFViewer_PageClicked(object sender, PageClickedEventArgs args)
{
if (addSignature)
{
int pageIndex = PDFViewer.CurrentPageIndex - 1;
CreateSignatureImage();

//Gets the first page of the document
PdfLoadedPage page = PDFViewer.LoadedDocument.Pages[pageIndex] as PdfLoadedPage;

//Retrieve the clicked client area position
System.Windows.Point clientPoint = args.Position;

// Convert client point to page point, which accounts for zoom mode.
System.Windows.Point pagePoint = PDFViewer.ConvertClientPointToPagePoint(clientPoint, pageIndex + 1);
double x = pagePoint.X;
double y = pagePoint.Y;

//Creates a certificate instance from PFX file with private key.
PdfCertificate pdfCert = new PdfCertificate( filePath + "PDF.pfx", "password123");

//Creates a digital signature
PdfSignature Signature = new PdfSignature(PDFViewer.LoadedDocument, page, pdfCert, "Signature");

//Sets an image for signature field
PdfBitmap signatureImage = new PdfBitmap( filePath + "ESign.png");

// Center the signature on the click position using dimensions in points.
float signWidth = signatureImage.PhysicalDimension.Width;
float signHeight = signatureImage.PhysicalDimension.Height;
Signature.Bounds = new System.Drawing.RectangleF((float)(x), (float)(y), signWidth, signHeight);

Signature.ContactInfo = "johndoe@owned.us";
Signature.LocationInfo = "Honolulu, Hawaii";
Signature.Reason = "I am author of this document.";

//Draws the signature image
Signature.Appearance.Normal.Graphics.DrawImage(signatureImage, 0, 0);

//Save the document into stream.
MemoryStream stream = new MemoryStream();
PDFViewer.LoadedDocument.Save(stream);
stream.Position = 0;

//Reloads the document
PDFViewer.Load(stream);
addSignature = false;
}

}

private void CreateSignatureImage()
{
int pageIndex = PDFViewer.CurrentPageIndex - 1;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even split "CreateSignatureImage" method , as text image creation as one and combining two images as another.

if(pageIndex < 0)
return;

//Creating image for current date and time details
CreateCurrentDataImage();

//Combine the name image and date-time image into a single image
CombineSignatureAndDataImage();

}

private void CombineSignatureAndDataImage()
{
// Load the two images
using (System.Drawing.Image nameImage = System.Drawing.Image.FromFile(filePath + "John.png"))
using (System.Drawing.Image signImage = System.Drawing.Image.FromFile(filePath + "DigitalSignatureBlock.png"))
{
// Create a new bitmap with combined width and max height
int signatureWidth = nameImage.Width + signImage.Width;
int signatureHeight = Math.Max(nameImage.Height, signImage.Height);
using (Bitmap combinedImage = new Bitmap(signatureWidth, signatureHeight))
using (Graphics g = System.Drawing.Graphics.FromImage(combinedImage))
{
// Draw both images side by side
g.DrawImage(nameImage, 0, 0);
g.DrawImage(signImage, nameImage.Width, 0);
// Save the result
combinedImage.Save(filePath + "ESign.png", System.Drawing.Imaging.ImageFormat.Png);
}
}
}

private void CreateCurrentDataImage()
{
int width = 200;
int height = 100;
string signerName = "John";
string dateTime = DateTime.Now.ToString("yyyy.MM.dd\nHH:mm:ss zzz");
string text = $"Digitally signed by {signerName}\nDate: {dateTime}\n\n";
string outputPath = filePath + "DigitalSignatureBlock.png";
Directory.CreateDirectory(System.IO.Path.GetDirectoryName(outputPath));
using (Bitmap bitmap = new Bitmap(width, height))
{
using (Graphics graphics = System.Drawing.Graphics.FromImage(bitmap))
{
using (Font font = new Font("Arial", 9))
using (SolidBrush backgroundBrush = new SolidBrush(System.Drawing.Color.White))
{
graphics.FillRectangle(backgroundBrush, 0, 0, width, height);
RectangleF layoutRect = new RectangleF(10, 10, width - 20, height - 20);
graphics.DrawString(text, font, System.Drawing.Brushes.Black, layoutRect);
bitmap.Save(outputPath, System.Drawing.Imaging.ImageFormat.Png);
}
}
}
}
}
}
12 changes: 12 additions & 0 deletions Signature/Add_ESign/PDFViewer_WPF.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>WinExe</OutputType>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Syncfusion.PdfViewer.WPF" Version="*" />
<PackageReference Include="System.Drawing.Common" Version="9.0.8" />
</ItemGroup>
<Import Project="targets\MultiTargeting.targets" />
</Project>
25 changes: 25 additions & 0 deletions Signature/Add_ESign/PDFViewer_WPF.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36401.2
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PDFViewer_WPF", "PDFViewer_WPF.csproj", "{0FAA7523-B034-4EA9-860A-A8936DFFD40E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0FAA7523-B034-4EA9-860A-A8936DFFD40E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0FAA7523-B034-4EA9-860A-A8936DFFD40E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0FAA7523-B034-4EA9-860A-A8936DFFD40E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0FAA7523-B034-4EA9-860A-A8936DFFD40E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BAAD6341-6945-42C7-8438-919E9DB8EB03}
EndGlobalSection
EndGlobal
52 changes: 52 additions & 0 deletions Signature/Add_ESign/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//[assembly: AssemblyTitle("PDFViewer_WPF")]
//[assembly: AssemblyDescription("")]
//[assembly: AssemblyConfiguration("")]
//[assembly: AssemblyCompany("")]
//[assembly: AssemblyProduct("PDFViewer_WPF")]
//[assembly: AssemblyCopyright("Copyright © 2025")]
//[assembly: AssemblyTrademark("")]
//[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

//In order to begin building localizable applications, set
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
//inside a <PropertyGroup>. For example, if you are using US english
//in your source files, set the <UICulture> to en-US. Then uncomment
//the NeutralResourceLanguage attribute below. Update the "en-US" in
//the line below to match the UICulture setting in the project file.

//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]


//[assembly: ThemeInfo(
// ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
// //(used if a resource is not found in the page,
// // or application resource dictionaries)
// ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
// //(used if a resource is not found in the page,
// // app, or any theme specific resource dictionaries)
//)]


// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
//[assembly: AssemblyVersion("1.0.0.0")]
//[assembly: AssemblyFileVersion("1.0.0.0")]
Loading