// // KMNConvertPDFManager.swift // PDF Reader Pro // // Created by 丁林圭 on 2024/10/23. // import Cocoa class KMNConvertTool: NSObject { static let imageExtensions = ["jpg","cur","bmp","jpeg","gif","png","tiff","tif",/*@"pic",*/"ico","icns","tga","psd","eps","hdr","jp2","jpc","pict","sgi","heic"] static let pdfExtensions = ["pdf"] static let officeExtensions = ["doc", "docx", "xls", "xlsx", "ppt", "pptx"] class func supportImageFileType() -> [String] { return imageExtensions } class func supportPDFFileType() -> [String] { return pdfExtensions } @objc class func isImageType(_ exn: String) -> Bool { return KMNConvertTool.imageExtensions.contains(exn.lowercased()) } @objc class func isPDFType(_ exn: String) -> Bool { return KMNConvertTool.pdfExtensions.contains(exn.lowercased()) } @objc class func isOfficeType(_ exn: String) -> Bool { return KMNConvertTool.officeExtensions.contains(exn.lowercased()) } class func convertOffice(filePath: String, completionBlock:@escaping (String?)->Void) -> Void { let today = Date() let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" let dateString = dateFormatter.string(from: today) let folderPath = "convertToPDF_office_" + dateString + "." + "pdf" let savePath: String? = folderPath.kUrlToPDFFolderPath() as String KMConvertPDFManager.convertFile(filePath, savePath: savePath!) { success, errorDic in if errorDic != nil || !success || !FileManager.default.fileExists(atPath: savePath!) { if FileManager.default.fileExists(atPath: savePath!) { try?FileManager.default.removeItem(atPath: savePath!) } let alert = NSAlert.init() alert.alertStyle = .critical var infoString = "" if errorDic != nil { for key in (errorDic! as Dictionary).keys { infoString = infoString.appendingFormat("%@\n", errorDic![key] as! CVarArg) } } alert.informativeText = NSLocalizedString("Please install Microsoft Office to create PDFs from Office files", comment: "") alert.messageText = NSLocalizedString("Failed to Create PDF", comment: "") alert.addButton(withTitle: NSLocalizedString("OK", comment: "")) alert.runModal() completionBlock(nil) return } if !savePath!.isPDFValid() { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "") alert.runModal() completionBlock(nil) return } completionBlock(savePath) } } class func openDocumentWithImageFromPasteboard(_ pboard: NSPasteboard, error outError: AutoreleasingUnsafeMutablePointer?) -> CPDFDocument? { var document: CPDFDocument? = nil var data: Data? = nil if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.pdf.rawValue]) { data = pboard.data(forType: NSPasteboard.PasteboardType.pdf) } else if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.postScript.rawValue]) { data = pboard.data(forType: NSPasteboard.PasteboardType.postScript) } else if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.tiff.rawValue]) { data = KMNConvertTool.convertTIFFDataToPDF(pboard.data(forType: NSPasteboard.PasteboardType.tiff) ?? Data()) } else { let images = pboard.readObjects(forClasses: [NSImage.self], options: [:]) let strings = pboard.readObjects(forClasses: [NSAttributedString.self], options: [:]) if images?.count ?? 0 > 0 { data = KMNConvertTool.convertTIFFDataToPDF((images![0] as AnyObject).tiffRepresentation!) } else if strings?.count ?? 0 > 0 { data = KMOCTool.convertStringsToPDF(withString: strings ?? [""]) // convertStringsToPDF(strings!) } } if let data = data { document = CPDFDocument(data: data) } else if let outError = outError { outError.pointee = NSError(domain: "SKDocumentErrorDomain", code: 3, userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("Unable to load data from clipboard", comment: "Error description")]) } return document } class func convertTIFFDataToPDF(_ tiffData: Data) -> Data? { guard let imsrc = CGImageSourceCreateWithData(tiffData as CFData, [kCGImageSourceTypeIdentifierHint: kUTTypeTIFF] as CFDictionary), CGImageSourceGetCount(imsrc) > 0, let cgImage = CGImageSourceCreateImageAtIndex(imsrc, 0, nil) else { return nil } let pdfData = NSMutableData(capacity: tiffData.count) let consumer = CGDataConsumer(data: pdfData! as CFMutableData)! var rect = CGRect(x: 0, y: 0, width: CGFloat(cgImage.width), height: CGFloat(cgImage.height)) let ctxt = CGContext(consumer: consumer, mediaBox: &rect, nil) ctxt!.beginPDFPage(nil) ctxt!.draw(cgImage, in: rect) ctxt!.endPDFPage() ctxt!.closePDF() return pdfData as? Data } }