KMWatermarkAdjectiveTools.swift 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. //
  2. // KMWatermarkAdjectiveTools.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by tangchao on 2022/12/27.
  6. //
  7. import Cocoa
  8. enum KMWatermarkAdjectiveType: Int {
  9. case watermark = 1
  10. case background = 2
  11. case headerfooter = 3
  12. case bates = 4
  13. }
  14. @objc class KMWatermarkAdjectiveTools: NSObject {
  15. class func fetchAvailableFonts(_ size: CGFloat) -> [NSAttributedString] {
  16. let fonts = NSFontManager.shared.availableFontFamilies
  17. var result: Array<NSAttributedString> = []
  18. for fontName in fonts {
  19. let font = NSFont(name: fontName, size: size)
  20. let attribute = [NSAttributedString.Key.font : font]
  21. let string = NSAttributedString(string: fontName, attributes: attribute as [NSAttributedString.Key : Any])
  22. result.append(string)
  23. }
  24. return result
  25. }
  26. class func fontNameToAttribute(_ name: String, _ size: CGFloat) -> NSAttributedString? {
  27. let names = NSFontManager.shared.availableFontFamilies
  28. if (!names.contains(name)) {
  29. return nil
  30. }
  31. let font = NSFont(name: name, size: size)
  32. if (font == nil) {
  33. return nil
  34. }
  35. let attribute = [NSAttributedString.Key.font : font]
  36. return NSAttributedString(string: name, attributes: attribute as [NSAttributedString.Key : Any])
  37. }
  38. class func parseColor(color: NSColor) -> (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
  39. var red: CGFloat = 0.0
  40. var green: CGFloat = 0.0
  41. var blue: CGFloat = 0.0
  42. var alpha: CGFloat = 0.0
  43. color.usingColorSpaceName(NSColorSpaceName.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
  44. return (red, green, blue, alpha)
  45. }
  46. @objc class func getDateFormats() -> [String] {
  47. return ["m/d", "m/d/yy", "m/d/yyyy",
  48. "mm/dd/yy", "mm/dd/yyyy",
  49. "d/m/yy", "d/m/yyyy",
  50. "dd/mm/yy", "dd/mm/yyyy",
  51. "mm/yy", "mm/yyyy",
  52. "m.d.yy", "m.d.yyyy",
  53. "mm.dd.yy", "mm.dd.yyyy", "mm.yy", "mm.yyyy",
  54. "d.m.yy", "d.m.yyyy",
  55. "dd.mm.yy", "dd.mm.yyyy",
  56. "yy-mm-dd",
  57. "yyyy-mm-dd"]
  58. }
  59. class func getPageFormats() -> [String] {
  60. return ["1",
  61. "1 of n",
  62. "1/n",
  63. "Page 1",
  64. "Page 1 of n"]
  65. }
  66. class func parsePageFormat(formatString: String, startPage: String, pageCount: String) -> String {
  67. var result = formatString
  68. for pageFormat in self.getPageFormats() {
  69. let string = "<<\(pageFormat)>>"
  70. if (result.contains(string)) {
  71. var tempString = ""
  72. if (string == "<<1>>") {
  73. tempString.append("<<\(startPage)>>")
  74. } else if (string == "<<1 of n>>") {
  75. tempString.append("<<\(startPage)>>")
  76. tempString.append(" of \(pageCount)")
  77. } else if (string == "<<1/n>>") {
  78. tempString.append("<<\(startPage)>>")
  79. tempString.append("/\(pageCount)")
  80. } else if (string == "<<Page 1>>") {
  81. tempString.append("Page \(startPage)")
  82. } else if (string == "<<Page 1 of n>>") {
  83. tempString.append("Page \(startPage)")
  84. tempString.append("of \(pageCount)")
  85. }
  86. result = result.replacingOccurrences(of: string, with: tempString)
  87. }
  88. }
  89. return result
  90. }
  91. class func parseDateFormat(formatString: String) -> String {
  92. var result: String = formatString
  93. for dateFormat in self.getDateFormats() {
  94. if (result.contains(dateFormat)) {
  95. var formatString: String = dateFormat.replacingOccurrences(of: "m", with: "M")
  96. var replace = "<<\(dateFormat)>>"
  97. let date = Date()
  98. let dateFormatter = DateFormatter()
  99. dateFormatter.dateFormat = formatString
  100. var dateString = dateFormatter.string(from: date)
  101. result = result.replacingOccurrences(of: replace, with: dateString)
  102. }
  103. }
  104. return result
  105. }
  106. class func KMWatermarkAdjectiveType(from toolBarType: KMToolbarType) -> KMWatermarkAdjectiveType {
  107. if (toolBarType == .bates) {
  108. return .bates
  109. } else if (toolBarType == .headerAndFooter) {
  110. return .headerfooter
  111. } else if (toolBarType == .background) {
  112. return .background
  113. } else if (toolBarType == .watermark) {
  114. return .watermark
  115. }
  116. return .watermark
  117. }
  118. class func KMToolBarTypeToRightSubViewType(_ type: KMToolbarType) -> RightSubViewType {
  119. if (type == .bates) {
  120. return .Bates
  121. } else if (type == .headerAndFooter) {
  122. return .Headerfooter
  123. } else if (type == .background) {
  124. return .Background
  125. } else if (type == .watermark) {
  126. return .Watermark
  127. }
  128. return .None
  129. }
  130. // MARK: Apply
  131. class func apply(_ model: AnyObject, _ pdfView: CPDFView, _ toPath: String, completion: @escaping (_ result: Bool) -> ()) {
  132. if (model.isKind(of: KMHeaderFooterObject.self)) {
  133. KMWatermarkAdjectiveTools.applyBates(model as! KMHeaderFooterObject, pdfView, toPath, completion: completion)
  134. } else if (model.isKind(of: KMHeaderFooterObject.self)) {
  135. KMWatermarkAdjectiveTools.applyHeaderFooter(model as! KMHeaderFooterObject, pdfView, toPath, completion: completion)
  136. } else if (model.isKind(of: KMBackgroundModel.self)) {
  137. KMWatermarkAdjectiveTools.applyBackground(model as! KMBackgroundModel, pdfView, toPath, completion: completion)
  138. } else if (model.isKind(of: KMWatermarkModel.self)) {
  139. KMWatermarkAdjectiveTools.applyWatermark(model as! KMWatermarkModel, pdfView, toPath, completion: completion)
  140. }
  141. }
  142. class func delete(_ type: KMWatermarkAdjectiveType, _ pdfView: CPDFView, _ toPath: String, completion: @escaping (_ result: Bool) -> ()) {
  143. if (pdfView.document.allowsPrinting == false || pdfView.document.allowsCopying == false) {
  144. let alert = NSAlert()
  145. alert.alertStyle = .critical
  146. alert.messageText = NSLocalizedString("This PDF document's user permissions does not allow modifying, content copying and printing.", comment: "")
  147. alert.runModal()
  148. completion(false)
  149. return
  150. }
  151. DispatchQueue.global().async {
  152. let document: CPDFDocument = CPDFDocument(url: pdfView.document.documentURL)
  153. if (type == .bates) {
  154. let property = document.bates()
  155. property?.clear()
  156. } else if (type == .headerfooter) {
  157. let property = document.headerFooter()
  158. property?.clear()
  159. } else if (type == .background) {
  160. let property = document.background()
  161. property?.clear()
  162. } else if (type == .watermark) {
  163. let array = document.watermarks() ?? []
  164. for model in array {
  165. document.removeWatermark(model)
  166. }
  167. }
  168. /// 保存到临时路径
  169. let documentPath = NSTemporaryDirectory()
  170. let tempPath: String = "\(documentPath)/\(toPath.lastPathComponent)"
  171. if (FileManager.default.fileExists(atPath: tempPath)) {
  172. try?FileManager.default.removeItem(atPath: tempPath)
  173. }
  174. let result = document.write(to: URL(fileURLWithPath: tempPath))
  175. if (result) {
  176. if (FileManager.default.fileExists(atPath: toPath)) {
  177. try?FileManager.default.removeItem(atPath: toPath)
  178. }
  179. try?FileManager.default.moveItem(atPath: tempPath, toPath: toPath)
  180. } else {
  181. try?FileManager.default.removeItem(atPath: tempPath)
  182. }
  183. DispatchQueue.main.async {
  184. completion(result)
  185. }
  186. }
  187. }
  188. private class func applyBates(_ model: KMHeaderFooterObject, _ pdfView: CPDFView, _ toPath: String, completion: @escaping (_ result: Bool) -> ()) {
  189. DispatchQueue.global().async {
  190. let document: CPDFDocument = pdfView.document
  191. var property = document.bates()
  192. var fontSize = 0.0
  193. var fontName: String = ""
  194. // switch model.textFont {
  195. // case .font(name: let name, size: let size):
  196. // fontName = name
  197. // fontSize = size
  198. // break
  199. // default:
  200. // break
  201. // }
  202. let font = NSFont.boldSystemFont(ofSize:fontSize)
  203. let style = NSMutableParagraphStyle()
  204. style.alignment = .center
  205. style.lineBreakMode = .byCharWrapping
  206. let size: NSSize = "text".boundingRect(with: NSSize(width: 1000, height: 1000), options: NSString.DrawingOptions(rawValue: 3), attributes: [NSAttributedString.Key.font : font, NSAttributedString.Key.paragraphStyle : style]).size
  207. property?.margin = NSEdgeInsetsMake(max(CGFloat(model.topMargin)-size.height, 0), CGFloat(model.leftMargin), max(CGFloat(model.bottomMargin)-size.height, 0), CGFloat(model.rightMargin))
  208. let strings = [model.topLeftString, model.topCenterString, model.topRightString, model.bottomLeftString, model.bottomCenterString, model.bottomRightString]
  209. var count: Int = 0
  210. var color: NSColor!
  211. // switch model.textColor {
  212. // case .color(red: let red, green: let green, blue: let blue, alpha: let alpha):
  213. // color = NSColor(red: red, green: green, blue: blue, alpha: alpha)
  214. // default:
  215. // break
  216. // }
  217. if (color == nil) {
  218. color = NSColor.black
  219. }
  220. for text in strings {
  221. property?.setText(text, at: UInt(count))
  222. property?.setTextColor(color, at: UInt(count))
  223. property?.setFontSize(fontSize, at: UInt(count))
  224. property?.setFontName(fontName, at: UInt(count))
  225. count += 1
  226. }
  227. // let pagesString = KMWatermarkAdjectiveTools.findPagesString(model)
  228. // if (pagesString.isEmpty) {
  229. // property?.pageString = "0-\(document.pageCount-1)"
  230. // } else {
  231. // property?.pageString = pagesString
  232. // }
  233. property?.update()
  234. /// 保存到临时路径
  235. let documentPath = NSTemporaryDirectory()
  236. let tempPath: String = "\(documentPath)/\(toPath.lastPathComponent)"
  237. if (FileManager.default.fileExists(atPath: tempPath)) {
  238. try?FileManager.default.removeItem(atPath: tempPath)
  239. }
  240. let result = document.write(to: URL(fileURLWithPath: tempPath))
  241. if (result) {
  242. if (FileManager.default.fileExists(atPath: toPath)) {
  243. try?FileManager.default.removeItem(atPath: toPath)
  244. }
  245. try?FileManager.default.moveItem(atPath: tempPath, toPath: toPath)
  246. } else {
  247. try?FileManager.default.removeItem(atPath: tempPath)
  248. }
  249. DispatchQueue.main.async {
  250. completion(result)
  251. }
  252. }
  253. }
  254. private class func applyHeaderFooter(_ model: KMHeaderFooterObject, _ pdfView: CPDFView, _ toPath: String, completion: @escaping (_ result: Bool) -> ()) {
  255. DispatchQueue.global().async {
  256. let document: CPDFDocument = pdfView.document
  257. var property = document.headerFooter()
  258. var fontSize = 0.0
  259. var fontName: String = ""
  260. // switch model.textFont {
  261. // case .font(name: let name, size: let size):
  262. // fontSize = size
  263. // fontName = name
  264. // break
  265. // default:
  266. // break
  267. // }
  268. let font = NSFont.boldSystemFont(ofSize:fontSize)
  269. let style = NSMutableParagraphStyle()
  270. style.alignment = .center
  271. style.lineBreakMode = .byCharWrapping
  272. let size: NSSize = "text".boundingRect(with: NSSize(width: 1000, height: 1000), options: NSString.DrawingOptions(rawValue: 3), attributes: [NSAttributedString.Key.font : font, NSAttributedString.Key.paragraphStyle : style]).size
  273. property?.margin = NSEdgeInsetsMake(max(CGFloat(model.topMargin)-size.height, 0), CGFloat(model.leftMargin), max(CGFloat(model.bottomMargin)-size.height, 0), CGFloat(model.rightMargin))
  274. let strings = KMWatermarkAdjectiveTools.parseModel(model: model, pdfView.document.pageCount)
  275. var count: Int = 0
  276. var color: NSColor!
  277. // switch model.textColor {
  278. // case .color(red: let red, green: let green, blue: let blue, alpha: let alpha):
  279. // color = NSColor(red: red, green: green, blue: blue, alpha: alpha)
  280. // default:
  281. // break
  282. // }
  283. if (color == nil) {
  284. color = NSColor.black
  285. }
  286. for text in strings {
  287. property?.setText(text, at: UInt(count))
  288. property?.setTextColor(color, at: UInt(count))
  289. property?.setFontSize(fontSize, at: UInt(count))
  290. property?.setFontName(fontName, at: UInt(count))
  291. count += 1
  292. }
  293. // let pagesString = KMWatermarkAdjectiveTools.findPagesString(model)
  294. // if (pagesString.isEmpty) {
  295. // property?.pageString = "0-\(document.pageCount-1)"
  296. // } else {
  297. // property?.pageString = pagesString
  298. // }
  299. property?.update()
  300. /// 保存到临时路径
  301. let documentPath = NSTemporaryDirectory()
  302. let tempPath: String = "\(documentPath)/\(toPath.lastPathComponent)"
  303. if (FileManager.default.fileExists(atPath: tempPath)) {
  304. try?FileManager.default.removeItem(atPath: tempPath)
  305. }
  306. let result = document.write(to: URL(fileURLWithPath: tempPath))
  307. if (result) {
  308. if (FileManager.default.fileExists(atPath: toPath)) {
  309. try?FileManager.default.removeItem(atPath: toPath)
  310. }
  311. try?FileManager.default.moveItem(atPath: tempPath, toPath: toPath)
  312. } else {
  313. try?FileManager.default.removeItem(atPath: tempPath)
  314. }
  315. DispatchQueue.main.async {
  316. completion(result)
  317. }
  318. }
  319. }
  320. private class func applyBackground(_ model: KMBackgroundModel, _ pdfView: CPDFView, _ toPath: String, completion: @escaping (_ result: Bool) -> ()) {
  321. DispatchQueue.global().async {
  322. let document: CPDFDocument = pdfView.document
  323. var property = document.background()
  324. property!.scale = model.scale
  325. property!.rotation = CGFloat(-model.rotation)
  326. property!.opacity = model.opacity
  327. property?.xOffset = model.horizontalSpace
  328. property?.yOffset = model.verticalSpace
  329. property?.horizontalAlignment = UInt(model.horizontalMode)
  330. property?.verticalAlignment = UInt(model.verticalMode)
  331. if (model.type == .color) {
  332. property?.color = model.color
  333. property?.type = .color
  334. }
  335. property?.pageString = "0-\(document.pageCount-1)"
  336. property?.update()
  337. /// 保存到临时路径
  338. let documentPath = NSTemporaryDirectory()
  339. let tempPath: String = "\(documentPath)/\(toPath.lastPathComponent)"
  340. if (FileManager.default.fileExists(atPath: tempPath)) {
  341. try?FileManager.default.removeItem(atPath: tempPath)
  342. }
  343. let result = document.write(to: URL(fileURLWithPath: tempPath))
  344. if (result) {
  345. if (FileManager.default.fileExists(atPath: toPath)) {
  346. try?FileManager.default.removeItem(atPath: toPath)
  347. }
  348. try?FileManager.default.moveItem(atPath: tempPath, toPath: toPath)
  349. } else {
  350. try?FileManager.default.removeItem(atPath: tempPath)
  351. }
  352. DispatchQueue.main.async {
  353. completion(result)
  354. }
  355. }
  356. }
  357. private class func applyWatermark(_ model: KMWatermarkModel, _ pdfView: CPDFView, _ toPath: String, completion: @escaping (_ result: Bool) -> ()) {
  358. DispatchQueue.global().async {
  359. var property: CPDFWatermark!
  360. var scale: CGFloat = model.scale
  361. if (!model.text.isEmpty) {
  362. property = CPDFWatermark(document: pdfView.document, type: .text)
  363. property.text = model.text
  364. property.textColor = model.getTextColor()
  365. scale = model.getTextFontSize() / 24.0
  366. } else {
  367. property = CPDFWatermark(document: pdfView.document, type: .image)
  368. property.image = model.image
  369. }
  370. property.scale = scale
  371. property.rotation = -model.rotation
  372. property.opacity = model.opacity
  373. property.tx = model.horizontalSpace
  374. property.ty = model.verticalSpace
  375. property.isFront = model.isFront
  376. var pageString: String = ""
  377. if (model.pageRangeType == .all) {
  378. for i in 0 ..< pdfView.document.pageCount {
  379. pageString.append("\(i)")
  380. if (i != pdfView.document.pageCount-1) {
  381. pageString.append(",")
  382. }
  383. }
  384. } else if (model.pageRangeType == .odd) {
  385. for i in 0 ..< pdfView.document.pageCount {
  386. if (i % 2 == 0) {
  387. pageString.append("\(i)")
  388. } else {
  389. continue
  390. }
  391. if (i != pdfView.document.pageCount-1) {
  392. pageString.append(",")
  393. }
  394. }
  395. } else if (model.pageRangeType == .even) {
  396. for i in 0 ..< pdfView.document.pageCount {
  397. if (i % 2 == 1) {
  398. pageString.append("\(i)")
  399. } else {
  400. continue
  401. }
  402. if (i != pdfView.document.pageCount-1) {
  403. pageString.append(",")
  404. }
  405. }
  406. } else {
  407. pageString = model.pagesString
  408. }
  409. property.pageString = pageString
  410. property.isTilePage = model.isTilePage
  411. property.horizontalSpacing = model.tileHorizontalSpace / scale
  412. property.verticalSpacing = model.tileVerticalSpace / scale
  413. if (model.verticalMode == 0) {
  414. property.verticalPosition = .top
  415. } else if (model.verticalMode == 1) {
  416. property.verticalPosition = .center
  417. } else if (model.verticalMode == 2) {
  418. property.verticalPosition = .bottom
  419. }
  420. if (model.horizontalMode == 0) {
  421. property.horizontalPosition = .left
  422. } else if (model.horizontalMode == 1) {
  423. property.horizontalPosition = .center
  424. } else if (model.horizontalMode == 2) {
  425. property.horizontalPosition = .right
  426. }
  427. model.watermark = property
  428. pdfView.document.addWatermark(property)
  429. /// 保存到临时路径
  430. let documentPath = NSTemporaryDirectory()
  431. let tempPath: String = "\(documentPath)/\(toPath.lastPathComponent)"
  432. if (FileManager.default.fileExists(atPath: tempPath)) {
  433. try?FileManager.default.removeItem(atPath: tempPath)
  434. }
  435. let result = pdfView.document.write(to: URL(fileURLWithPath: tempPath))
  436. if (result) {
  437. if (FileManager.default.fileExists(atPath: toPath)) {
  438. try?FileManager.default.removeItem(atPath: toPath)
  439. }
  440. try?FileManager.default.moveItem(atPath: tempPath, toPath: toPath)
  441. } else {
  442. try?FileManager.default.removeItem(atPath: tempPath)
  443. }
  444. DispatchQueue.main.async {
  445. completion(result)
  446. }
  447. }
  448. }
  449. // MARK: Add
  450. class func add(_ model: AnyObject, _ pdfView: CPDFView, completion: @escaping (_ result: Bool) -> ()) {
  451. if (model.isKind(of: KMHeaderFooterObject.self)) {
  452. // KMWatermarkAdjectiveTools.applyBates(model as! KMHeaderFooterObject, pdfView, toPath, completion: completion)
  453. } else if (model.isKind(of: KMHeaderFooterObject.self)) {
  454. // KMWatermarkAdjectiveTools.applyHeaderFooter(model as! KMHeaderFooterObject, pdfView, toPath, completion: completion)
  455. } else if (model.isKind(of: KMBackgroundModel.self)) {
  456. // KMWatermarkAdjectiveTools.applyBackground(model as! KMBackgroundModel, pdfView, toPath, completion: completion)
  457. } else if (model.isKind(of: KMWatermarkModel.self)) {
  458. KMWatermarkAdjectiveTools.addWatermark(model as! KMWatermarkModel, pdfView, completion: completion)
  459. }
  460. }
  461. private class func addWatermark(_ model: KMWatermarkModel, _ pdfView: CPDFView, completion: @escaping (_ result: Bool) -> ()) {
  462. DispatchQueue.global().async {
  463. var property: CPDFWatermark!
  464. var scale: CGFloat = model.scale
  465. if (!model.text.isEmpty) {
  466. property = CPDFWatermark(document: pdfView.document, type: .text)
  467. property.text = model.text
  468. property.textColor = model.getTextColor()
  469. scale = model.getTextFontSize() / 24.0
  470. } else {
  471. property = CPDFWatermark(document: pdfView.document, type: .image)
  472. property.image = model.image
  473. }
  474. property.scale = scale
  475. property.rotation = -model.rotation
  476. property.opacity = model.opacity
  477. property.tx = model.horizontalSpace
  478. property.ty = model.verticalSpace
  479. property.isFront = model.isFront
  480. var pageString: String = ""
  481. if (model.pageRangeType == .all) {
  482. for i in 0 ..< pdfView.document.pageCount {
  483. pageString.append("\(i)")
  484. if (i != pdfView.document.pageCount-1) {
  485. pageString.append(",")
  486. }
  487. }
  488. } else if (model.pageRangeType == .odd) {
  489. for i in 0 ..< pdfView.document.pageCount {
  490. if (i % 2 == 0) {
  491. pageString.append("\(i)")
  492. } else {
  493. continue
  494. }
  495. if (i != pdfView.document.pageCount-1) {
  496. pageString.append(",")
  497. }
  498. }
  499. } else if (model.pageRangeType == .even) {
  500. for i in 0 ..< pdfView.document.pageCount {
  501. if (i % 2 == 1) {
  502. pageString.append("\(i)")
  503. } else {
  504. continue
  505. }
  506. if (i != pdfView.document.pageCount-1) {
  507. pageString.append(",")
  508. }
  509. }
  510. } else {
  511. pageString = model.pagesString
  512. }
  513. property.pageString = pageString
  514. property.isTilePage = model.isTilePage
  515. property.horizontalSpacing = model.tileHorizontalSpace / scale
  516. property.verticalSpacing = model.tileVerticalSpace / scale
  517. if (model.verticalMode == 0) {
  518. property.verticalPosition = .top
  519. } else if (model.verticalMode == 1) {
  520. property.verticalPosition = .center
  521. } else if (model.verticalMode == 2) {
  522. property.verticalPosition = .bottom
  523. }
  524. if (model.horizontalMode == 0) {
  525. property.horizontalPosition = .left
  526. } else if (model.horizontalMode == 1) {
  527. property.horizontalPosition = .center
  528. } else if (model.horizontalMode == 2) {
  529. property.horizontalPosition = .right
  530. }
  531. model.watermark = property
  532. let result = pdfView.document.addWatermark(property)
  533. DispatchQueue.main.async {
  534. completion(result)
  535. }
  536. }
  537. }
  538. // MARK: Update
  539. class func update(_ model: AnyObject, _ pdfView: CPDFView, completion: @escaping (_ result: Bool) -> ()) {
  540. if (model.isKind(of: KMHeaderFooterObject.self)) {
  541. // KMWatermarkAdjectiveTools.applyBates(model as! KMHeaderFooterObject, pdfView, toPath, completion: completion)
  542. } else if (model.isKind(of: KMHeaderFooterObject.self)) {
  543. // KMWatermarkAdjectiveTools.applyHeaderFooter(model as! KMHeaderFooterObject, pdfView, toPath, completion: completion)
  544. } else if (model.isKind(of: KMBackgroundModel.self)) {
  545. // KMWatermarkAdjectiveTools.applyBackground(model as! KMBackgroundModel, pdfView, toPath, completion: completion)
  546. } else if (model.isKind(of: KMWatermarkModel.self)) {
  547. KMWatermarkAdjectiveTools.updateWatermark(model as! KMWatermarkModel, pdfView, completion: completion)
  548. }
  549. }
  550. private class func updateWatermark(_ model: KMWatermarkModel, _ pdfView: CPDFView, completion: @escaping (_ result: Bool) -> ()) {
  551. DispatchQueue.global().async {
  552. var property: CPDFWatermark!
  553. var scale: CGFloat = model.scale
  554. if (!model.text.isEmpty) {
  555. property = CPDFWatermark(document: pdfView.document, type: .text)
  556. property.text = model.text
  557. property.textColor = model.getTextColor()
  558. scale = model.getTextFontSize() / 24.0
  559. } else {
  560. property = CPDFWatermark(document: pdfView.document, type: .image)
  561. property.image = model.image
  562. }
  563. property.scale = scale
  564. property.rotation = -model.rotation
  565. property.opacity = model.opacity
  566. property.tx = model.horizontalSpace
  567. property.ty = model.verticalSpace
  568. property.isFront = model.isFront
  569. var pageString: String = ""
  570. if (model.pageRangeType == .all) {
  571. for i in 0 ..< pdfView.document.pageCount {
  572. pageString.append("\(i)")
  573. if (i != pdfView.document.pageCount-1) {
  574. pageString.append(",")
  575. }
  576. }
  577. } else if (model.pageRangeType == .odd) {
  578. for i in 0 ..< pdfView.document.pageCount {
  579. if (i % 2 == 0) {
  580. pageString.append("\(i)")
  581. } else {
  582. continue
  583. }
  584. if (i != pdfView.document.pageCount-1) {
  585. pageString.append(",")
  586. }
  587. }
  588. } else if (model.pageRangeType == .even) {
  589. for i in 0 ..< pdfView.document.pageCount {
  590. if (i % 2 == 1) {
  591. pageString.append("\(i)")
  592. } else {
  593. continue
  594. }
  595. if (i != pdfView.document.pageCount-1) {
  596. pageString.append(",")
  597. }
  598. }
  599. } else {
  600. pageString = model.pagesString
  601. }
  602. property.pageString = pageString
  603. property.isTilePage = model.isTilePage
  604. property.horizontalSpacing = model.tileHorizontalSpace / scale
  605. property.verticalSpacing = model.tileVerticalSpace / scale
  606. if (model.verticalMode == 0) {
  607. property.verticalPosition = .top
  608. } else if (model.verticalMode == 1) {
  609. property.verticalPosition = .center
  610. } else if (model.verticalMode == 2) {
  611. property.verticalPosition = .bottom
  612. }
  613. if (model.horizontalMode == 0) {
  614. property.horizontalPosition = .left
  615. } else if (model.horizontalMode == 1) {
  616. property.horizontalPosition = .center
  617. } else if (model.horizontalMode == 2) {
  618. property.horizontalPosition = .right
  619. }
  620. model.watermark = property
  621. let watermarks = pdfView.document.watermarks()
  622. if (watermarks != nil) {
  623. for i in 0 ..< watermarks!.count {
  624. let watermark = watermarks![i]
  625. pdfView.document.removeWatermark(watermark)
  626. }
  627. }
  628. let result = pdfView.document.addWatermark(property)
  629. DispatchQueue.main.async {
  630. completion(result)
  631. }
  632. }
  633. }
  634. private class func parseModel(model: KMHeaderFooterObject, _ pageCount: UInt) -> [String] {
  635. var topLeftString: String = ""
  636. if (!model.topLeftString.isEmpty) {
  637. var string = KMWatermarkAdjectiveTools.parsePageFormat(formatString: model.topLeftString, startPage: model.startString, pageCount: "\(pageCount)")
  638. string = KMWatermarkAdjectiveTools.parseDateFormat(formatString: string)
  639. topLeftString = string
  640. }
  641. var topCenterString: String = ""
  642. if (!model.topCenterString.isEmpty) {
  643. var string = KMWatermarkAdjectiveTools.parsePageFormat(formatString: model.topCenterString, startPage: model.startString, pageCount: "\(pageCount)")
  644. string = KMWatermarkAdjectiveTools.parseDateFormat(formatString: string)
  645. topCenterString = string
  646. }
  647. var topRightString: String = ""
  648. if (!model.topRightString.isEmpty) {
  649. var string = KMWatermarkAdjectiveTools.parsePageFormat(formatString: model.topRightString, startPage: model.startString, pageCount: "\(pageCount)")
  650. string = KMWatermarkAdjectiveTools.parseDateFormat(formatString: string)
  651. topRightString = string
  652. }
  653. var bottomLeftString: String = ""
  654. if (!model.bottomLeftString.isEmpty) {
  655. var string = KMWatermarkAdjectiveTools.parsePageFormat(formatString: model.bottomLeftString, startPage: model.startString, pageCount: "\(pageCount)")
  656. string = KMWatermarkAdjectiveTools.parseDateFormat(formatString: string)
  657. bottomLeftString = string
  658. }
  659. var bottomCenterString: String = ""
  660. if (!model.bottomCenterString.isEmpty) {
  661. var string = KMWatermarkAdjectiveTools.parsePageFormat(formatString: model.bottomCenterString, startPage: model.startString, pageCount: "\(pageCount)")
  662. string = KMWatermarkAdjectiveTools.parseDateFormat(formatString: string)
  663. bottomCenterString = string
  664. }
  665. var bottomRightString: String = ""
  666. if (!model.bottomRightString.isEmpty) {
  667. var string = KMWatermarkAdjectiveTools.parsePageFormat(formatString: model.bottomRightString, startPage: model.startString, pageCount: "\(pageCount)")
  668. string = KMWatermarkAdjectiveTools.parseDateFormat(formatString: string)
  669. bottomRightString = string
  670. }
  671. return [topLeftString, topCenterString, topRightString, bottomLeftString, bottomCenterString, bottomRightString]
  672. }
  673. class func findPagesString(_ model: KMWatermarkAdjectiveBaseModel) -> String{
  674. if (model.pageRangeType == .all) { /// 全部页面
  675. return "0-\(model.pageCount-1)"
  676. } else if (model.pageRangeType == .odd) { /// 奇数页面
  677. var string: String = ""
  678. for i in 0 ..< model.pageCount {
  679. if (i % 2 == 1) {
  680. continue
  681. }
  682. string.append("\(i)")
  683. if (i != model.pageCount-1) {
  684. string.append(",")
  685. }
  686. }
  687. return string
  688. } else if (model.pageRangeType == .even) { /// 偶数页面
  689. var string: String = ""
  690. for i in 0 ..< model.pageCount {
  691. if (i % 2 == 0) {
  692. continue
  693. }
  694. string.append("\(i)")
  695. if (i != model.pageCount-1) {
  696. string.append(",")
  697. }
  698. }
  699. return string
  700. } else { /// 自定义
  701. return model.pageRangeString
  702. }
  703. }
  704. }