123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711 |
- //
- // KMWatermarkManager.swift
- // PDF Reader Pro
- //
- // Created by tangchao on 2022/12/19.
- //
- import Cocoa
- enum KMWatermarkKey: String {
- case watermarkType = "watermarkTypeKey"
-
- case text = "WatermarTextKey"
- case textFontSize = "WatermarkOfTextFontSizeKey"
- case textfontStyle = "WatermarkOfTextFontStyleKey"
- case textFontName = "textFontName"
-
- case textColor = "WatermarkTextColorKey"
- case red = "WatermarkOfRedKey"
- case green = "WatermarkOfGreenKey"
- case blue = "WatermarkOfBlueKey"
-
- case imagePath = "WatermarkOfImagePathKey"
-
- case rotate = "WatermarkOfRotationKey"
- case opacity = "WatermarkOfOpacityKey"
- case isScale = "WatermarkOfIsScaleKey"
- case scale = "WatermarkOfScaleKey"
- case verticalMode = "WatermarkOfVerticalModeKey"
- case verticalSpace = "WatermarkOfVerticalSpaceKey"
- case horizontalMode = "WatermarkOfHorizontalModeKey"
- case horizontalSpace = "WatermarkOfHorizontalSpaceKey"
- case isFront = "WatermarkOfIsFrontKey"
- case createDate = "WatermarkOfCreatTemplateDateKey"
- case pageRangeType = "WatermarkOfPageRangeTypeKey"
- case pageRangeString = "WatermarkOfPageStringKey"
- case tileVerticalSpace = "WatermarkTileVerticalSpaceKey"
- case tileHorizontalSpace = "WatermarkTileHorizontalSpaceKey"
- case isTile = "WatermarkOfIsTileKey"
- case lastAddData = "kAddLastWatermarkDataKey1"
- case id = "kWatermarkIDKey"
- case tag = "kWatermarkTagKey"
- case watermarkName = "watermarkNameKey"
-
- }
- class KMWatermarkManager: NSObject {
- let watermarkFolderPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("watermark")
-
- let watermarkPlistPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("watermark").stringByAppendingPathComponent("watermark.plist")
-
- let watermarkImageFolder = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("watermark").stringByAppendingPathComponent("image")
-
- static let defaultManager = KMWatermarkManager()
-
- var watermarks: Array<KMWatermarkModel> = []
-
- var defaultWatermarkData = KMWatermarkModel.defaultWDData()
-
- override init() {
- super.init()
-
- #if DEBUG
- print("watermarkPlistPath=\(watermarkPlistPath ?? "")")
- #endif
-
- if (!FileManager.default.fileExists(atPath: watermarkFolderPath!)) {
- try?FileManager.default.createDirectory(atPath: watermarkFolderPath!, withIntermediateDirectories: true, attributes: nil)
- }
-
- if (!FileManager.default.fileExists(atPath: watermarkImageFolder!)) {
- let create: ()? = try?FileManager.default.createDirectory(atPath: watermarkImageFolder!, withIntermediateDirectories: false)
- }
-
- if (FileManager.default.fileExists(atPath: watermarkPlistPath!)) {
- let dataDict = NSDictionary(contentsOfFile: watermarkPlistPath!)
- for keyIndex in 0 ..< (dataDict?.allKeys.count ?? 0) {
- let key: String = dataDict?.allKeys[keyIndex] as! String
-
- let watermarkDict: NSDictionary = dataDict?.object(forKey: key) as! NSDictionary
- let model = parseDictionary(dict: watermarkDict)
- watermarks.append(model)
- }
- watermarks.sort(){$0.tag > $1.tag}
-
- }
- }
-
- //MARK: - 增删改查
- func addWatermark(watermark: KMWatermarkModel) -> Bool {
- if (!FileManager.default.fileExists(atPath: watermarkFolderPath!)) {
- let create: ()? = try?FileManager.default.createDirectory(atPath: watermarkFolderPath!, withIntermediateDirectories: true, attributes: nil)
- if (create == nil) {
- return false
- }
- }
-
- if (!FileManager.default.fileExists(atPath: watermarkPlistPath!)) {
- FileManager.default.createFile(atPath: watermarkPlistPath!, contents: nil)
- }
-
- let dict = NSDictionary(contentsOfFile: watermarkPlistPath!)
- var newDict:NSMutableDictionary!
- if (dict != nil) {
- newDict = NSMutableDictionary(dictionary: dict!)
- } else {
- newDict = NSMutableDictionary()
- }
-
- let watermarkDict = self.parseWaterMark(model: watermark)
- if (watermarkDict.isEmpty) {
- return false
- }
-
- let key: String = watermark.tag
- if newDict.object(forKey: key) != nil {
- newDict.setObject(watermarkDict, forKey: key as NSCopying)
- } else {
- newDict.addEntries(from: [key : watermarkDict])
- }
-
- let result = newDict.write(toFile: watermarkPlistPath!, atomically: true)
- if (result) {
- if (self.watermarks.count < 1) {
- self.watermarks.append(watermark)
- } else {
- self.watermarks.insert(watermark, at: 0)
- }
- watermark.updatePreviewImage()
- }
- return result
- }
-
- func updateWatermark(watermark: KMWatermarkModel) -> Bool {
- if (!FileManager.default.fileExists(atPath: watermarkFolderPath!)) {
- let create: ()? = try?FileManager.default.createDirectory(atPath: watermarkFolderPath!, withIntermediateDirectories: false)
- if (create == nil) {
- return false
- }
- }
-
- if (!FileManager.default.fileExists(atPath: watermarkPlistPath!)) {
- FileManager.default.createFile(atPath: watermarkPlistPath!, contents: nil)
- }
-
- var flagModel: KMWatermarkModel!
- for model in self.watermarks {
- if (model.tag == watermark.tag) {
- flagModel = model
- break
- }
- }
-
- if (flagModel == nil) {
- return false
- }
-
- let dict = NSDictionary(contentsOfFile: watermarkPlistPath!)
- var newDict:NSMutableDictionary!
- if (dict != nil) {
- newDict = NSMutableDictionary(dictionary: dict!)
- } else {
- newDict = NSMutableDictionary()
- }
-
- let watermarkDict = self.parseWaterMark(model: watermark)
- if (watermarkDict.isEmpty) {
- return false
- }
-
- newDict.setObject(watermarkDict, forKey: flagModel.tag as NSCopying)
- let result = newDict.write(toFile: watermarkPlistPath!, atomically: true)
- if (result) {
- if let index = self.watermarks.firstIndex(of: flagModel) {
- self.watermarks[index] = watermark
- }
- watermark.updatePreviewImage()
- }
- return result
- }
-
- func removeWatermark(watermark: KMWatermarkModel) -> Bool {
-
- if (!FileManager.default.fileExists(atPath: watermarkPlistPath!)) {
- return false
- }
-
- let key: String = watermark.tag
-
- let dictionary = NSDictionary(contentsOfFile: watermarkPlistPath!)
- var newDictionary: NSMutableDictionary!
- if (dictionary != nil) {
- newDictionary = NSMutableDictionary(dictionary: dictionary!)
- } else {
- newDictionary = NSMutableDictionary()
- }
- newDictionary.removeObject(forKey: key)
-
- let result = newDictionary.write(toFile: watermarkPlistPath!, atomically: true)
- if (result) {
- if let filePath: String = watermark.imagePath {
- try?FileManager.default.removeItem(atPath: filePath)
- }
- if (self.watermarks.contains(watermark)) {
- self.watermarks.removeObject(watermark)
- }
- }
- return result
- }
-
- func removeAllWatermark() -> Bool {
- if (!FileManager.default.fileExists(atPath: watermarkPlistPath!)) {
- return false
- }
-
- let dictionary = NSDictionary(contentsOfFile: watermarkPlistPath!)
- var newDictionary: NSMutableDictionary!
- if (dictionary != nil) {
- newDictionary = NSMutableDictionary(dictionary: dictionary!)
- } else {
- newDictionary = NSMutableDictionary()
- }
-
- newDictionary.removeAllObjects()
-
- let result = newDictionary.write(toFile: watermarkPlistPath!, atomically: true)
- if (result) {
- self.watermarks.removeAll()
- }
-
- return result
- }
-
- //MARK: - private
- func setDictToWatermarK(dict: NSDictionary, _ model: KMWatermarkModel) {
-
- model.watermarkType = .text
- if let typeIndex = dict.object(forKey: KMWatermarkKey.watermarkType.rawValue) as? AnyObject {
- if let rawValue = typeIndex as? Int {
- model.watermarkType = CPDFWatermarkType(rawValue: rawValue) ?? .text
- } else if let rawValue = typeIndex as? String, let rawIndex = Int(rawValue) {
- model.watermarkType = CPDFWatermarkType(rawValue: rawIndex) ?? .text
- }
- }
-
- model.text = (dict.object(forKey: KMWatermarkKey.text.rawValue) as? String)
- model.fontName = (dict.object(forKey: KMWatermarkKey.textFontName.rawValue) as? String) ?? ""
- model.fontStyle = (dict.object(forKey: KMWatermarkKey.textfontStyle.rawValue) as? String) ?? ""
- model.fontSize = (dict.object(forKey: KMWatermarkKey.textFontSize.rawValue) as? CGFloat) ?? 12
-
- if let pathValue = dict.object(forKey: KMWatermarkKey.imagePath.rawValue) {
- let path = watermarkFolderPath?.stringByAppendingPathComponent(pathValue as! String)
- if (FileManager.default.fileExists(atPath: path!)) {
- model.imagePath = path ?? ""
- }
- }
-
- model.isScale = (dict.object(forKey: KMWatermarkKey.isScale.rawValue) as? Bool) ?? false
- model.scale = (dict.object(forKey: KMWatermarkKey.scale.rawValue) as? CGFloat) ?? 1
- model.rotation = dict.object(forKey: KMWatermarkKey.rotate.rawValue) as? CGFloat ?? 0
- model.opacity = (dict.object(forKey: KMWatermarkKey.opacity.rawValue) as? CGFloat) ?? 1
- model.verticalPosition = (dict.object(forKey: KMWatermarkKey.verticalMode.rawValue) as? CPDFWatermarkVerticalPosition) ?? .center
- model.ty = dict.object(forKey: KMWatermarkKey.verticalSpace.rawValue) as? CGFloat ?? 0
- model.horizontalPosition = (dict.object(forKey: KMWatermarkKey.horizontalMode.rawValue) as? CPDFWatermarkHorizontalPosition) ?? .center
- model.tx = dict.object(forKey: KMWatermarkKey.horizontalSpace.rawValue) as? CGFloat ?? 0
- if let textColorKey = dict.object(forKey: KMWatermarkKey.textColor.rawValue) as? String {
- model.textColor = NSColor.km_init(hex: textColorKey)
- } else {
- let red: CGFloat = dict.object(forKey: KMWatermarkKey.red.rawValue) as? CGFloat ?? 0
- let green: CGFloat = dict.object(forKey: KMWatermarkKey.green.rawValue) as? CGFloat ?? 0
- let blue: CGFloat = dict.object(forKey: KMWatermarkKey.blue.rawValue) as? CGFloat ?? 0
- model.textColor = NSColor(red: red, green: green, blue: blue, alpha: 1.0)
- }
- model.isFront = (dict.object(forKey: KMWatermarkKey.isFront.rawValue) as? Bool) ?? false
- model.isTilePage = (dict.object(forKey: KMWatermarkKey.isTile.rawValue) as? Bool) ?? false
- model.horizontalSpacing = (dict.object(forKey: KMWatermarkKey.tileHorizontalSpace.rawValue) as? CGFloat) ?? 0
- model.verticalSpacing = (dict.object(forKey: KMWatermarkKey.tileVerticalSpace.rawValue) as? CGFloat) ?? 0
- model.tag = (dict.object(forKey: KMWatermarkKey.tag.rawValue) as? String) ?? ""
- model.watermarkName = (dict.object(forKey: KMWatermarkKey.watermarkName.rawValue) as? String) ?? ""
-
- }
-
- //MARK: - Parse
- func parseWaterMark(model: KMWatermarkModel) -> Dictionary<String, Any> {
-
- var dict: [String : Any] = [:]
-
- if model.watermarkType == .text {
- dict[KMWatermarkKey.watermarkType.rawValue] = "0"
- } else if model.watermarkType == .image {
- dict[KMWatermarkKey.watermarkType.rawValue] = "1"
- }
-
- if let text = model.text {
- dict[KMWatermarkKey.text.rawValue] = text
- }
- dict[KMWatermarkKey.textFontName.rawValue] = model.fontName
- dict[KMWatermarkKey.textfontStyle.rawValue] = model.fontStyle
- dict[KMWatermarkKey.textFontSize.rawValue] = model.fontSize
- if let imagePath = model.imagePath {
- dict[KMWatermarkKey.imagePath.rawValue] = imagePath
- }
- dict[KMWatermarkKey.isFront.rawValue] = model.isFront
- dict[KMWatermarkKey.isScale.rawValue] = model.isScale
- dict[KMWatermarkKey.scale.rawValue] = model.scale
- dict[KMWatermarkKey.opacity.rawValue] = model.opacity
- dict[KMWatermarkKey.rotate.rawValue] = model.rotation
- dict[KMWatermarkKey.verticalMode.rawValue] = model.verticalPosition.rawValue
- dict[KMWatermarkKey.verticalSpace.rawValue] = model.ty
- dict[KMWatermarkKey.horizontalMode.rawValue] = model.horizontalPosition.rawValue
- dict[KMWatermarkKey.horizontalSpace.rawValue] = model.tx
- dict[KMWatermarkKey.textColor.rawValue] = model.textColor.toHex()
- dict[KMWatermarkKey.isTile.rawValue] = model.isTilePage
- dict[KMWatermarkKey.tileVerticalSpace.rawValue] = model.verticalSpacing
- dict[KMWatermarkKey.tileHorizontalSpace.rawValue] = model.horizontalSpacing
- dict[KMWatermarkKey.tag.rawValue] = model.tag
- dict[KMWatermarkKey.watermarkName.rawValue] = model.watermarkName
-
- return dict
- }
-
- private func parseDictionary(dict: NSDictionary) -> KMWatermarkModel {
- let model = KMWatermarkModel()
-
- model.watermarkType = (dict.object(forKey: KMWatermarkKey.watermarkType.rawValue) as? CPDFWatermarkType) ?? .text
-
- model.text = (dict.object(forKey: KMWatermarkKey.text.rawValue) as? String)
- model.fontName = (dict.object(forKey: KMWatermarkKey.textFontName.rawValue) as? String) ?? ""
- model.fontStyle = (dict.object(forKey: KMWatermarkKey.textfontStyle.rawValue) as? String) ?? ""
- model.fontSize = (dict.object(forKey: KMWatermarkKey.textFontSize.rawValue) as? CGFloat) ?? 12
-
- if let pathValue = dict.object(forKey: KMWatermarkKey.imagePath.rawValue) {
- model.imagePath = pathValue as? String
- }
-
- model.isScale = (dict.object(forKey: KMWatermarkKey.isScale.rawValue) as? Bool) ?? false
- model.scale = (dict.object(forKey: KMWatermarkKey.scale.rawValue) as? CGFloat) ?? 1
- model.rotation = dict.object(forKey: KMWatermarkKey.rotate.rawValue) as? CGFloat ?? 0
- model.opacity = (dict.object(forKey: KMWatermarkKey.opacity.rawValue) as? CGFloat) ?? 1
- model.verticalPosition = (dict.object(forKey: KMWatermarkKey.verticalMode.rawValue) as? CPDFWatermarkVerticalPosition) ?? .center
- model.ty = dict.object(forKey: KMWatermarkKey.verticalSpace.rawValue) as? CGFloat ?? 0
- model.horizontalPosition = (dict.object(forKey: KMWatermarkKey.horizontalMode.rawValue) as? CPDFWatermarkHorizontalPosition) ?? .center
- model.tx = dict.object(forKey: KMWatermarkKey.horizontalSpace.rawValue) as? CGFloat ?? 0
- if let textColorKey = dict.object(forKey: KMWatermarkKey.textColor.rawValue) as? String {
- model.textColor = NSColor.km_init(hex: textColorKey)
- } else {
- let red: CGFloat = dict.object(forKey: KMWatermarkKey.red.rawValue) as? CGFloat ?? 0
- let green: CGFloat = dict.object(forKey: KMWatermarkKey.green.rawValue) as? CGFloat ?? 0
- let blue: CGFloat = dict.object(forKey: KMWatermarkKey.blue.rawValue) as? CGFloat ?? 0
- model.textColor = NSColor(red: red, green: green, blue: blue, alpha: 1.0)
- }
- model.isFront = (dict.object(forKey: KMWatermarkKey.isFront.rawValue) as? Bool) ?? false
- model.isTilePage = (dict.object(forKey: KMWatermarkKey.isTile.rawValue) as? Bool) ?? false
- model.horizontalSpacing = (dict.object(forKey: KMWatermarkKey.tileHorizontalSpace.rawValue) as? CGFloat) ?? 0
- model.verticalSpacing = (dict.object(forKey: KMWatermarkKey.tileVerticalSpace.rawValue) as? CGFloat) ?? 0
- model.tag = (dict.object(forKey: KMWatermarkKey.tag.rawValue) as? String) ?? ""
- model.watermarkName = (dict.object(forKey: KMWatermarkKey.watermarkName.rawValue) as? String) ?? ""
-
- return model
- }
-
- //MARK: - Getter
- func drawImageAtpageRect(rect: NSRect, data: KMWatermarkModel) -> NSImage? {
- var size = NSZeroSize
- let text: String = data.text ?? ""
- if data.watermarkType == .image {
- if let image = data.image() {
- size = image.size
- size.width *= data.scale
- size.height *= data.scale
- }
- } else if data.watermarkType == .text {
- var font = NSFont.systemFont(ofSize: 52)
- if data.isTilePage {
- font = NSFont.systemFont(ofSize: data.fontSize)
- }
- let style = NSMutableParagraphStyle()
- style.alignment = .center
- style.lineBreakMode = .byCharWrapping
- let attributes: [NSAttributedString.Key: Any] = [ .paragraphStyle: style, .font: font ]
- size = text.boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude), options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: attributes).size
- }
-
- let radian = data.rotation * (CGFloat.pi/180)
- let t = CGAffineTransform(rotationAngle: radian)
- var newRect = rect
- if !data.isTilePage {
- newRect = CGRect(x: 0, y: 0, width: size.width + 40, height: size.height + 40).applying(t)
- }
- let image = NSImage(size: newRect.size)
- image.lockFocus()
- NSGraphicsContext.current?.imageInterpolation = .high
- NSGraphicsContext.saveGraphicsState()
- NSColor.clear.set()
- rect.fill()
- NSGraphicsContext.restoreGraphicsState()
- guard let context = NSGraphicsContext.current?.cgContext else { return nil }
- let imageSize = newRect.size
- NSGraphicsContext.current = NSGraphicsContext(cgContext: context, flipped: false)
- NSGraphicsContext.saveGraphicsState()
-
- if data.watermarkType == .image {
- guard let image = data.image() else { return nil }
- var size = image.size
- size.width *= data.scale
- size.height *= data.scale
- let width = sqrt(image.size.height * image.size.height + image.size.width * image.size.width)
- let newRect = CGRect(x: -(width - image.size.width)/2, y: -(width - image.size.height)/2, width: width, height: width)
- let new_w = newRect.size.width
- let new_h = newRect.size.height
- let radian = data.rotation * (CGFloat.pi / 180)
- let t = CGAffineTransform(rotationAngle: radian)
- if data.isTilePage {
- context.translateBy(x: image.size.width/2, y: image.size.height/2)
- context.concatenate(t)
- context.translateBy(x: -(image.size.width/2), y: -(image.size.height/2))
-
- let verticalWidth = size.width + data.horizontalSpacing * data.scale
- let horizontalHeight = size.height + data.verticalSpacing * data.scale
- let line: Int = Int((new_h - data.verticalSpacing * data.scale)/horizontalHeight + 1)
- let row: Int = Int((new_w - data.horizontalSpacing * data.scale) / verticalWidth + 1)
- let point = CGPoint(x: image.size.width/2 - size.width/2 + data.tx*data.scale, y:image.size.height/2 - size.height/2 + data.ty * data.scale)
- 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)
- image.draw(in: area, from: NSZeroRect, operation: .sourceOver, fraction: data.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)
- image.draw(in: area, from: NSZeroRect, operation: .sourceOver, fraction: data.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)
- image.draw(in: area, from: NSZeroRect, operation: .sourceOver, fraction: data.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)
- image.draw(in: area, from: NSZeroRect, operation: .sourceOver, fraction: data.opacity)
- }
- }
- } else {
- var size = image.size
- size.width *= data.scale
- size.height *= data.scale
- let radian = data.rotation * (CGFloat.pi / 180)
- let t = CGAffineTransform(rotationAngle: radian)
- var imageRect = CGRect(origin: .zero, size: size).applying(t)
- if data.verticalPosition == .bottom {
- imageRect.origin.y = imageSize.height - imageRect.size.height
- } else if data.verticalPosition == .center {
- imageRect.origin.y = (imageSize.height - imageRect.size.height) / 2.0
- } else {
- imageRect.origin.y = 0
- }
- if data.horizontalPosition == .left {
- imageRect.origin.x = 0
- } else if data.horizontalPosition == .center {
- imageRect.origin.x = (imageSize.width - imageRect.size.width) / 2.0
- } else {
- imageRect.origin.x = imageSize.width - imageRect.size.width
- }
- let contextCenter = CGPoint(x: imageRect.midX, y: imageRect.midY)
- context.translateBy(x: contextCenter.x, y: contextCenter.y)
- context.rotate(by: radian)
- context.translateBy(x: -contextCenter.x, y: -contextCenter.y)
- image.draw(in: CGRect(x: imageRect.origin.x+(imageRect.size.width-size.width)/2.0, y: imageRect.origin.y+(imageRect.size.height-size.height)/2.0, width: size.width, height: size.height), from: NSZeroRect, operation: .sourceOver, fraction: data.opacity)
- }
- }else if text.count > 0 {
- var font = NSFont.systemFont(ofSize: 52)
- if data.isTilePage {
- font = NSFont.systemFont(ofSize: data.fontSize)
- }
- var color = data.textColor
- var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0
- color.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: nil)
- color = NSColor.init(calibratedRed: red, green: green, blue: blue, alpha: data.opacity)
-
- size = .zero
-
- let alpha = data.opacity
- let tileHorizontalSpace = data.horizontalSpacing
- let tileVerticalSpace = data.verticalSpacing
- let horizontalSpace = data.tx
- let verticalSpace = data.ty
- let style = NSMutableParagraphStyle()
- style.alignment = .center
- style.lineBreakMode = .byCharWrapping
- let attributes: [NSAttributedString.Key: Any] = [ .paragraphStyle: style, .foregroundColor: NSColor(calibratedRed: red, green: green, blue: blue, alpha: alpha), .font: font ]
- size = text.boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude), options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: attributes).size
- let textRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
- if data.isTilePage {
- let width = sqrt(image.size.height * image.size.height + image.size.width * image.size.width)
- let newRect = CGRect(x: -(width - image.size.width) / 2, y: -(width - image.size.height) / 2, width: width, height: width)
- let new_w = newRect.size.width
- let new_h = newRect.size.height
- context.translateBy(x: image.size.width / 2, y: image.size.height / 2)
- context.concatenate(CGAffineTransform(rotationAngle: radian))
- context.translateBy(x: -(image.size.width / 2), y: -(image.size.height / 2))
- let verticalWidth = size.width + tileHorizontalSpace / 3.0
- let horizontalHeight = size.height + tileVerticalSpace / 3.0
- let line: Int = Int((new_h - tileHorizontalSpace / 3.0) / horizontalHeight + 1)
- let row: Int = Int((new_w - tileVerticalSpace / 3.0) / verticalWidth + 1)
- let point = CGPoint(x: image.size.width / 2 - size.width / 2 + horizontalSpace / 3.0, y: image.size.height / 2 - size.height / 2 + verticalSpace / 3.0)
- for i in 0..<line {
- for j in 0..<row {
- let drawRect = CGRect(x: point.x + CGFloat(j) * verticalWidth, y: point.y + CGFloat(i) * horizontalHeight, width: size.width, height: size.height)
- text.draw(in: drawRect, withAttributes: attributes)
- }
- }
- for i in 1..<line {
- for j in 0..<row {
- let drawRect = CGRect(x: point.x + CGFloat(j) * verticalWidth, y: point.y - CGFloat(i) * horizontalHeight, width: size.width, height: size.height)
- text.draw(in: drawRect, withAttributes: attributes)
- }
- }
- for i in 0..<line {
- for j in 1..<row {
- let drawRect = CGRect(x: point.x - CGFloat(j) * verticalWidth, y: point.y + CGFloat(i) * horizontalHeight, width: size.width, height: size.height)
- text.draw(in: drawRect, withAttributes: attributes)
- }
- }
- for i in 1..<line {
- for j in 1..<row {
- let drawRect = CGRect(x: point.x - CGFloat(j) * verticalWidth, y: point.y - CGFloat(i) * horizontalHeight, width: size.width, height: size.height)
- text.draw(in: drawRect, withAttributes: attributes)
- }
- }
- } else {
- var textRect = textRect
- if data.verticalPosition == .bottom {
- textRect.origin.y = imageSize.height - textRect.size.height
- } else if data.verticalPosition == .center {
- textRect.origin.y = (imageSize.height - textRect.size.height) / 2.0
- } else {
- textRect.origin.y = 0
- }
- if data.horizontalPosition == .left {
- textRect.origin.x = 0
- } else if data.horizontalPosition == .center {
- textRect.origin.x = (imageSize.width - textRect.size.width) / 2.0
- } else {
- textRect.origin.x = imageSize.width - textRect.size.width
- }
- let contextCenter = CGPoint(x: textRect.midX, y: textRect.midY)
- context.translateBy(x: contextCenter.x, y: contextCenter.y)
- context.rotate(by: radian)
- context.translateBy(x: -contextCenter.x, y: -contextCenter.y)
- (data.text ?? "").draw(in: CGRect(x: textRect.origin.x + (textRect.size.width - size.width) / 2.0, y: textRect.origin.y + (textRect.size.height - size.height) / 2.0, width: size.width, height: size.height), withAttributes: attributes)
- }
- }
- NSGraphicsContext.restoreGraphicsState()
- NSGraphicsContext.current?.imageInterpolation = .default
- image.unlockFocus()
- return image
- }
-
- class func getFontSize() -> [String] {
- return ["6","8","10","12","14",
- "16","18","20","22","24",
- "26","28","30","32","34",
- "36","40","48","64","80",
- "96","112"]
- }
-
- func fetchAvailableName() -> String {
- var availableIndex: Int = 0
- let watermark = "Watermark"
- for model in self.watermarks {
- let watermarkID = model.tag
- if (watermarkID.hasPrefix(watermark)) {
- let indexString: String = (watermarkID.components(separatedBy: watermark).last ?? "0")
- let index: Int = Int(indexString) ?? 0
- if (index >= availableIndex) {
- availableIndex = index + 1
- }
- }
- }
-
- return "\(watermark)\(availableIndex)"
- }
-
- //MARK: - Compare
- class func compareIsChangedModel(_ model: KMWatermarkModel, withDict dict: NSDictionary) -> Bool {
- if let value = dict["fontName"] {
- if model.fontName != (value as! String) {
- return true
- }
- }
-
- if let value = dict.object(forKey: KMWatermarkKey.text.rawValue) {
- if model.text != (value as! String) {
- return true
- }
- }
-
- if let value = dict.object(forKey: KMWatermarkKey.textFontName.rawValue) {
- if model.fontName != (value as! String) {
- return true
- }
- }
-
- if let value = dict.object(forKey: KMWatermarkKey.textfontStyle.rawValue) {
- if model.fontStyle != (value as! String) {
- return true
- }
- }
-
- if let value = dict.object(forKey: KMWatermarkKey.textFontSize.rawValue) {
- if model.fontSize != (value as! CGFloat) {
- return true
- }
- }
-
- if let value = dict.object(forKey: KMWatermarkKey.imagePath.rawValue) {
- if model.imagePath != (value as! String) {
- return true
- }
- }
-
-
- if let value = dict.object(forKey: KMWatermarkKey.isScale.rawValue) {
- if model.isScale != (value as! Bool) {
- return true
- }
- }
- if let value = dict.object(forKey: KMWatermarkKey.scale.rawValue) {
- if model.scale != (value as! CGFloat) {
- return true
- }
- }
-
- if let value = dict.object(forKey: KMWatermarkKey.rotate.rawValue) {
- if model.rotation != (value as! CGFloat) {
- return true
- }
- }
-
- if let value = dict.object(forKey: KMWatermarkKey.opacity.rawValue) {
- if model.opacity != (value as! CGFloat) {
- return true
- }
- }
-
- if let value = dict.object(forKey: KMWatermarkKey.verticalMode.rawValue) {
- if model.verticalPosition.rawValue != (value as! Int) {
- return true
- }
- }
- if let value = dict.object(forKey: KMWatermarkKey.verticalSpace.rawValue) {
- if model.ty != (value as! CGFloat) {
- return true
- }
- }
- if let value = dict.object(forKey: KMWatermarkKey.horizontalMode.rawValue) {
- if model.horizontalPosition.rawValue != (value as! Int) {
- return true
- }
- }
-
- if let value = dict.object(forKey: KMWatermarkKey.horizontalSpace.rawValue) {
- if model.tx != (value as! CGFloat) {
- return true
- }
- }
-
- if let value = dict.object(forKey: KMWatermarkKey.textColor.rawValue) {
- var modelColorText = model.textColor.colorToHexString()
- if modelColorText.count > 7 {
- modelColorText = modelColorText.substring(to: 7)
- }
- if var valueString = value as? String {
- if valueString.count > 7 {
- valueString = valueString.substring(to: 7)
- }
- if valueString != modelColorText {
- return true
- }
- }
- }
-
- if let value = dict.object(forKey: KMWatermarkKey.isFront.rawValue) {
- if model.isFront != (value as! Bool) {
- return true
- }
- }
- if let value = dict.object(forKey: KMWatermarkKey.isTile.rawValue) {
- if model.isTilePage != (value as! Bool) {
- return true
- }
- }
- if let value = dict.object(forKey: KMWatermarkKey.tileHorizontalSpace.rawValue) {
- if model.horizontalSpacing != (value as! CGFloat) {
- return true
- }
- }
- if let value = dict.object(forKey: KMWatermarkKey.tileVerticalSpace.rawValue) {
- if model.verticalSpacing != (value as! CGFloat) {
- return true
- }
- }
-
- return false
- }
- }
|