KMWatermarkAdjectiveTools.swift 34 KB

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