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(); } } }