using ComPDFKit.DigitalSign;
using ComPDFKit.Import;
using ComPDFKit.PDFAnnotation;
using ComPDFKit.PDFAnnotation.Form;
using ComPDFKit.PDFDocument;
using ComPDFKit.PDFPage;
using Compdfkit_Tools.Helper;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using Pen = System.Windows.Media.Pen;
using Point = System.Windows.Point;
using Window = System.Windows.Window;
namespace Compdfkit_Tools.PDFControl
{
///
/// CPDFSignControl.xaml 的交互逻辑
///
public partial class FillDigitalSignatureControl : UserControl
{
private readonly string logoPath = "Logo.png";
private string imagePath = string.Empty;
private string Text = string.Empty;
private Dictionary TabDict { get; set; }
private CPDFSignatureConfig tempSignatureConfig = new CPDFSignatureConfig();
private CPDFSignatureCertificate signatureCertificate;
public CPDFDocument Document;
private string signatureName = string.Empty;
private string location = string.Empty;
private string reason = string.Empty;
private string _signaturePath = string.Empty;
public string SignaturePath
{
get => _signaturePath;
set
{
_signaturePath = value;
}
}
private string _password = string.Empty;
public string Password
{
get => _password;
set
{
_password = value;
signatureCertificate = CPDFPKCS12CertHelper.GetCertificateWithPKCS12Path(SignaturePath, Password);
signatureName = DictionaryValueConverter.GetGrantorFromDictionary(signatureCertificate.SubjectDict);
tempSignatureConfig.Text = signatureName;
CreateTempSignature();
}
}
public CPDFSignatureWidget signatureWidget { get; set; }
public event EventHandler AfterFillSignature;
public FillDigitalSignatureControl()
{
InitializeComponent();
TabDict = new Dictionary
{
["Keyboard"] = KeyboardBorder,
["Trackpad"] = TrackpadBorder,
["Image"] = ImageBorder,
["None"] = NoneBorder
};
SetCheckedTab("Keyboard");
}
private void CreateTempSignature()
{
CPDFDocument tempDocument = CPDFDocument.CreateDocument();
tempDocument.InsertPage(0, 200, 200, string.Empty);
CPDFPage page = tempDocument.PageAtIndex(0);
CPDFSignatureWidget signatureWidget = page.CreateWidget(C_WIDGET_TYPE.WIDGET_SIGNATUREFIELDS) as CPDFSignatureWidget;
signatureWidget.SetRect(new CRect(0, 100, 300, 0));
tempSignatureConfig.IsDrawLogo = (bool)LogoChk.IsChecked;
if (tempSignatureConfig.IsDrawLogo)
{
tempSignatureConfig.LogoBitmap = new Bitmap(logoPath);
}
tempSignatureConfig.Content = Text;
signatureWidget.UpdataApWithSignature(tempSignatureConfig);
byte[] signatureBitmapBytes = GetTempSignatureImage(signatureWidget, out int width, out int height);
signatureWidget.ReleaseAnnot();
if (signatureBitmapBytes.Length > 0)
{
PixelFormat fmt = PixelFormats.Bgra32;
BitmapSource bps = BitmapSource.Create(width, height, 96, 96, fmt, null, signatureBitmapBytes, (width * fmt.BitsPerPixel + 7) / 8);
imageControl.Source = bps;
}
else
{
imageControl.Source = null;
}
}
public static byte[] GetTempSignatureImage(CPDFSignatureWidget signatureWidget, out int width, out int height)
{
CRect rect = signatureWidget.GetRect();
var flags = BindingFlags.NonPublic | BindingFlags.Static;
var dpiProperty = typeof(SystemParameters).GetProperty("Dpi", flags);
int dpi = (int)dpiProperty.GetValue(null, null);
width = (int)(rect.width() * dpi / 72D * 2);
height = (int)(rect.height() * dpi / 72D * 2);
byte[] imageData = new byte[width * height * 4];
signatureWidget.RenderAnnot(width, height, imageData, CPDFAppearanceType.Normal);
return imageData;
}
private void TextAlignBtn_Click(object sender, RoutedEventArgs e)
{
ToggleButton checkBtn = sender as ToggleButton;
if (checkBtn == null)
{
return;
}
checkBtn.IsChecked = true;
if (checkBtn != TextAlignLeftBtn)
{
tempSignatureConfig.IsContentAlginLeft = true;
TextAlignLeftBtn.IsChecked = false;
}
if (checkBtn != TextAlignRightBtn)
{
tempSignatureConfig.IsContentAlginLeft = false;
TextAlignRightBtn.IsChecked = false;
}
CreateTempSignature();
}
private void Border_MouseDown(object sender, MouseButtonEventArgs e)
{
Border clickBorder = sender as Border;
if (clickBorder == null || clickBorder.Tag == null)
{
return;
}
SetCheckedTab(clickBorder.Tag.ToString());
ImagePickPanel.Visibility = Visibility.Hidden;
if (clickBorder == NoneBorder)
{
tempSignatureConfig.IsDrawOnlyContent = true;
}
else
{
tempSignatureConfig.IsDrawOnlyContent = false;
if (clickBorder == KeyboardBorder)
{
tempSignatureConfig.Text = signatureName;
tempSignatureConfig.ImageBitmap = null;
}
else
{
tempSignatureConfig.Text = string.Empty;
if (clickBorder == TrackpadBorder)
{
CanvaDrawPopup.Visibility = Visibility.Visible;
}
else if (clickBorder == ImageBorder)
{
ImagePickPanel.Visibility = Visibility.Visible;
if (!string.IsNullOrEmpty(imagePath))
{
tempSignatureConfig.ImageBitmap = new Bitmap(imagePath);
}
}
}
}
SetProperty();
CreateTempSignature();
}
private void SetCheckedTab(string tab)
{
if (TabDict != null && TabDict.ContainsKey(tab))
{
foreach (string key in TabDict.Keys)
{
Border checkBorder = TabDict[key];
if (checkBorder == null)
{
continue;
}
checkBorder.BorderThickness = new Thickness(0);
if (key == tab)
{
checkBorder.BorderThickness = new Thickness(0, 0, 0, 2);
}
}
}
}
private void CanvasPopupClose_Click(object sender, RoutedEventArgs e)
{
CanvaDrawPopup.Visibility = Visibility.Collapsed;
}
private void CanvasClearBtn_Click(object sender, RoutedEventArgs e)
{
DrawInkCanvas.Strokes.Clear();
}
private void CanvasPopupConfirm_Click(object sender, RoutedEventArgs e)
{
tempSignatureConfig.ImageBitmap = GetDrawInk();
CanvaDrawPopup.Visibility = Visibility.Collapsed;
SetProperty();
CreateTempSignature();
}
public Bitmap GetDrawInk()
{
if (DrawInkCanvas != null && DrawInkCanvas.Strokes != null && DrawInkCanvas.Strokes.Count > 0)
{
Rect bound = DrawInkCanvas.Strokes.GetBounds();
DrawingVisual drawVisual = new DrawingVisual();
DrawingContext drawContext = drawVisual.RenderOpen();
foreach (Stroke drawStroke in DrawInkCanvas.Strokes)
{
Pen drawPen = new Pen(new SolidColorBrush(drawStroke.DrawingAttributes.Color), drawStroke.DrawingAttributes.Width);
PathGeometry drawPath = new PathGeometry();
PathFigureCollection Figures = new PathFigureCollection();
PathFigure AddFigure = new PathFigure();
Figures.Add(AddFigure);
drawPath.Figures = Figures;
if (drawStroke.StylusPoints.Count > 1)
{
StylusPoint startPoint = drawStroke.StylusPoints[0];
AddFigure.StartPoint = new Point(startPoint.X - bound.X, startPoint.Y - bound.Y);
for (int i = 1; i < drawStroke.StylusPoints.Count; i++)
{
StylusPoint drawPoint = drawStroke.StylusPoints[i];
Point offsetPoint = new Point(drawPoint.X - bound.X, drawPoint.Y - bound.Y);
LineSegment drawSegment = new LineSegment();
drawSegment.Point = offsetPoint;
AddFigure.Segments.Add(drawSegment);
}
}
if (AddFigure.Segments.Count > 0)
{
drawContext.DrawGeometry(null, drawPen, drawPath);
}
}
drawContext.Close();
RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)bound.Width, (int)bound.Height, 96, 96, PixelFormats.Pbgra32);
renderBitmap.Render(drawVisual);
BitmapFrame newFrame = BitmapFrame.Create(renderBitmap);
PngBitmapEncoder pngEncoder = new PngBitmapEncoder();
pngEncoder.Frames.Add(newFrame);
using (MemoryStream newStream = new MemoryStream())
{
pngEncoder.Save(newStream);
return new Bitmap(newStream);
}
}
else
{
return null;
}
}
private void SetProperty()
{
Text = string.Empty;
if ((bool)NameChk.IsChecked)
{
if ((bool)TabChk.IsChecked)
{
Text += "Name: ";
}
Text += DictionaryValueConverter.GetGrantorFromDictionary(signatureCertificate.SubjectDict) + "\n";
}
if ((bool)DateChk.IsChecked)
{
if ((bool)TabChk.IsChecked)
{
Text += "Date: ";
}
DateTime currentDateTime = DateTime.Now;
string customFormat = "yyyy.MM.dd HH:mm:ss";
string formattedDateTime = currentDateTime.ToString(customFormat);
Text += formattedDateTime + "\n";
}
if ((bool)LogoChk.IsChecked)
{
tempSignatureConfig.IsDrawLogo = true;
}
else
{
tempSignatureConfig.IsDrawLogo = false;
}
if ((bool)ReasonChk.IsChecked)
{
if ((bool)TabChk.IsChecked)
{
Text += "Reason: ";
}
Text += (ReasonCmb.SelectedItem as ComboBoxItem).Content.ToString() + "\n";
}
if ((bool)DistinguishableNameChk.IsChecked)
{
if ((bool)TabChk.IsChecked)
{
Text += "DN: ";
}
Text += signatureCertificate.Subject + "\n";
}
if ((bool)ComPDFKitVersionChk.IsChecked)
{
Assembly assembly = Assembly.GetExecutingAssembly();
Version version = assembly.GetName().Version;
if ((bool)TabChk.IsChecked)
{
Text += "ComPDFKit Version: ";
}
Text += version.Major.ToString() + "." + version.Minor.ToString() + "." + version.Build.ToString() + "." + version.Revision.ToString() + "\n";
}
if ((bool)PositionChk.IsChecked)
{
if ((bool)TabChk.IsChecked)
{
Text += "Location: ";
}
Text += PositionTbx.Text + "\n";
}
}
private void ReasonCheckBox_Click(object sender, RoutedEventArgs e)
{
CheckBox checkItem = sender as CheckBox;
if (checkItem == null)
{
return;
}
ReasonPanel.Visibility = checkItem.IsChecked == true ? Visibility.Visible : Visibility.Collapsed;
}
private void BrowseTxt_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
string pngPath = CommonHelper.GetExistedPathOrEmpty("PNG files (*.png)|*.png");
if (!string.IsNullOrEmpty(pngPath))
{
imagePath = pngPath;
tempSignatureConfig.ImageBitmap = new Bitmap(imagePath);
SetProperty();
CreateTempSignature();
}
}
private void ClearTxt_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
imagePath = string.Empty;
tempSignatureConfig.ImageBitmap = null;
SetProperty();
CreateTempSignature();
}
private void NameChk_Click(object sender, RoutedEventArgs e)
{
SetProperty();
CreateTempSignature();
}
private void DateChk_Click(object sender, RoutedEventArgs e)
{
SetProperty();
CreateTempSignature();
}
private void LogoChk_Click(object sender, RoutedEventArgs e)
{
SetProperty();
CreateTempSignature();
}
private void ReasonChk_Click(object sender, RoutedEventArgs e)
{
if (!(bool)ReasonChk.IsChecked)
{
Reasonstp.Visibility = Visibility.Collapsed;
}
else
{
Reasonstp.Visibility = Visibility.Visible;
}
SetProperty();
CreateTempSignature();
}
private void DistinguishableNameChk_Click(object sender, RoutedEventArgs e)
{
SetProperty();
CreateTempSignature();
}
private void PositionChk_Click(object sender, RoutedEventArgs e)
{
if (!(bool)PositionChk.IsChecked)
{
PositionStp.Visibility = Visibility.Collapsed;
}
else
{
PositionStp.Visibility = Visibility.Visible;
}
SetProperty();
CreateTempSignature();
}
private void TabChk_Click(object sender, RoutedEventArgs e)
{
SetProperty();
CreateTempSignature();
}
private void ReasonCmb_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SetProperty();
CreateTempSignature();
}
private void ComPDFKitVersionChk_Click(object sender, RoutedEventArgs e)
{
SetProperty();
CreateTempSignature();
}
private void PositionTbx_TextChanged(object sender, TextChangedEventArgs e)
{
if (!(bool)PositionChk.IsChecked)
{
PositionStp.Visibility = Visibility.Collapsed;
}
else
{
PositionStp.Visibility = Visibility.Visible;
}
SetProperty();
CreateTempSignature();
}
private void ContinueBtn_Click(object sender, RoutedEventArgs e)
{
string filePath = CommonHelper.GetGeneratePathOrEmpty("PDF files (*.pdf)|*.pdf", Document.FileName + "_Signed.pdf");
if (string.IsNullOrEmpty(filePath))
{
return;
}
if (filePath.ToLower() == Document.FilePath.ToLower())
{
MessageBox.Show("Do not use the new file name that is the same as the current file name.");
return;
}
if ((bool)ReasonChk.IsChecked)
{
reason = (ReasonCmb?.SelectedItem as ComboBoxItem)?.Content?.ToString();
}
else
{
reason = string.Empty;
}
if ((bool)PositionChk.IsChecked)
{
location = PositionTbx.Text;
}
else
{
location = string.Empty;
}
signatureWidget.UpdataApWithSignature(tempSignatureConfig);
if (Document.WriteSignatureToFilePath(signatureWidget, filePath, SignaturePath, Password, location, reason, CPDFSignaturePermissions.CPDFSignaturePermissionsNone))
{
AfterFillSignature?.Invoke(sender, filePath);
}
CloseWindow(sender);
}
private void CancelBtn_Click(object sender, RoutedEventArgs e)
{
CloseWindow(sender);
}
private void CloseWindow(object sender)
{
Window parentWindow = Window.GetWindow(sender as DependencyObject);
parentWindow?.Close();
}
}
}