123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442 |
- //
- // KMPrintPresenter_C.swift
- // PDF Reader Pro
- //
- // Created by lizhe on 2022/12/21.
- //
- //
- import Cocoa
- class KMPrintPresenter_C: NSObject {
- lazy var printData: KMPrintModel! = KMPrintModel()
- var document: CPDFDocument?
- fileprivate weak var delegate: KMPrintPresenter_CDeleage?
- /**
- 初始化presenter
- */
- func initPresenter(delegate: KMPrintPresenter_CDeleage, data: KMPrintModel, document: CPDFDocument) {
- self.delegate = delegate
- self.printData = data
- self.updatePrintDocument(documentURL: document.documentURL, data: self.printData)
- }
- func reloadData() {
- self.updatePrintDocument(documentURL: self.document!.documentURL, data: self.printData)
- }
- /**
- @abstract 解除绑定
- */
- func free() {
- delegate = nil
- }
- }
- protocol KMPrintPresenter_CDeleage: NSObject {
- func showData(presenter: KMPrintPresenter_C, document: CPDFDocument)
- }
- protocol KMPrintPresenter_CDocument: NSObject {}
- extension KMPrintPresenter_C: KMPrintPresenter_CDocument {
- /**
- @abstract 获取打印document
- @param url 源文件url
- @param data 数据
- @retrun document
- */
- func updatePrintDocument(documentURL: URL, data: KMPrintModel) -> CPDFDocument {
- /**
- 获取基本参数
- */
- let printModel: KMPrintModel = data
- /**
- 绘制document
- */
- //创建预览document
- let previewDocument = self.creatDocument(url: documentURL)
- //获取总page
- let pages = self.fetchPages(documentURL: documentURL, range: printModel.page.range)
- //插入page
- let insertSuccess = self.insertPages(document: previewDocument, printModel: printModel, pages: pages)
- if insertSuccess {
- KMPrint("插入成功")
- } else {
- KMPrint("插入失败")
- }
- //重置document
- let filePath = self.saveDocument(document: previewDocument)
- if self.delegate != nil {
- self.delegate?.showData(presenter: self, document: previewDocument)
- }
- KMPrint("保存地址" + filePath)
- return previewDocument
- }
- /**
- @abstract 插入page
- @param paperSet 纸张设置
- @param pageSet page设置
- @param pages page数组
- */
- func insertPages(document: CPDFDocument,
- printModel: KMPrintModel,
- pages: [CPDFPage]) -> Bool {
- //每张纸包含的apge数量
- var pageOfPaperCount: Int = 1
- switch printModel.page.operation.type {
- case .multipage:
- pageOfPaperCount = Int(printModel.page.operation.pageOfPaper.point.x * printModel.page.operation.pageOfPaper.point.y)
- case .poster:
- pageOfPaperCount = Int(printModel.page.operation.pageOfPaper.point.x * printModel.page.operation.pageOfPaper.point.y)
- default:
- pageOfPaperCount = 1
- }
- //总页数
- let count: Int = Int(ceil(Double(pages.count / pageOfPaperCount)))
- let size = printModel.page.operation.size
- var insertPages: [CPDFPage] = []
- for i in 0...count {
- //获取多页page
- var drawPages: [CPDFPage] = []
- for j in 0...pageOfPaperCount {
- if i * pageOfPaperCount + j < pages.count {
- let drawPage = pages[i * pageOfPaperCount + j]
- drawPages.append(drawPage)
- }
- }
- //TODO: 暂时屏蔽
- let insertPage = KMPrintPage_C.init()
- insertPage.pages = drawPages
- insertPage.data = printModel
- insertPage.setBounds(CGRect(x: 0, y: 0, width: printModel.paper.info.size.width, height: printModel.paper.info.size.height), for: CPDFDisplayBox.mediaBox)
- insertPage.drawBlock = { [unowned self] box, context, pages, data in
- //绘制page
- self.drawPageToContext(context: context, pages: pages, data: data)
- }
- insertPages.append(insertPage)
- }
- var result = true
- if insertPages.count != 0 {
- for index in 0...insertPages.count - 1 {
- let page = insertPages[index]
- var success = false
- if (printModel.page.range.reversePrintOrder) {
- success = document.insertPageObject(page, at: 0)
- } else {
- success = document.insertPageObject(page, at: UInt(index))
- }
- if success {
- KMPrint("插入成功")
- } else {
- KMPrint("插入失败")
- result = false
- }
- }
- }
- // var result = true
- // if pages.count != 0 {
- // for index in 0...pages.count - 1 {
- // let page = pages[index]
- // let success = document.insertPageObject(page, at: UInt(index))
- // if success {
- // print("插入成功")
- // } else {
- // print("插入失败")
- // result = false
- // }
- // }
- // }
- return result
- }
- func creatDocument(url: URL) -> CPDFDocument {
- if FileManager.default.fileExists(atPath: NSTemporaryDirectory() + "/PDFReaderProTest") {
- try?FileManager.default.createDirectory(atPath: NSTemporaryDirectory() + "/PDFReaderProTest", withIntermediateDirectories: true)
- }
- let document = CPDFDocument(url: url)!
- // document.importPages(IndexSet(integer: 0), from: document, at: 0)
- let count = document.pageCount
- for _ in 0...count {
- document.removePage(at: 0)
- }
- return document
- }
- func saveDocument(document: CPDFDocument) -> String {
- let filePath = NSTemporaryDirectory() + "/PDFReaderProTest/test2.pdf"
- if FileManager.default.fileExists(atPath: filePath) {
- try?FileManager.default.removeItem(atPath: filePath)
- }
- let url: URL = NSURL(string: filePath)! as URL
- var success = document.write(to: url)
- if !success {
- success = NSData(data: document.dataRepresentation()).write(to: url, atomically: true)
- }
- if success {
- KMPrint("保存成功" + filePath)
- } else {
- KMPrint("保存失败")
- }
- return filePath
- }
- /**
- 获取pages
- @param type 页面类型
- @param selectPages 当type 为custom时 传入选中page的下标
- */
- func fetchPages(documentURL: URL, range: KMPrintPageRange) -> [CPDFPage] {
- let document = CPDFDocument.init(url: documentURL)!
- if document.pageCount < 1 {
- let page: CPDFPage = document.page(at: 0)
- return [page]
- } else {
- var pagesArray: [CPDFPage] = []
- switch range.type {
- case .allPage:
- for index in 0...document.pageCount - 1 {
- let page: CPDFPage = document.page(at: index)!
- pagesArray.append(page)
- }
- case .evenPage:
- for index in 0...document.pageCount - 1 {
- if index % 2 == 0 {
- let page: CPDFPage = document.page(at: index)!
- pagesArray.append(page)
- }
- }
- case .oddPage:
- for index in 0...document.pageCount - 1 {
- if index % 2 != 0 {
- let page: CPDFPage = document.page(at: index)!
- pagesArray.append(page)
- }
- }
- // case .currentPage:
- // let page = self.pdfView.currentPage()
- // if page != nil {
- // pagesArray.append(page!)
- // } else {
- // print("page不存在")
- // }
- case .custom:
- for index in range.selectPages {
- let page: CPDFPage = document.page(at: UInt(index - 1))
- pagesArray.append(page)
- }
- default:
- KMPrint("无匹配选项")
- }
- return pagesArray
- }
- }
- /**
- @abstract 获取context
- @param size纸张大小
- */
- func createContext(size: CGSize) -> CGContext {
- let s = CGSize(width: nearbyint(size.width), height: nearbyint(size.height))
- let rep = NSBitmapImageRep.init(bitmapDataPlanes: nil,
- pixelsWide: Int(s.width),
- pixelsHigh: Int(s.height),
- bitsPerSample: 8,
- samplesPerPixel: 4,
- hasAlpha: true,
- isPlanar: false,
- colorSpaceName: NSColorSpaceName.calibratedRGB,
- bytesPerRow: 0,
- bitsPerPixel: 0)!
- let context: CGContext = NSGraphicsContext.init(bitmapImageRep: rep)!.cgContext
- return context
- }
- /**
- @abstract 绘制page
- @param context
- @pages page数组 [CPDFPage]
- */
- func drawPageToContext(context: CGContext, pages: [CPDFPage], data: KMPrintModel) {
- /**
- paper
- */
- let paperDirection: KMPrintPaperDirectionType = .vertical //打印方向
- let paperSize: CGSize = CGSize(width: 595, height: 842) //页面paper大小
- var dealPaperSize: CGSize = paperSize //页面paper大小
- let paperInset: NSEdgeInsets = NSEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) //绘制paper大小
- var columnCount: Int = 2 //行
- var rowCount: Int = 2 //列
- let columnSpace: CGFloat = 2.0 //行间距
- let rowSpace: CGFloat = 2.0 //列间距
- let border: Bool = true
- /**
- page
- */
- let pageOrder: KMPrintPageOperation.Multipage.Order = .horizontal //页面顺序
- var pageSize: CGSize = CGSize(width: 100, height: 100) //page大小
- let contentType: KMPrintContentType = .document
- var scale: Float = 1.0 //缩放尺寸
- let autoRotate: Bool = false
- /**
- 计算
- */
- if paperDirection == .horizontal {
- dealPaperSize = CGSize(width: dealPaperSize.height, height: dealPaperSize.width)
- }
- //减去inset
- dealPaperSize = CGSize(width: dealPaperSize.width - paperInset.left - paperInset.right,
- height: dealPaperSize.height - paperInset.bottom - paperInset.top)
- //计算page尺寸(减去page之间的间隙)
- pageSize = CGSize(width: (dealPaperSize.width - CGFloat((columnCount - 1)) * CGFloat(columnSpace)) / CGFloat(columnCount),
- height: (dealPaperSize.height - CGFloat((rowCount - 1)) * CGFloat(rowSpace)) / CGFloat(rowCount))
- //如果是横向参数需切换
- if pageOrder == .horizontal ||
- pageOrder == .horizontalReverseSequence {
- let temp = columnCount
- columnCount = rowCount
- rowCount = temp
- }
- for i in 0...columnCount {
- for j in 0...rowCount {
- let index = j + i * columnCount
- if index < pages.count {
- //参数
- let page = pages[index]
- let rect = page.bounds(for: CPDFDisplayBox.cropBox)
- let originSize = rect.size
- var dealSize = originSize
- var rotate = page.rotation
- var annoations: [CPDFAnnotation] = page.annotations
- //处理
- switch contentType {
- case .document:
- annoations.removeAll()
- case .documentAndStamp:
- for annoation in annoations {
- if !(annoation.isKind(of: CPDFStampAnnotation.self)) {
- annoation.page.removeAnnotation(annoation)
- }
- }
- case .documentAndMarkup:
- for annoation in annoations {
- if !(annoation.isKind(of: CPDFMarkupAnnotation.self)) {
- annoation.page.removeAnnotation(annoation)
- }
- }
- default: break
- }
- if rotate == 90 ||
- rotate == 270 {
- dealSize = CGSize(width: originSize.height, height: originSize.width)
- }
- //取出page横竖时能显示的最大Rect
- if autoRotate {
- //page旋转度数为0度或者180度时,在指定的大小内,能显示的比例
- let scale1 = Float(min(pageSize.width / originSize.width, pageSize.height / originSize.height))
- //page旋转度数为90度或者270度时,在指定的大小内,能显示的比例
- let scale2 = Float(min(pageSize.width / originSize.height, pageSize.height / originSize.width))
- scale = max(scale1, scale2)
- if scale1 > scale2 {
- //高为竖直排列时,显示最大,则需将page时90度或者270度需要进行旋转
- if rotate == 90 ||
- rotate == 270 {
- rotate = rotate - 90
- }
- } else {
- //宽为竖直排列时,显示最大,则需将page时0度或者180度需要进行旋转
- if rotate == 0 ||
- rotate == 180 {
- rotate = rotate - 90
- }
- }
- if rotate == 90 ||
- rotate == 270 {
- dealSize = CGSize(width: originSize.height, height: originSize.width)
- } else {
- dealSize = CGSize(width: originSize.width, height: originSize.height)
- }
- } else {
- scale = Float(min(pageSize.width / dealSize.width, pageSize.height / dealSize.height))
- }
- scale = min(scale, 1)
- //居中
- let spaceX: CGFloat = (pageSize.width - dealSize.width * CGFloat(scale)) / 2
- let spaceY: CGFloat = (pageSize.height - dealSize.height * CGFloat(scale))/2
- var translateX: CGFloat = 0.0
- var translateY: CGFloat = 0.0
- switch pageOrder {
- case .horizontal:
- translateX = (pageSize.width + columnSpace) + CGFloat(j) + paperInset.left + spaceX
- //页面内容高度 + 下边的行间距 - 第几个cell的高度 +居中
- translateY = dealPaperSize.height + paperInset.bottom - (pageSize.height + rowSpace) * (CGFloat(i) + 1) + spaceY + rowSpace
- case .horizontalReverseSequence:
- translateX = dealPaperSize.width + paperInset.left - (pageSize.width + columnSpace) * (CGFloat(j) + 1) + spaceX + columnSpace
- translateY = dealPaperSize.height - (pageSize.height + rowSpace) * (CGFloat(i) + 1) + spaceY + paperInset.bottom + rowSpace
- case .vertical:
- translateX = (pageSize.width + columnSpace) * CGFloat(i) + paperInset.left + spaceX
- translateY = dealPaperSize.height - (pageSize.height + rowSpace) * (CGFloat(j) + 1) + spaceY + paperInset.bottom + rowSpace
- case .verticalReverseSequence:
- translateX = dealPaperSize.width + paperInset.left - (pageSize.width + columnSpace) * (CGFloat(i) + 1) + spaceX + columnSpace
- translateY = dealPaperSize.height - (pageSize.height + rowSpace) * (CGFloat(j) + 1) + spaceY + paperInset.bottom + rowSpace
- }
- context.saveGState()
- //平移
- context.translateBy(x: translateX, y: translateY)
- //缩放
- context.scaleBy(x: CGFloat(scale), y: CGFloat(scale))
- page.draw(with: CPDFDisplayBox.cropBox, to: context)
- page.transform(context, for: CPDFDisplayBox.cropBox)
- if border {
- var dirtyRect = rect
- if rotate == 90 ||
- rotate == 270 {
- dirtyRect = NSMakeRect(dirtyRect.origin.x, dirtyRect.origin.y, dirtyRect.size.height, dirtyRect.size.width)
- }
- context.addRect(dirtyRect)
- context.setStrokeColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)
- context.strokePath()
- }
- context.restoreGState()
- }
- }
- }
- }
- }
- protocol KMPrintPresenter_CProtocol: NSObject {
- }
|