// // KMWatermarkPDFView.swift // PDF Master // // Created by tangchao on 2022/12/19. // import Cocoa class KMWatermarkPDFView: CPDFView { var watermarkModel: KMWatermarkModel! override func draw(_ page: CPDFPage!, to context: CGContext!) { if (self.watermarkModel == nil) { super.draw(page, to: context) return } if (self.watermarkModel.isFront) { super.draw(page, to: context) if (self.needDraw(page)) { drawWatermarkPage(page, to: context) } } else { if (self.needDraw(page)) { drawWatermarkPage(page, to: context) } super.draw(page, to: context) } } func needDraw(_ page: CPDFPage) -> Bool { if (self.watermarkModel == nil) { return true } if (self.watermarkModel.pageRangeType == 0) { return true } // else if (self.watermarkModel.pageRangeType == 1) { // let array = self.watermarkModel.pagesString.components(separatedBy: ",") // let index: Int = Int(self.document.index(for: page)) // if (!array.contains("\(index+1)")) { // return false // } // } else if (self.watermarkModel.pageRangeType == 1) { let index: Int = Int(self.document.index(for: page)) return (index % 2 == 0) } else if (self.watermarkModel.pageRangeType == 2) { let index: Int = Int(self.document.index(for: page)) return (index % 2 == 1) } else if (self.watermarkModel.pageRangeType == 3) { if (self.watermarkModel.pagesString.isEmpty) { return false } let array = self.watermarkModel.pagesString.components(separatedBy: ",") let index: Int = Int(self.document.index(for: page)) if (!array.contains("\(index+1)")) { return false } } return true } func drawWatermarkPage(_ page: CPDFPage, to context: CGContext) { let pageBounds = page.bounds(for: .cropBox) let w: CGFloat = NSWidth(pageBounds) let h: CGFloat = NSHeight(pageBounds) let width: CGFloat = sqrt(w*w+h*h) var newRect: CGRect = CGRect(x: -(width-w)*0.5, y: -(width-h)*0.5, width: width, height: width) let new_w: CGFloat = NSWidth(newRect) let new_h: CGFloat = NSHeight(newRect) if (context != nil) { NSGraphicsContext.current = NSGraphicsContext(cgContext: context, flipped: false) } NSGraphicsContext.saveGraphicsState() page.transform(context, for: .cropBox) // if (self.watermarkModel.pagesString.count > 0) { // let array = self.watermarkModel.pagesString.components(separatedBy: ",") // let index: Int = Int(self.document.index(for: page)) // if (!array.contains("\(index)")) { // return // } // } if (!self.watermarkModel.text.isEmpty) { var font = self.watermarkModel.textFont if (font == nil) { // font = NSFont(name: "Helvetica", size: 48) } var color = NSColor.black if (self.watermarkModel.textColor != nil) { // color = self.watermarkModel.textColor } var red: CGFloat = 0 var green: CGFloat = 0 var blue: CGFloat = 0 color.usingColorSpaceName(NSColorSpaceName.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: nil) color = NSColor(red: red, green: green, blue: blue, alpha: self.watermarkModel.opacity) var size = NSZeroSize let style = NSMutableParagraphStyle() style.alignment = self.watermarkModel.textAligement style.lineBreakMode = .byCharWrapping let dict = [NSAttributedString.Key.paragraphStyle : style, NSAttributedString.Key.foregroundColor : color, NSAttributedString.Key.font : font] as [NSAttributedString.Key : Any] size = self.watermarkModel.text.boundingRect(with: NSSize(width: 1000, height: 1000), options: NSString.DrawingOptions(rawValue: 3), attributes: dict).size let radian: CGFloat = self.watermarkModel.rotation*(Double.pi/180.0) let t: CGAffineTransform = CGAffineTransform(rotationAngle: radian) var rect:CGRect = CGRect(x: 0, y: 0, width: size.width, height: size.height) if (self.watermarkModel.isTilePage) { context.translateBy(x: w * 0.5, y: h * 0.5) context.concatenate(t) context.translateBy(x: -(w/2), y: -(h/2)) let verticalWidth: CGFloat = size.width + self.watermarkModel.tileHorizontalSpace let horizontalHeight: CGFloat = size.height + self.watermarkModel.tileVerticalSpace let line: Int = Int(((new_h-self.watermarkModel.tileVerticalSpace)/horizontalHeight)+1) let row: Int = Int(((new_w-self.watermarkModel.tileHorizontalSpace)/verticalWidth)+1) let point: CGPoint = CGPoint(x: w*0.5-size.width*0.5+self.watermarkModel.horizontalSpace, y: h*0.5-size.height*0.5+self.watermarkModel.verticalSpace) for i in 0 ..< line { for j in 0 ..< row { self.watermarkModel.text.draw(in: NSRect(x: point.x+CGFloat(j)*verticalWidth, y: point.y+CGFloat(i)*horizontalHeight, width: size.width, height: size.height), withAttributes: dict) } } for i in 1 ..< line { for j in 0 ..< row { self.watermarkModel.text.draw(in: NSRect(x: point.x+CGFloat(j)*verticalWidth, y: point.y-CGFloat(i)*horizontalHeight, width: size.width, height: size.height), withAttributes: dict) } } for i in 0 ..< line { for j in 1 ..< row { self.watermarkModel.text.draw(in: NSRect(x: point.x-CGFloat(j)*verticalWidth, y: point.y+CGFloat(i)*horizontalHeight, width: size.width, height: size.height), withAttributes: dict) } } for i in 1 ..< line { for j in 1 ..< row { self.watermarkModel.text.draw(in: NSRect(x: point.x-CGFloat(j)*verticalWidth, y: point.y-CGFloat(i)*horizontalHeight, width: size.width, height: size.height), withAttributes: dict) } } } else { if (self.watermarkModel.verticalMode == 0) { rect.origin.y = pageBounds.size.height-rect.size.height } else if (self.watermarkModel.verticalMode == 1) { rect.origin.y = (pageBounds.size.height-rect.size.height) * 0.5 } else { rect.origin.y = 0 } if (self.watermarkModel.horizontalMode == 0) { rect.origin.x = 0 } else if (self.watermarkModel.horizontalMode == 1) { rect.origin.x = (pageBounds.size.width-rect.size.width) * 0.5 } else { rect.origin.x = pageBounds.size.width-rect.size.width } rect.origin.x += self.watermarkModel.horizontalSpace rect.origin.y += self.watermarkModel.verticalSpace let contextCenter = CGPoint(x: rect.midX, y: rect.midY) context.translateBy(x: contextCenter.x, y: contextCenter.y) context.rotate(by: radian) context.translateBy(x: -contextCenter.x, y: -contextCenter.y) self.watermarkModel.text.draw(in: rect, withAttributes: dict) } } else if (self.watermarkModel.image != nil) { let tiffData = self.watermarkModel.image.tiffRepresentation let bitmap: NSBitmapImageRep! bitmap = NSBitmapImageRep(data: tiffData!) let ciImage = CIImage(bitmapImageRep: bitmap) var size: NSSize = (ciImage?.extent.size)! size.width *= self.watermarkModel.scale size.height *= self.watermarkModel.scale let radian = self.watermarkModel.rotation * (Double.pi / 180.0) let t: CGAffineTransform = CGAffineTransform(rotationAngle: radian) var rect = NSMakeRect(0, 0, size.width, size.height) if (self.watermarkModel.isTilePage) { context.translateBy(x: w/2,y: h/2) context.concatenate(t) context.translateBy(x: -(w/2), y: -(h/2)) let verticalWidth: CGFloat = size.width + self.watermarkModel.tileHorizontalSpace let horizontalHeight: CGFloat = size.height + self.watermarkModel.tileVerticalSpace let line: Int = Int((new_h - self.watermarkModel.tileVerticalSpace)/horizontalHeight + 1) let row: Int = Int((new_w - self.watermarkModel.tileHorizontalSpace) / verticalWidth + 1) let point = NSPoint(x: w/2 - size.width/2, y: h/2 - size.height/2) for i in 0 ..< (line/2+1) { for j in 0 ..< row { let area = CGRect(x: point.x + CGFloat(j) * verticalWidth, y: point.y + CGFloat(i)*horizontalHeight, width: size.width, height: size.height) self.watermarkModel.image.draw(in: area, from: NSZeroRect, operation: .overlay, fraction: self.watermarkModel.opacity) } } for i in 1 ..< (line/2+1) { for j in 0 ..< row { let area = CGRect(x: point.x + CGFloat(j) * verticalWidth, y: point.y - CGFloat(i)*horizontalHeight, width: size.width, height: size.height) self.watermarkModel.image.draw(in: area, from: NSZeroRect, operation: .overlay, fraction: self.watermarkModel.opacity) } } for i in 0 ..< (line/2+1) { for j in 1 ..< row { let area = CGRect(x: point.x - CGFloat(j) * verticalWidth, y: point.y + CGFloat(i)*horizontalHeight, width: size.width, height: size.height) self.watermarkModel.image.draw(in: area, from: NSZeroRect, operation: .overlay, fraction: self.watermarkModel.opacity) } } for i in 1 ..< (line/2+1) { for j in 1 ..< row { let area = CGRect(x: point.x - CGFloat(j) * verticalWidth, y: point.y - CGFloat(i)*horizontalHeight, width: size.width, height: size.height) self.watermarkModel.image.draw(in: area, from: NSZeroRect, operation: .overlay, fraction: self.watermarkModel.opacity) } } } else { if (self.watermarkModel.verticalMode == 0) { rect.origin.y = pageBounds.size.height-rect.size.height } else if (self.watermarkModel.verticalMode == 1) { rect.origin.y = (pageBounds.size.height-rect.size.height) * 0.5 } else { rect.origin.y = 0 } if (self.watermarkModel.horizontalMode == 0) { rect.origin.x = 0 } else if (self.watermarkModel.horizontalMode == 1) { rect.origin.x = (pageBounds.size.width-rect.size.width) * 0.5 } else { rect.origin.x = pageBounds.size.width-rect.size.width } rect.origin.x += self.watermarkModel.horizontalSpace rect.origin.y += self.watermarkModel.verticalSpace let contextCenter = CGPoint(x: rect.midX, y: rect.midY) context.translateBy(x: contextCenter.x, y: contextCenter.y) context.rotate(by: radian) context.translateBy(x: -contextCenter.x, y: -contextCenter.y) self.watermarkModel.image.draw(in: rect, from: NSZeroRect, operation: .overlay, fraction: self.watermarkModel.opacity) } } NSGraphicsContext.restoreGraphicsState() } }