// // KMPrintPresenter.swift // PDF Master // // Created by lizhe on 2022/12/21. // import Cocoa import PDFKit //MARK: CPDFKit page 方法无法使用 暂时使用系统方法 class KMPrintPresenter: NSObject { lazy var printData: KMPrintModel! = KMPrintModel() var document: CPDFDocument? fileprivate weak var delegate: KMPrintPresenterDeleage? /** 初始化presenter 绑定数据 */ func initPresenter(delegate: KMPrintPresenterDeleage, data: KMPrintModel, document: CPDFDocument) { self.delegate = delegate self.printData = data self.document = document 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 KMPrintPresenterDeleage: NSObject { func showData(presenter: KMPrintPresenter, document: CPDFDocument) } protocol KMPrintPresenterDocument: NSObject {} extension KMPrintPresenter: KMPrintPresenterDocument { /** @abstract 获取打印document @param url 源文件url @param data 数据 @retrun document */ func updatePrintDocument(documentURL: URL, data: KMPrintModel) -> CPDFDocument { // 获取基本参数 let printModel: KMPrintModel = data //获取总page let pages = self.fetchPages(documentURL, printModel.page) //绘制PDF let filePath = self.drawPages(nil, printModel, pages) let result = CPDFDocument(url: URL(fileURLWithPath: filePath))! if self.delegate != nil { self.delegate?.showData(presenter: self, document: result) } KMPrint("保存地址" + filePath) return result } /** @abstract 插入page @param paperSet 纸张设置 @param pageSet page设置 @param pages page数组 */ func drawPages(_ toFilePath: String?, _ printModel: KMPrintModel, _ pages: [KMPrintDrawPage]) -> String { /** 参数 */ //纸张大小 let paperSize: CGSize = self.fetchPaperSize(printModel.paper) //总页数 let paperCount: Int = self.fetchTotalPaperCount(paperSize, pages, printModel.page) //每页page数 let pageOfPaperCount: Int = self.fetchPageOfPaper(printModel.page) //获取每张纸的page let drawPages: [[KMPrintDrawPage]] = self.fetchDrawPages(paperSize, printModel.page, paperCount, pageOfPaperCount, pages) //导出地址 let filePath = KMPrintPresenter.fetchSaveFilePath(toFilePath) /** 绘制每张纸的内容 */ //创建画布 let context: CGContext = self.createContext(filePath, paperSize) for drawPage in drawPages { context.beginPDFPage(nil) self.drawPageToContext(context, drawPage, printModel) context.endPDFPage() } context.closePDF() return filePath } /** 获取绘制的pages @pageModel page参数 @param paperCount 纸张数量 @param pageOfPaperCount 每张纸的page数量 @param pages 所有page数量 */ func fetchDrawPages(_ paperSize: CGSize, _ pageModel: KMPrintPageModel,_ paperCount: Int, _ pageOfPaperCount: Int, _ pages: [KMPrintDrawPage]) -> [[KMPrintDrawPage]] { guard pages.count != 0 else { return [] } //一个page重复获取次数 var pageRepetitionCount = 1 if (pageModel.operation.type == .poster) { if (pageModel.operation.poster.type == .tile) { pageRepetitionCount = Int(pageModel.operation.poster.tilePoint.x * pageModel.operation.poster.tilePoint.y) } else if (pageModel.operation.poster.type == .breakUp) { pageRepetitionCount = Int(pageModel.operation.poster.pageOfPaper.point.x * pageModel.operation.poster.pageOfPaper.point.y) } } var drawPages:[[KMPrintDrawPage]] = [] for i in 0...(paperCount - 1) { //获取多页page var tempPags: [KMPrintDrawPage] = [] for j in 0...(pageOfPaperCount - 1) { let pageIndex = i / pageRepetitionCount if (pageIndex * pageOfPaperCount + j < pages.count) { let originDrawPage = (pages[pageIndex * pageOfPaperCount + j]) let drawPage = KMPrintDrawPage() drawPage.page = originDrawPage.page var pageCropRect = self.fetchPageCropRect(paperSize,i % pageRepetitionCount, pageModel, drawPage) var pageShowRect = pageCropRect if (pageModel.operation.type == .poster) { if (pageModel.operation.poster.type == .tile) { pageShowRect = self.fetchPageShowRect(paperSize, i % pageRepetitionCount, pageModel, drawPage) } else if (pageModel.operation.poster.type == .breakUp) { pageShowRect = pageCropRect } } drawPage.cropRect = pageCropRect drawPage.showRect = pageShowRect tempPags.append(drawPage) } } drawPages.append(tempPags) } return drawPages } /** 获取pages @param type 页面类型 @param contentType annoation类型 @param selectPages 当type 为custom时 传入选中page的下标 */ static func fetchSaveFilePath(_ filePath: String?) -> String { var saveFilePath = filePath ?? "" if saveFilePath.count == 0 { saveFilePath = NSTemporaryDirectory() + "/PDFMasterTest/test2.pdf" } if !FileManager.default.fileExists(atPath: NSTemporaryDirectory() + "/PDFMasterTest") { try?FileManager.default.createDirectory(atPath: NSTemporaryDirectory() + "/PDFMasterTest", withIntermediateDirectories: true) } if FileManager.default.fileExists(atPath: saveFilePath) { try?FileManager.default.removeItem(atPath: saveFilePath) } return saveFilePath } /** 获取pages @param type 页面类型 @param contentType annoation类型 @param selectPages 当type 为custom时 传入选中page的下标 */ static func creatDocument(_ url: URL) -> CPDFDocument { if FileManager.default.fileExists(atPath: NSTemporaryDirectory() + "/PDFMasterTest") { try?FileManager.default.createDirectory(atPath: NSTemporaryDirectory() + "/PDFMasterTest", withIntermediateDirectories: true) } let document = CPDFDocument(url: url)! // document.importPages(IndexSet(integer: 0), from: document, at: 0) let count = document.pageCount for _ in 0...(count - 1) { document.removePage(at: 0) } return document } /** 获取pages @param type 页面类型 @param contentType annoation类型 @param selectPages 当type 为custom时 传入选中page的下标 */ func fetchPages(_ documentURL: URL, _ pageModel: KMPrintPageModel) -> [KMPrintDrawPage] { let document = PDFDocument.init(url: documentURL)! var pageIndexs: [Int] = [] let range = pageModel.range let contentType = pageModel.contentType let reversePrintOrder = range.reversePrintOrder switch range.type { case .allPage: for index in 0...document.pageCount - 1 { pageIndexs.append(index) } case .evenPage: for index in 0...document.pageCount - 1 { if index % 2 == 0 { pageIndexs.append(index) } } case .oddPage: for index in 0...document.pageCount - 1 { if index % 2 != 0 { pageIndexs.append(index) } } case .currentPage: pageIndexs.append(0) case .custom: pageIndexs.append(0) default: pageIndexs.append(0) } var pagesArray: [KMPrintDrawPage] = [] for index in pageIndexs { let page = document.page(at: index)! let drawPage = KMPrintDrawPage() drawPage.page = page self.dealPageContent(contentType, [drawPage]) if reversePrintOrder { pagesArray.insert(drawPage, at: 0) } else { pagesArray.append(drawPage) } } return pagesArray } /** 处理page annoation 内容 @param contentType annoation类型 @param pages page */ func dealPageContent (_ contentType: KMPrintContentType, _ pages: [KMPrintDrawPage]) -> Void { for page in pages { let annoations: [PDFAnnotation] = page.page.annotations //内容处理 switch contentType { case .document: for annoation in annoations { annoation.page!.removeAnnotation(annoation) } case .documentAndStamp: for annoation in annoations { if !self.isAnnoationStamp(type: annoation.type!) { annoation.page!.removeAnnotation(annoation) } } case .documentAndMarkup: for annoation in annoations { if !self.isAnnoationMarkup(type: annoation.type!) { annoation.page!.removeAnnotation(annoation) } } case .documentAndForm: for annoation in annoations { if !self.isAnnoationForm(type: annoation.type!) { annoation.page!.removeAnnotation(annoation) } } default: KMPrint("未找到") break } } } /** @abstract 获取context @param size纸张大小 */ func createContext(_ saveFilePath: String, _ size: CGSize) -> CGContext { var mediaBox: CGRect = NSMakeRect(0, 0, size.width, size.height) let url = CFURLCreateWithFileSystemPath(nil, saveFilePath as CFString, .cfurlposixPathStyle, false) let content: CGContext = CGContext.init(url!, mediaBox: &mediaBox, nil)! return content } /** @abstract 绘制page @param context @pages page数组 [CPDFPage] */ func drawPageToContext(_ context: CGContext, _ pages: [KMPrintDrawPage], _ data: KMPrintModel, _ drawPageRect: CGRect = NSZeroRect) { //左下角有坐标系原点 /** paper */ let paperSize: CGSize = self.fetchPaperSize(data.paper)//纸张大小 let paperItemSize: CGSize = self.fetchPaperItemSize(data.paper) //页面paper大小(去除边框) let paperInset: NSEdgeInsets = data.paper.info.inset //绘制paper大小 let border: Bool = true //是否存在边框 /** page */ let pageOrder: KMPrintPageOperation.Multipage.Order = .horizontal //页面顺序 let pageSize: CGSize = self.fetchPageItemSize(data.page, paperItemSize) //page大小 let showModel: KMPrintPageOperation.Size = self.fetchShowModel(data.page) let autoRotate = self.fetchAutoRotate(data.page) let autoSize: Bool = self.fetchAutoSize(data.page) //行列 let columnAndRow = self.fetchPageColumnAndRow(data.page) //行 列数量 let columnAndRowSpace = CGPoint(x: 2, y: 2) //行 列之间的空间 for i in 0...Int(columnAndRow.x) - 1 { for j in 0...(Int(columnAndRow.y) - 1) { let index = j + i * Int(columnAndRow.x) if index < pages.count { //参数 let page: KMPrintDrawPage = pages[index] let rect = page.showRect //裁剪当前Page page.page.setBounds(page.cropRect, for: .cropBox) let pageItemSize = rect.size let rotate = page.page.rotation var scale = self.fetchPageScale(page, pageSize, autoRotate, autoSize) if data.page.operation.type == .size { if showModel.model == .custom { scale *= showModel.scale } else if showModel.model == .full { scale = 1 } } else if (data.page.operation.type == .poster) { if (data.page.operation.poster.type == .tile) { scale = data.page.operation.poster.scale } } //当前item的自身中心点 let center = CGPoint(x: (pageSize.width - pageItemSize.width * scale) / 2.0 , y: (pageSize.height - pageItemSize.height * scale) / 2.0) var origin = rect.origin //多页Page自动旋转 if autoSize { switch pageOrder { case .horizontal: origin.x = (pageSize.width + columnAndRowSpace.x) * CGFloat(j) + paperInset.left + center.x //页面内容高度 + 下边的行间距 - 第几个cell的高度 +居中 origin.y = paperSize.height - (pageSize.height + columnAndRowSpace.y) * (CGFloat(i) + 1) + center.y + columnAndRowSpace.y case .horizontalReverseSequence: origin.x = paperSize.width - (pageSize.width + columnAndRowSpace.x) * (CGFloat(j) + 1) + center.x + columnAndRowSpace.x origin.y = paperSize.height - (pageSize.height + columnAndRowSpace.y) * (CGFloat(i) + 1) + center.y + paperInset.bottom + columnAndRowSpace.y case .vertical: origin.x = (pageSize.width + columnAndRowSpace.x) * CGFloat(i) + paperInset.left + center.x origin.y = paperSize.height - (pageSize.height + columnAndRowSpace.y) * (CGFloat(j) + 1) + center.y + paperInset.bottom + columnAndRowSpace.y case .verticalReverseSequence: origin.x = paperSize.width - (pageSize.width + columnAndRowSpace.x) * (CGFloat(i) + 1) + center.x + columnAndRowSpace.x origin.y = paperSize.height - (pageSize.height + columnAndRowSpace.y) * (CGFloat(j) + 1) + center.y + paperInset.bottom + columnAndRowSpace.y default: KMPrint("未找到") break } } NSGraphicsContext.saveGraphicsState() //平移 context.translateBy(x: origin.x, y: origin.y) //缩放 context.scaleBy(x: CGFloat(scale), y: CGFloat(scale)) page.page.draw(with: PDFDisplayBox.cropBox, to: context) // page.transform(context, for: PDFDisplayBox.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: 1.0, green: 1.0, blue: 1.0, alpha: 1.0) context.strokePath() } NSGraphicsContext.restoreGraphicsState() // page.setBounds(NSRect(x: 0, y: 0, width: pageRect.size.width, height: pageRect.size.height), for: .cropBox) } } } } } protocol KMPrintPresenterPage {} extension KMPrintPresenter: KMPrintPresenterPage { /** 获取pages @param type 页面类型 @param contentType annoation类型 @param selectPages 当type 为custom时 传入选中page的下标 */ func fetchPageCropRect(_ paperSize: CGSize, _ index: Int, _ pageModel: KMPrintPageModel, _ page: KMPrintDrawPage) -> CGRect { var newRect = page.page.bounds(for: .cropBox) if (pageModel.operation.type == .poster) { let originSize = newRect.size var cropPoint = CGPoint(x: 1, y: 1) var scale = 1.0 if (pageModel.operation.poster.type == .tile) { cropPoint = pageModel.operation.poster.tilePoint // scale = pageModel.operation.poster.scale } else if (pageModel.operation.poster.type == .breakUp) { cropPoint = pageModel.operation.poster.pageOfPaper.point } let width = originSize.width / cropPoint.x let height = originSize.height / cropPoint.y let column: Int = Int(cropPoint.x) //行 let row: Int = Int(cropPoint.y) //列 for i in 0...column - 1 { for j in 0...row - 1 { if i + j + i * (row - 1) == index { newRect.origin.x = CGFloat(i) * width * scale newRect.origin.y = ((originSize.height - CGFloat(j) * height - height)) * scale newRect.size.width = width * scale newRect.size.height = height * scale return newRect } } } } return newRect } func fetchPageShowRect(_ paperSize: CGSize, _ index: Int, _ pageModel: KMPrintPageModel, _ page: KMPrintDrawPage) -> CGRect { var newRect = NSZeroRect var pageRect = CGRect(x: 0, y: 0, width: paperSize.width, height: paperSize.height) if (pageModel.operation.type == .poster) { let pageSize = page.page.bounds(for: .cropBox) var cropPoint = CGPoint(x: 1, y: 1) var scale = 1.0 if (pageModel.operation.poster.type == .tile) { cropPoint = pageModel.operation.poster.tilePoint scale = pageModel.operation.poster.scale } else if (pageModel.operation.poster.type == .breakUp) { cropPoint = pageModel.operation.poster.pageOfPaper.point } if (cropPoint.x == 1 && cropPoint.y == 1) { } else { let originPaperSize = CGSize(width: paperSize.width * cropPoint.x, height: paperSize.height * cropPoint.y) let pageWidth = pageSize.width * scale let pageHeight = pageSize.height * scale let pageOrigin = CGPoint(x: (originPaperSize.width - pageWidth) / 2, y: (originPaperSize.height - pageHeight) / 2) let width = originPaperSize.width / cropPoint.x let height = originPaperSize.height / cropPoint.y let column: Int = Int(cropPoint.x) //行 let row: Int = Int(cropPoint.y) //列 for i in 0...column - 1 { for j in 0...row - 1 { if i + j + i * (row - 1) == index { newRect.origin.x = CGFloat(i) * width newRect.origin.y = ((originPaperSize.height - CGFloat(j) * height - height)) newRect.size.width = width newRect.size.height = height if (pageOrigin.x > newRect.origin.x) { pageRect.origin.x = pageOrigin.x pageRect.size.width = newRect.size.width - pageOrigin.x } else if (originPaperSize.width - pageOrigin.x > newRect.origin.x) { pageRect.origin.x = 0 pageRect.size.width = newRect.size.width - pageOrigin.x } else { pageRect.origin.x = 0 pageRect.size.width = newRect.size.width } if (originPaperSize.height - pageOrigin.y < newRect.origin.y + newRect.size.height) { pageRect.origin.y = 0 pageRect.size.height = newRect.size.height - pageOrigin.y } else if (pageOrigin.y > newRect.origin.y) { pageRect.origin.y = pageOrigin.y pageRect.size.height = newRect.size.height - pageOrigin.y } else { pageRect.origin.y = newRect.origin.y - pageOrigin.y pageRect.size.height = newRect.size.height } return pageRect } } } } } return pageRect } func fetchPageColumnAndRow(_ pageModel: KMPrintPageModel) -> CGPoint { var point = NSZeroPoint let pageOrder: KMPrintPageOperation.Multipage.Order = pageModel.operation.multipage.orderType //页面顺序 switch pageModel.operation.type { case .multipage: point.x = pageModel.operation.multipage.pageOfPaper.point.x point.y = pageModel.operation.multipage.pageOfPaper.point.y default: point.x = 1 point.y = 1 } //如果是横向参数需切换 if pageOrder == .horizontal || pageOrder == .horizontalReverseSequence { let temp = point.x point.x = point.y point.y = temp } return point } func fetchAutoRotate(_ pageModel: KMPrintPageModel) -> Bool { var autoRotate = false switch pageModel.operation.type { case .multipage: autoRotate = pageModel.operation.multipage.isAutoRotate case .pamphlet: autoRotate = pageModel.operation.pamphlet.isAutoRotate default: autoRotate = false } return autoRotate } func fetchAutoSize(_ pageModel: KMPrintPageModel) -> Bool { var autoSize = false switch pageModel.operation.type { case .size: autoSize = true default: autoSize = false } return autoSize } func fetchShowModel(_ pageModel: KMPrintPageModel) -> KMPrintPageOperation.Size { var model = KMPrintPageOperation.Size() switch pageModel.operation.type { case .size: model = pageModel.operation.size default: model = KMPrintPageOperation.Size() } return model } func fetchPageItemSize(_ pageModel: KMPrintPageModel, _ paperSize: CGSize) -> CGSize { var size = NSZeroSize let columnAndRow = self.fetchPageColumnAndRow(pageModel) //行 列数量 let columnAndRowSpace = CGPoint(x: 2, y: 2) //行 列之间的空间 //page大小 size = CGSize(width: (paperSize.width - CGFloat((columnAndRow.x - 1)) * CGFloat(columnAndRowSpace.x)) / columnAndRow.x, height: (paperSize.height - CGFloat((columnAndRow.y - 1)) * CGFloat(columnAndRowSpace.y)) / columnAndRow.y) return size } func fetchPageScale(_ page: KMPrintDrawPage, _ pageItemSize: CGSize, _ autoRotate: Bool, _ autoSize: Bool) -> CGFloat { var scale = 1.0 let originSize = page.page.bounds(for: .cropBox) var rotate = page.page.rotation //取出page横竖时能显示的最大Rect if autoRotate { //page旋转度数为0度或者180度时,在指定的大小内,能显示的比例 let scale1 = min(pageItemSize.width / originSize.width, pageItemSize.height / originSize.height) //page旋转度数为90度或者270度时,在指定的大小内,能显示的比例 let scale2 = min(pageItemSize.width / originSize.height, pageItemSize.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 } } } else { scale = min(pageItemSize.width / originSize.width, pageItemSize.height / originSize.height) } if (autoSize) { } else { scale = min(scale, 1) } return scale } func fetchPageRotate(_ page: KMPrintDrawPage, _ pageItemSize: CGSize, _ autoRotate: Bool) -> CGFloat { var scale = 1.0 let originSize = page.page.bounds(for: .cropBox) var rotate = page.page.rotation //取出page横竖时能显示的最大Rect if autoRotate { //page旋转度数为0度或者180度时,在指定的大小内,能显示的比例 let scale1 = min(pageItemSize.width / originSize.width, pageItemSize.height / originSize.height) //page旋转度数为90度或者270度时,在指定的大小内,能显示的比例 let scale2 = min(pageItemSize.width / originSize.height, pageItemSize.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 } } } else { scale = min(pageItemSize.width / originSize.width, pageItemSize.height / originSize.height) } return scale } func fetchPageLite(pageModel: KMPrintPageModel) { } } protocol KMPrintPresenterPaper {} extension KMPrintPresenter: KMPrintPresenterPaper { /** 获取每张纸的page @param type 页面类型 @param contentType annoation类型 @param selectPages 当type 为custom时 传入选中page的下标 */ func fetchPageOfPaper(_ pageModel: KMPrintPageModel) -> Int { var count = 1 switch pageModel.operation.type { case .multipage: count = Int(pageModel.operation.multipage.pageOfPaper.point.x * pageModel.operation.multipage.pageOfPaper.point.y) case .poster: count = Int(pageModel.operation.multipage.pageOfPaper.point.x * pageModel.operation.multipage.pageOfPaper.point.y) default: count = 1 } return count } /** 获取总纸张数 @param pages page总数 @param contentType annoation类型 @param selectPages 当type 为custom时 传入选中page的下标 */ func fetchTotalPaperCount (_ paperSize: CGSize, _ pages: [KMPrintDrawPage], _ pageModel: KMPrintPageModel) -> Int { var count = 1 let pageOfPaper = self.fetchPageOfPaper(pageModel) switch pageModel.operation.type { case .multipage: count = Int(ceilf(Float(pages.count / pageOfPaper))) case .poster: if (pageModel.operation.poster.type == .tile) { //1 2 4 9 16 let scale = pageModel.operation.poster.scale let pageSize = pages.first?.page.bounds(for: .cropBox).size ?? paperSize let point = self.fetchPosterPageCount(paperSize: paperSize, pageSize: pageSize, scale: scale) pageModel.operation.poster.tilePoint = point count = Int((point.x * point.y)) * pages.count } else if (pageModel.operation.poster.type == .breakUp) { count = Int((pageModel.operation.poster.pageOfPaper.point.x * pageModel.operation.poster.pageOfPaper.point.y)) * pages.count } else { count = Int(ceilf(Float(pages.count / pageOfPaper))) } default: count = Int(ceilf(Float(pages.count / pageOfPaper))) } return count } func fetchPosterPageCount(paperSize: CGSize, pageSize: CGSize, scale: CGFloat) -> CGPoint { var xCount: Int = 1 var yCount: Int = 1 var contain: Bool = true while (contain) { if (pageSize.width * scale < CGFloat(xCount) * paperSize.width && pageSize.height * scale < CGFloat(yCount) * paperSize.height) { contain = false break } //增加行数 和 列数 if xCount == yCount { xCount += 1 } else { yCount += 1 } } return CGPoint(x: xCount, y: yCount) } /** 获取pages @param type 页面类型 @param contentType annoation类型 @param selectPages 当type 为custom时 传入选中page的下标 */ func fetchPaperSize(_ paperModel: KMPrintPaperModel) -> CGSize { var paperSize = paperModel.info.size let direction = paperModel.direction if direction == .vertical { paperSize = CGSize(width: paperModel.info.size.width, height: paperModel.info.size.height) } else if direction == .horizontal { paperSize = CGSize(width: paperModel.info.size.height, height: paperModel.info.size.width) } return paperSize } func fetchPaperItemSize(_ paperModel: KMPrintPaperModel) -> CGSize { var paperSize = self.fetchPaperSize(paperModel) let paperInset = paperModel.info.inset paperSize = CGSize(width: paperSize.width - paperInset.left - paperInset.right, height: paperSize.height - paperInset.bottom - paperInset.top) return paperSize } } protocol KMPrintPresenterDraw {} extension KMPrintPresenter: KMPrintPresenterDraw { // -(void)drawCutMarkContext:(CGContextRef)context contextSize:(CGSize)size // { // CGContextSetStrokeColorWithColor(context, [NSColor blackColor].CGColor); // CGContextSetLineWidth(context, 1.0); // CGContextSetLineCap(context, kCGLineCapSquare); // // if(self.columnIndex == 1 && self.lineIndex == 1) { // [self drawLeftBottomCutMarks:context size:size]; // [self drawRightTopCutMarks:context size:size]; // [self drawRightBottomCutMarks:context size:size]; // } else if (self.lineIndex == 1 && self.columnIndex == self.vertArray.count) { // [self drawLeftTopCutMarks:context size:size]; // [self drawRightTopCutMarks:context size:size]; // [self drawRightBottomCutMarks:context size:size]; // } else if (self.columnIndex == 1 && self.lineIndex == self.hourArray.count) { // [self drawLeftTopCutMarks:context size:size]; // [self drawLeftBottomCutMarks:context size:size]; // [self drawRightBottomCutMarks:context size:size]; // } else if (self.columnIndex == self.vertArray.count && self.hourArray.count == self.lineIndex) { // [self drawLeftTopCutMarks:context size:size]; // [self drawLeftBottomCutMarks:context size:size]; // [self drawRightTopCutMarks:context size:size]; // } else { // [self drawLeftTopCutMarks:context size:size]; // [self drawLeftBottomCutMarks:context size:size]; // [self drawRightTopCutMarks:context size:size]; // [self drawRightBottomCutMarks:context size:size]; // } // //绘制完成 // CGContextStrokePath(context); // } // // //左上角切割标记 // -(void)drawLeftTopCutMarks:(CGContextRef)context size:(CGSize)size // { // CGFloat KBlankA4H =size.height; // CGPoint point_LeftTop = CGPointZero; // // if (self.PDFPrint.splitType == kKMPDFPosterSplitType_PageNumber) { // point_LeftTop.x = self.PDFPrint.fullPageEdgeInsets.left; // } else { // point_LeftTop.x = self.PDFPrint.edgeInsets.left; // } // // point_LeftTop.y = KBlankA4H - self.PDFPrint.edgeInsets.top; // // CGContextMoveToPoint(context, 10,point_LeftTop.y); // CGContextAddLineToPoint(context,point_LeftTop.x, point_LeftTop.y); // // CGContextMoveToPoint(context, point_LeftTop.x - 10,KBlankA4H -10); // CGContextAddLineToPoint(context,point_LeftTop.x - 10,point_LeftTop.y); // } // // //右上角切割标记 // -(void)drawRightTopCutMarks:(CGContextRef)context size:(CGSize)size // { // CGFloat KBlankA4W =size.width; // CGFloat KBlankA4H =size.height; // // CGPoint point_RightTop = CGPointZero;//右上角 // // if (self.PDFPrint.splitType == kKMPDFPosterSplitType_PageNumber) { // point_RightTop.x = KBlankA4W - self.PDFPrint.fullPageEdgeInsets.right; // point_RightTop.y = KBlankA4H - self.PDFPrint.fullPageEdgeInsets.top; // } else { // point_RightTop.x = KBlankA4W - self.PDFPrint.edgeInsets.right; // point_RightTop.y = KBlankA4H - self.PDFPrint.edgeInsets.top; // } // // CGContextMoveToPoint(context,point_RightTop.x,point_RightTop.y); // CGContextAddLineToPoint(context,KBlankA4W - 10,point_RightTop.y); // // CGContextMoveToPoint(context,point_RightTop.x + 10,KBlankA4H - 10); // CGContextAddLineToPoint(context,point_RightTop.x + 10,point_RightTop.y); // } // // //左下角切割标记 // -(void)drawLeftBottomCutMarks:(CGContextRef)context size:(CGSize)size // { // CGPoint point_LeftBottom = CGPointZero;//左下角 // if (self.PDFPrint.splitType == kKMPDFPosterSplitType_PageNumber) { // point_LeftBottom.x = self.PDFPrint.fullPageEdgeInsets.left; // point_LeftBottom.y = self.PDFPrint.fullPageEdgeInsets.bottom; // } else { // point_LeftBottom.x = self.PDFPrint.edgeInsets.left; // point_LeftBottom.y = self.PDFPrint.edgeInsets.bottom; // } // // //左下角 // CGContextMoveToPoint(context, 10,point_LeftBottom.y); // CGContextAddLineToPoint(context,point_LeftBottom.x, point_LeftBottom.y); // // CGContextMoveToPoint(context, point_LeftBottom.x- 10,10); // CGContextAddLineToPoint(context,point_LeftBottom.x - 10,point_LeftBottom.y); // } // // //右下角切割标记 // -(void)drawRightBottomCutMarks:(CGContextRef)context size:(CGSize)size // { // CGFloat KBlankA4W =size.width; // // CGPoint point_RightBottom = CGPointZero;//右下角 // if (self.PDFPrint.splitType == kKMPDFPosterSplitType_PageNumber) { // point_RightBottom.x = KBlankA4W - self.PDFPrint.fullPageEdgeInsets.right; // point_RightBottom.y = self.PDFPrint.fullPageEdgeInsets.bottom; // } else { // point_RightBottom.x = KBlankA4W - self.PDFPrint.edgeInsets.right; // point_RightBottom.y = self.PDFPrint.edgeInsets.bottom; // } // // CGContextMoveToPoint(context,KBlankA4W - 10,point_RightBottom.y); // CGContextAddLineToPoint(context,point_RightBottom.x,point_RightBottom.y); // // CGContextMoveToPoint(context,point_RightBottom.x+ 10,10); // CGContextAddLineToPoint(context,point_RightBottom.x+ 10,point_RightBottom.y); // } func drawString(_ pageModel: KMPrintPageModel, _ contextSize: CGSize) { var string = pageModel.operation.poster.tags.first ?? "" // if string.isEmpty { // string = // } } // // - (void)drawLabelTextContextSize:(CGSize)contextSize // { // CGFloat KBlankA4W =contextSize.width; // CGFloat KBlankA4H =contextSize.height; // // NSString *contextString = nil; // if (self.PDFPrint.labelString && self.PDFPrint.labelString.length > 0) { // contextString = self.PDFPrint.labelString; // } else { // NSDate *date = [NSDate date]; // NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease]; // [formatter setDateFormat:@"YYYY-MM-dd hh:mm:ss"]; // contextString = [NSString stringWithFormat:@"(%ld,%ld) %@ %@",self.columnIndex,self.lineIndex,[self.filePath lastPathComponent],[formatter stringFromDate:date]]; // } // // CGFloat fontSize = 12.0 * (MAX(KBlankA4W, KBlankA4H)/842); // NSFont *font = [NSFont systemFontOfSize:fontSize]; // NSColor *color = [NSColor blackColor]; // // NSSize size = NSZeroSize; // NSMutableParagraphStyle *style = [[[NSMutableParagraphStyle alloc] init] autorelease]; // [style setAlignment:NSCenterTextAlignment]; // [style setLineBreakMode:NSLineBreakByCharWrapping]; // NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; // [dictionary setObject:style forKey:NSParagraphStyleAttributeName]; // [dictionary setObject:color forKey:NSForegroundColorAttributeName]; // [dictionary setObject:font forKey:NSFontAttributeName]; // size = [contextString boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) // options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading // attributes:dictionary].size; // // if (self.PDFPrint.splitType == kKMPDFPosterSplitType_PageNumber) { // [contextString drawInRect:CGRectMake(self.PDFPrint.fullPageEdgeInsets.left +10, // KBlankA4H - self.PDFPrint.fullPageEdgeInsets.top + size.height, // size.width, size.height) // withAttributes:dictionary]; // } else { // [contextString drawInRect:CGRectMake(self.PDFPrint.edgeInsets.left +10, // KBlankA4H - self.PDFPrint.edgeInsets.top + size.height, // size.width, size.height) // withAttributes:dictionary]; // } // // } } protocol KMPrintPresenterPrivate {} extension KMPrintPresenter: KMPrintPresenterPrivate { func isAnnoationStamp(type: String) -> Bool { let annotationStamp: [String] = ["Square"] return annotationStamp.contains(type) } func isAnnoationMarkup(type: String) -> Bool { let annotationStamp: [String] = ["Widget", "Freehand"] return annotationStamp.contains(type) } func isAnnoationForm(type: String) -> Bool { let annotationStamp: [String] = ["FreeText"] return annotationStamp.contains(type) } } protocol KMPrintPresenterProtocol: NSObject { } ///** // @abstract 获取context // @param size纸张大小 // */ //func createContext(_ saveFilePath: String, 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 //}