CPDFAddWatermarkViewController.swift 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. //
  2. // CPDFAddWatermarkViewController.swift
  3. // PDFViewer-Swift
  4. //
  5. // Copyright © 2014-2024 PDF Technologies, Inc. All Rights Reserved.
  6. //
  7. // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
  8. // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
  9. // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
  10. // This notice may not be removed from this file.
  11. //
  12. import UIKit
  13. import ComPDFKit
  14. @objc public protocol CPDFAddWatermarkViewControllerDelegate: AnyObject {
  15. @objc optional func addWatermarkViewControllerSave(_ addWatermarkViewControllerSave: CPDFAddWatermarkViewController, Text textWaterModel: CWatermarkModel)
  16. @objc optional func addWatermarkViewControllerSave(_ addWatermarkViewControllerSave: CPDFAddWatermarkViewController, Image imageWaterModel: CWatermarkModel)
  17. }
  18. public class CPDFAddWatermarkViewController: UIViewController, CPDFTextWatermarkSettingViewControllerDelegate, CPDFImageWatermarkSettingViewControllerDelegate {
  19. public weak var delegate: CPDFAddWatermarkViewControllerDelegate?
  20. private var segmentedControl: UISegmentedControl?
  21. private var fileURL: URL?
  22. private var preIamgeView: UIImageView?
  23. private var document: CPDFDocument?
  24. private var pageSize: CGSize = .zero
  25. private var page: CPDFPage?
  26. private var textWaterModel: CWatermarkModel?
  27. private var imageWaterModel: CWatermarkModel?
  28. var moveBeginCenter = CGPoint.zero
  29. var moveBeginPoint = CGPoint.zero
  30. var rotateBeginTransform = CGAffineTransform.identity
  31. var moveBeginFontSize: CGFloat = 0.0
  32. var moveRotateBeginCenter: CGPoint = .zero
  33. var moveBeginBounds: CGRect = .zero
  34. var initialAngle:CGFloat = 0.0
  35. private var textWatermarkPreView: CTextWatermarkPreView?
  36. private var imageWatermarkPreView: CImageWatermarkPreView?
  37. private var textWatermarkSettingViewController: CPDFTextWatermarkSettingViewController?
  38. private var imageWatermarkSettingViewController: CPDFImageWatermarkSettingViewController?
  39. deinit {
  40. #if DEBUG
  41. print("====CPDFAddWatermarkViewController==deinit")
  42. #endif
  43. }
  44. // MARK: - Init
  45. public init(fileURL: URL?, document: CPDFDocument?) {
  46. super.init(nibName: nil, bundle: nil)
  47. self.fileURL = fileURL
  48. self.document = document
  49. }
  50. required init?(coder: NSCoder) {
  51. fatalError("init(coder:) has not been implemented")
  52. }
  53. // MARK: - ViewController Methods
  54. public override func viewDidLoad() {
  55. super.viewDidLoad()
  56. // Do any additional setup after loading the view.
  57. initWitNavigation()
  58. page = document?.page(at: 0)
  59. pageSize = document?.pageSize(at: 0) ?? .zero
  60. textWatermarkPreView = CTextWatermarkPreView.init(frame: view.bounds, Image: page?.thumbnail(of: pageSize))
  61. imageWatermarkPreView = CImageWatermarkPreView.init(frame: view.bounds, Image: page?.thumbnail(of: pageSize))
  62. let image = UIImage(named: "CLog", in: Bundle(for: CImageWatermarkPreView.classForCoder()), compatibleWith: nil) ?? UIImage()
  63. imageWatermarkPreView?.preImageView?.image = imageWithImageSimple(image,scale: CGSize(width: 60, height: 60))
  64. imageWatermarkPreView?.preImageView?.sizeToFit()
  65. if imageWatermarkPreView != nil {
  66. view.addSubview(imageWatermarkPreView!)
  67. }
  68. if textWatermarkPreView != nil {
  69. view.addSubview(textWatermarkPreView!)
  70. }
  71. textWatermarkPreView?.isHidden = false
  72. imageWatermarkPreView?.isHidden = true
  73. createTextPreViewGestureRecognizer()
  74. createImagePreViewGestureRecognizer()
  75. initTextWaterModel()
  76. initImageWaterModel()
  77. textWatermarkSettingViewController = CPDFTextWatermarkSettingViewController(waterModel: textWaterModel)
  78. textWatermarkSettingViewController?.delegate = self
  79. if textWatermarkSettingViewController != nil {
  80. let presentationController = AAPLCustomPresentationController.init(presentedViewController: textWatermarkSettingViewController!, presenting: self)
  81. textWatermarkSettingViewController?.transitioningDelegate = presentationController
  82. self.present(textWatermarkSettingViewController!, animated: true)
  83. }
  84. }
  85. public override func viewWillLayoutSubviews() {
  86. textWatermarkPreView?.frame = view.bounds
  87. imageWatermarkPreView?.frame = view.bounds
  88. let multiple = min(view.bounds.size.width / pageSize.width, view.bounds.size.height / pageSize.height)
  89. textWatermarkPreView?.documentSize = CGSize(width: pageSize.width * multiple, height: pageSize.height * multiple)
  90. textWatermarkPreView?.setNeedsLayout()
  91. imageWatermarkPreView?.documentSize = CGSize(width: pageSize.width * multiple, height: pageSize.height * multiple)
  92. imageWatermarkPreView?.setNeedsLayout()
  93. var bounds = textWatermarkPreView?.preLabel?.bounds
  94. bounds = adaptWidth(with: (textWatermarkPreView?.preLabel)!, fontSize: textWaterModel?.watermarkScale ?? 0)
  95. textWatermarkPreView?.preLabel?.bounds = bounds ?? .zero
  96. }
  97. public override func viewWillAppear(_ animated: Bool) {
  98. super.viewWillAppear(animated)
  99. textWatermarkPreView?.setNeedsDisplay()
  100. imageWatermarkPreView?.setNeedsDisplay()
  101. }
  102. public override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
  103. textWatermarkPreView?.setNeedsDisplay()
  104. imageWatermarkPreView?.setNeedsDisplay()
  105. }
  106. // MARK: - Public Methods
  107. func showView() {
  108. buttonItemClicked_setting(UIButton())
  109. }
  110. // MARK: - Private Methods
  111. private func initTextWaterModel() {
  112. textWaterModel = CWatermarkModel()
  113. textWaterModel?.text = NSLocalizedString("Watermark", comment: "")
  114. textWaterModel?.watermarkScale = 24.0
  115. textWaterModel?.watermarkOpacity = 1.0
  116. textWaterModel?.isTile = false
  117. textWaterModel?.isFront = true
  118. textWaterModel?.textColor = .black
  119. textWaterModel?.fontName = "Helvetica"
  120. textWaterModel?.fontStyleName = "Regular"
  121. textWaterModel?.watermarkRotation = 0.0
  122. textWaterModel?.fileURL = fileURL
  123. textWaterModel?.horizontalSpacing = 30
  124. textWaterModel?.verticalSpacing = 30
  125. textWaterModel?.pageString = ""
  126. textTileViewRefresh()
  127. }
  128. private func initImageWaterModel() {
  129. imageWaterModel = CWatermarkModel()
  130. imageWaterModel?.watermarkScale = 24.0
  131. imageWaterModel?.watermarkOpacity = 1.0
  132. imageWaterModel?.isTile = false
  133. imageWaterModel?.isFront = true
  134. imageWaterModel?.watermarkRotation = 0.0
  135. imageWaterModel?.pageString = ""
  136. let image = UIImage(named: "CLog", in: Bundle(for: CImageWatermarkPreView.classForCoder()), compatibleWith: nil) ?? UIImage()
  137. imageWaterModel?.image = imageWithImageSimple(image,scale: CGSize(width: 60, height: 60))
  138. imageWaterModel?.fileURL = fileURL
  139. imageWaterModel?.horizontalSpacing = 30
  140. imageWaterModel?.verticalSpacing = 30
  141. imageWaterModel?.pageString = ""
  142. imageTileViewRefresh()
  143. }
  144. private func textTileViewRefresh() {
  145. textWatermarkPreView?.textTileView?.stransform = CGAffineTransform(rotationAngle: -(360.0-textWaterModel!.watermarkRotation)*CGFloat.pi/180.0)
  146. var red: CGFloat = 0
  147. var green: CGFloat = 0
  148. var blue: CGFloat = 0
  149. var alpha: CGFloat = 0
  150. textWaterModel?.textColor?.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
  151. textWatermarkPreView?.textTileView?.fontColor = UIColor(red: red, green: green, blue: blue, alpha: textWaterModel?.watermarkOpacity ?? 1)
  152. textWatermarkPreView?.textTileView?.fontSize = textWaterModel?.watermarkScale ?? 20.0
  153. textWatermarkPreView?.textTileView?.waterString = textWaterModel?.text
  154. textWatermarkPreView?.textTileView?.centerPoint = textWatermarkPreView?.preLabel?.center ?? .zero
  155. let familyName = textWaterModel?.fontName
  156. let styleName = textWaterModel?.fontStyleName
  157. textWatermarkPreView?.textTileView?.familyName = familyName
  158. textWatermarkPreView?.textTileView?.fontStyleName = styleName
  159. textWatermarkPreView?.textTileView?.setNeedsDisplay()
  160. }
  161. private func imageTileViewRefresh() {
  162. imageWatermarkPreView?.imageTileView?.stransform = CGAffineTransform(rotationAngle: -(360.0-imageWaterModel!.watermarkRotation)*CGFloat.pi/180.0)
  163. imageWatermarkPreView?.imageTileView?.waterImageView = imageWatermarkPreView?.preImageView
  164. imageWatermarkPreView?.imageTileView?.centerPoint = imageWatermarkPreView?.preImageView?.center ?? .zero
  165. imageWatermarkPreView?.imageTileView?.setNeedsDisplay()
  166. }
  167. private func initWitNavigation() {
  168. let backItem = UIBarButtonItem(image: UIImage(named: "CPDFViewImageBack", in: Bundle(for: CPDFAddWatermarkViewController.classForCoder()), compatibleWith: nil), style: .plain, target: self, action: #selector(buttonItemClicked_back(_:)))
  169. navigationItem.leftBarButtonItem = backItem
  170. let settingItem = UIBarButtonItem(image: UIImage(named: "CWatermarkNavigationSettingImage", in: Bundle(for: CPDFAddWatermarkViewController.classForCoder()), compatibleWith: nil), style: .plain, target: self, action: #selector(buttonItemClicked_setting(_:)))
  171. let saveIten = UIBarButtonItem(title: NSLocalizedString("Share", comment: ""), style: .plain, target: self, action: #selector(buttonItemClicked_save(_:)))
  172. var rightItems = [UIBarButtonItem]()
  173. rightItems.append(saveIten)
  174. rightItems.append(settingItem)
  175. navigationItem.rightBarButtonItems = rightItems
  176. let segmmentTitleArray = [NSLocalizedString("Text", comment: ""), NSLocalizedString("Image", comment: "")]
  177. segmentedControl = UISegmentedControl(items: segmmentTitleArray)
  178. if UIDevice.current.userInterfaceIdiom == .pad {
  179. segmentedControl?.frame = CGRect(x: 15, y: 44, width: self.view.frame.size.width - 400, height: 30)
  180. } else if UIDevice.current.userInterfaceIdiom == .phone {
  181. segmentedControl?.frame = CGRect(x: 15, y: 44, width: self.view.frame.size.width - 200, height: 30)
  182. }
  183. segmentedControl?.autoresizingMask = .flexibleWidth
  184. segmentedControl?.selectedSegmentIndex = 0
  185. segmentedControl?.autoresizingMask = [.flexibleWidth, .flexibleHeight]
  186. segmentedControl?.addTarget(self, action: #selector(segmentedControlValueChanged_type(_:)), for: .valueChanged)
  187. if segmentedControl != nil {
  188. navigationItem.titleView = self.segmentedControl!
  189. }
  190. }
  191. private func createTextPreViewGestureRecognizer() {
  192. textWatermarkPreView?.documentView?.isUserInteractionEnabled = true
  193. textWatermarkPreView?.preLabel?.isUserInteractionEnabled = true
  194. textWatermarkPreView?.rotationBtn?.isUserInteractionEnabled = true
  195. let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapWatermarkLabel(_:)))
  196. textWatermarkPreView?.preLabel?.addGestureRecognizer(tapGestureRecognizer)
  197. let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(panWatermarkLabel(_:)))
  198. textWatermarkPreView?.preLabel?.addGestureRecognizer(panRecognizer)
  199. let panRotationBtnRecognizer = UIPanGestureRecognizer(target: self, action: #selector(rotationWatermarkLabel(_:)))
  200. textWatermarkPreView?.rotationBtn?.addGestureRecognizer(panRotationBtnRecognizer)
  201. }
  202. private func createImagePreViewGestureRecognizer() {
  203. imageWatermarkPreView?.documentView?.isUserInteractionEnabled = true
  204. imageWatermarkPreView?.preImageView?.isUserInteractionEnabled = true
  205. imageWatermarkPreView?.rotationBtn?.isUserInteractionEnabled = true
  206. let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(panWatermarkImageView(_:)))
  207. imageWatermarkPreView?.preImageView?.addGestureRecognizer(panRecognizer)
  208. let panRotationBtnRecognizer = UIPanGestureRecognizer(target: self, action: #selector(rotationWatermarkImageView(_:)))
  209. imageWatermarkPreView?.rotationBtn?.addGestureRecognizer(panRotationBtnRecognizer)
  210. }
  211. private func imageWithImageSimple(_ image: UIImage) -> UIImage? {
  212. let multiple = max(image.size.width / 180, image.size.height / 240)
  213. let size = CGSize(width: image.size.width / multiple, height: image.size.height / multiple)
  214. UIGraphicsBeginImageContext(size)
  215. image.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
  216. let newImage = UIGraphicsGetImageFromCurrentImageContext()
  217. UIGraphicsEndImageContext()
  218. return newImage
  219. }
  220. private func imageWithImageSimple(_ image: UIImage, scale size: CGSize) -> UIImage? {
  221. UIGraphicsBeginImageContext(size)
  222. image.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
  223. let newImage = UIGraphicsGetImageFromCurrentImageContext()
  224. UIGraphicsEndImageContext()
  225. return newImage
  226. }
  227. func adaptWidth(with content: UILabel, fontSize: CGFloat) -> CGRect {
  228. if content.text == nil || content.text == "" {
  229. content.text = NSLocalizedString("", comment: "")
  230. }
  231. let fn = content.font.fontName
  232. let font = UIFont(name: fn, size: fontSize) ?? UIFont.systemFont(ofSize: fontSize)
  233. content.font = font
  234. let attributedString = NSAttributedString(string: content.text ?? "", attributes: [.font: font])
  235. var rectSize = attributedString.boundingRect(with: CGSize(width: 0, height: 0), options: .usesLineFragmentOrigin, context: nil)
  236. rectSize = CGRect(x: rectSize.origin.x, y: rectSize.origin.y, width: rectSize.size.width + 20, height: rectSize.size.height + 20)
  237. content.backgroundColor = .clear
  238. return rectSize
  239. }
  240. func distance(from point1: CGPoint, to point2: CGPoint) -> CGFloat {
  241. let dx = point2.x - point1.x
  242. let dy = point2.y - point1.y
  243. return sqrt(dx * dx + dy * dy)
  244. }
  245. func shareAction(url: URL?) {
  246. if (url != nil) {
  247. let activityVC = UIActivityViewController(activityItems: [url!], applicationActivities: nil)
  248. activityVC.definesPresentationContext = true
  249. if UI_USER_INTERFACE_IDIOM() == .pad {
  250. activityVC.popoverPresentationController?.sourceView = self.navigationController?.navigationBar ?? self.view
  251. let x = self.navigationController?.navigationBar.frame.width ?? 0
  252. let rect = CGRect(x: x, y: 0, width: 0, height: 0)
  253. activityVC.popoverPresentationController?.sourceRect = rect
  254. }
  255. self.present(activityVC, animated: true) {
  256. self.navigationController?.popViewController(animated: false)
  257. }
  258. activityVC.completionWithItemsHandler = { (activityType, completed, returnedItems, activityError) in
  259. if completed {
  260. print("Success!")
  261. } else {
  262. print("Failed Or Canceled!")
  263. }
  264. }
  265. }
  266. }
  267. // MARK: - Action
  268. @objc func buttonItemClicked_back(_ button: UIButton) {
  269. self.navigationController?.popViewController(animated: false)
  270. }
  271. @objc func buttonItemClicked_setting(_ button: UIButton) {
  272. if ((imageWatermarkSettingViewController?.view.superview) == nil) && ((textWatermarkSettingViewController?.view.superview) == nil) {
  273. if segmentedControl?.selectedSegmentIndex == 0 {
  274. textWatermarkSettingViewController = CPDFTextWatermarkSettingViewController(waterModel: textWaterModel)
  275. textWatermarkSettingViewController?.delegate = self
  276. let presentationController = AAPLCustomPresentationController.init(presentedViewController: textWatermarkSettingViewController!, presenting: self)
  277. textWatermarkSettingViewController!.transitioningDelegate = presentationController
  278. self.present(textWatermarkSettingViewController!, animated: true)
  279. } else if (segmentedControl?.selectedSegmentIndex == 1) {
  280. imageWatermarkSettingViewController = CPDFImageWatermarkSettingViewController(waterModel: imageWaterModel)
  281. imageWatermarkSettingViewController?.delegate = self
  282. let presentationController = AAPLCustomPresentationController.init(presentedViewController: imageWatermarkSettingViewController!, presenting: self)
  283. imageWatermarkSettingViewController!.transitioningDelegate = presentationController
  284. self.present(imageWatermarkSettingViewController!, animated: true)
  285. }
  286. }
  287. }
  288. @objc func buttonItemClicked_save(_ button: UIButton) {
  289. if (!(FileManager.default.fileExists(atPath: TEMPOARTFOLDER))) {
  290. try? FileManager.default.createDirectory(atPath: TEMPOARTFOLDER, withIntermediateDirectories: true, attributes: nil)
  291. }
  292. guard let lastPathComponent = self.document?.documentURL.deletingPathExtension().lastPathComponent else { return }
  293. let secPath = TEMPOARTFOLDER + "/" + lastPathComponent + "_Watermark.pdf"
  294. do {
  295. try FileManager.default.removeItem(atPath: secPath)
  296. } catch {
  297. // Handle the error, e.g., print an error message or perform other actions
  298. }
  299. let url = NSURL(fileURLWithPath: secPath) as URL
  300. self.document?.write(to: url)
  301. let waterDocument = CPDFDocument(url: url)
  302. if waterDocument?.isLocked == true {
  303. waterDocument?.unlock(withPassword: document?.password)
  304. }
  305. if segmentedControl?.selectedSegmentIndex == 0 {
  306. textWaterModel?.horizontalSpacing = 30.0 / (textWatermarkPreView?.documentView?.size.width ?? 0)
  307. textWaterModel?.verticalSpacing = 30.0 / (textWatermarkPreView?.documentView?.size.height ?? 0)
  308. let tx = (textWatermarkPreView?.preLabel?.centerX ?? 0) - ((textWatermarkPreView?.documentView?.size.width ?? 0) / 2)
  309. let ty = -((textWatermarkPreView?.preLabel?.centerY ?? 0) - ((textWatermarkPreView?.documentView?.size.height ?? 0) / 2))
  310. textWaterModel?.tx = tx / ((textWatermarkPreView?.documentView?.size.width ?? 0) / 2)
  311. textWaterModel?.ty = ty / ((textWatermarkPreView?.documentView?.size.height ?? 0) / 2)
  312. let page = waterDocument?.page(at: 0)
  313. let textWatermark = CPDFWatermark(document: waterDocument, type: .text)
  314. textWatermark?.text = textWaterModel?.text
  315. let familyName = textWaterModel?.fontName
  316. let styleName = textWaterModel?.fontStyleName
  317. let font = CPDFFont(familyName: familyName ?? "Helvetica", fontStyle: styleName ?? "")
  318. textWatermark?.cFont = font
  319. textWatermark?.fontSize = textWaterModel?.watermarkScale ?? 0
  320. textWatermark?.textColor = textWaterModel?.textColor
  321. textWatermark?.scale = (page?.size.width ?? 0) / (textWatermarkPreView?.documentView?.size.width ?? 24)
  322. textWatermark?.isTilePage = textWaterModel?.isTile ?? false
  323. textWatermark?.isFront = textWaterModel?.isFront ?? true
  324. textWatermark?.tx = (textWaterModel?.tx ?? 0) * ((page?.size.width ?? 0) / 2)
  325. textWatermark?.ty = (textWaterModel?.ty ?? 0) * ((page?.size.height ?? 0) / 2)
  326. textWatermark?.rotation = textWaterModel?.watermarkRotation ?? 0
  327. if textWaterModel?.pageString?.isEmpty == true {
  328. if let pageCount = waterDocument?.pageCount, pageCount > 1 {
  329. textWaterModel?.pageString = "0-\(pageCount - 1)"
  330. } else {
  331. textWaterModel?.pageString = "0"
  332. }
  333. }
  334. textWatermark?.pageString = textWaterModel?.pageString
  335. if textWatermark?.isTilePage == true {
  336. textWatermark?.verticalSpacing = (textWaterModel?.verticalSpacing ?? 0) * (page?.size.height ?? 0)
  337. textWatermark?.horizontalSpacing = (textWaterModel?.horizontalSpacing ?? 0) * (page?.size.width ?? 0)
  338. }
  339. waterDocument?.addWatermark(textWatermark)
  340. waterDocument?.write(to: url)
  341. shareAction(url: url)
  342. } else if segmentedControl?.selectedSegmentIndex == 1 {
  343. imageWaterModel?.horizontalSpacing = 30.0 / (imageWatermarkPreView?.documentView?.size.width ?? 0)
  344. imageWaterModel?.verticalSpacing = 30.0 / (imageWatermarkPreView?.documentView?.size.height ?? 0)
  345. let tx = (imageWatermarkPreView?.preImageView?.centerX ?? 0) - ((imageWatermarkPreView?.documentView?.size.width ?? 0) / 2)
  346. let ty = -((imageWatermarkPreView?.preImageView?.centerY ?? 0) - ((imageWatermarkPreView?.documentView?.size.height ?? 0) / 2))
  347. imageWaterModel?.tx = tx / ((imageWatermarkPreView?.documentView?.size.width ?? 0) / 2)
  348. imageWaterModel?.ty = ty / ((imageWatermarkPreView?.documentView?.size.height ?? 0) / 2)
  349. imageWaterModel?.watermarkScale = (imageWatermarkPreView?.preImageView?.frame.size.width ?? 0) / (imageWatermarkPreView?.documentView?.size.width ?? 0) / (imageWaterModel?.image?.size.width ?? 0)
  350. let page = waterDocument?.page(at: 0)
  351. let imageWatermark = CPDFWatermark(document: waterDocument, type: .image)
  352. imageWatermark?.image = imageWaterModel?.image
  353. imageWatermark?.scale = (imageWaterModel?.watermarkScale ?? 0) * (page?.size.width ?? 0)
  354. imageWatermark?.isTilePage = imageWaterModel?.isTile ?? false
  355. imageWatermark?.isFront = imageWaterModel?.isFront ?? true
  356. imageWatermark?.tx = (imageWaterModel?.tx ?? 0) * ((page?.size.width ?? 0) / 2)
  357. imageWatermark?.ty = (imageWaterModel?.ty ?? 0) * ((page?.size.height ?? 0) / 2)
  358. imageWatermark?.rotation = imageWaterModel?.watermarkRotation ?? 0
  359. if imageWaterModel?.pageString?.isEmpty == true {
  360. if let pageCount = waterDocument?.pageCount, pageCount > 1 {
  361. imageWaterModel?.pageString = "0-\(pageCount - 1)"
  362. } else {
  363. imageWaterModel?.pageString = "0"
  364. }
  365. }
  366. imageWatermark?.pageString = imageWaterModel?.pageString
  367. if imageWatermark?.isTilePage == true {
  368. imageWatermark?.verticalSpacing = (imageWaterModel?.verticalSpacing ?? 0) * (page?.size.height ?? 0)
  369. imageWatermark?.horizontalSpacing = (imageWaterModel?.horizontalSpacing ?? 0) * (page?.size.width ?? 0)
  370. }
  371. waterDocument?.addWatermark(imageWatermark)
  372. waterDocument?.write(to: url)
  373. shareAction(url: url)
  374. }
  375. }
  376. @objc func segmentedControlValueChanged_type(_ sender: UISegmentedControl) {
  377. if segmentedControl?.selectedSegmentIndex == 0 {
  378. if ((imageWatermarkSettingViewController?.view.superview) != nil) {
  379. imageWatermarkSettingViewController?.dismiss(animated: false)
  380. }
  381. textWatermarkPreView?.isHidden = false
  382. imageWatermarkPreView?.isHidden = true
  383. textWatermarkSettingViewController = CPDFTextWatermarkSettingViewController(waterModel: textWaterModel)
  384. textWatermarkSettingViewController?.delegate = self
  385. let presentationController = AAPLCustomPresentationController.init(presentedViewController: textWatermarkSettingViewController!, presenting: self)
  386. textWatermarkSettingViewController!.transitioningDelegate = presentationController
  387. self.present(textWatermarkSettingViewController!, animated: true)
  388. imageWatermarkPreView?.imageTileView?.isHidden = true
  389. if textWaterModel?.isTile == true {
  390. textWatermarkPreView?.textTileView?.isHidden = false
  391. } else {
  392. textWatermarkPreView?.textTileView?.isHidden = true
  393. }
  394. } else if segmentedControl?.selectedSegmentIndex == 1 {
  395. if ((textWatermarkSettingViewController?.view.superview) != nil) {
  396. textWatermarkSettingViewController?.dismiss(animated: false)
  397. }
  398. textWatermarkPreView?.isHidden = true
  399. imageWatermarkPreView?.isHidden = false
  400. imageWatermarkSettingViewController = CPDFImageWatermarkSettingViewController(waterModel: imageWaterModel)
  401. imageWatermarkSettingViewController?.delegate = self
  402. let presentationController = AAPLCustomPresentationController.init(presentedViewController: imageWatermarkSettingViewController!, presenting: self)
  403. imageWatermarkSettingViewController!.transitioningDelegate = presentationController
  404. self.present(imageWatermarkSettingViewController!, animated: true)
  405. textWatermarkPreView?.textTileView?.isHidden = true
  406. if imageWaterModel?.isTile == true {
  407. imageWatermarkPreView?.imageTileView?.isHidden = false
  408. } else {
  409. imageWatermarkPreView?.imageTileView?.isHidden = true
  410. }
  411. }
  412. }
  413. @objc func tapWatermarkLabel(_ recognizer: UITapGestureRecognizer) {
  414. let alertController = UIAlertController(title: NSLocalizedString("Text Watermark", comment: ""), message: NSLocalizedString("Type your watermark text here.", comment: ""), preferredStyle: .alert)
  415. alertController.addTextField { textField in
  416. textField.clearButtonMode = .always
  417. }
  418. alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: { actio in
  419. }))
  420. alertController.addAction(UIAlertAction(title: NSLocalizedString("Apply", comment: ""), style: .default, handler: { actio in
  421. if (alertController.textFields?.first?.text?.count ?? 0) > 0 {
  422. self.textWatermarkPreView?.preLabel?.text = alertController.textFields?.first?.text
  423. self.textWaterModel?.text = alertController.textFields?.first?.text
  424. self.textTileViewRefresh()
  425. self.textWatermarkPreView?.setNeedsDisplay()
  426. var bounds = self.textWatermarkPreView?.preLabel?.bounds
  427. bounds = self.adaptWidth(with: (self.textWatermarkPreView?.preLabel)!, fontSize: self.textWaterModel?.watermarkScale ?? 0)
  428. self.textWatermarkPreView?.preLabel?.bounds = bounds ?? .zero
  429. }
  430. }))
  431. self.present(alertController, animated: true)
  432. }
  433. @objc func panWatermarkLabel(_ recognizer: UIPanGestureRecognizer) {
  434. if textWaterModel?.isTile == true {
  435. return
  436. }
  437. let point = recognizer.translation(in: textWatermarkPreView?.documentView)
  438. let newX = (textWatermarkPreView?.preLabel?.center.x ?? 0) + point.x
  439. let newY = (textWatermarkPreView?.preLabel?.center.y ?? 0) + point.y
  440. let newPoint = CGPoint(x: newX, y: newY)
  441. if let documentView = textWatermarkPreView?.documentView, documentView.bounds.contains(newPoint) {
  442. textWatermarkPreView?.preLabel?.center = newPoint
  443. }
  444. recognizer.setTranslation(.zero, in: textWatermarkPreView?.documentView)
  445. textTileViewRefresh()
  446. self.textWatermarkPreView?.setNeedsDisplay()
  447. }
  448. @objc func panWatermarkImageView(_ recognizer: UIPanGestureRecognizer) {
  449. if imageWaterModel?.isTile == true {
  450. return
  451. }
  452. let point = recognizer.translation(in: imageWatermarkPreView?.documentView)
  453. let newX = (imageWatermarkPreView?.preImageView?.center.x ?? 0) + point.x
  454. let newY = (imageWatermarkPreView?.preImageView?.center.y ?? 0) + point.y
  455. let newPoint = CGPoint(x: newX, y: newY)
  456. if let documentView = imageWatermarkPreView?.documentView, documentView.bounds.contains(newPoint) {
  457. imageWatermarkPreView?.preImageView?.center = newPoint
  458. }
  459. recognizer.setTranslation(.zero, in: imageWatermarkPreView?.documentView)
  460. imageTileViewRefresh()
  461. imageWatermarkPreView?.setNeedsDisplay()
  462. }
  463. @objc func rotationWatermarkImageView(_ recognizer: UIPanGestureRecognizer) {
  464. guard let label = imageWatermarkPreView?.preImageView,
  465. let superview = imageWatermarkPreView?.documentView else {
  466. return
  467. }
  468. switch recognizer.state {
  469. case .began:
  470. let location = recognizer.location(in: superview)
  471. moveBeginPoint = location
  472. moveBeginCenter = imageWatermarkPreView?.preImageView?.center ?? .zero
  473. rotateBeginTransform = imageWatermarkPreView?.preImageView?.transform ?? .identity
  474. moveBeginBounds = imageWatermarkPreView?.preImageView?.bounds ?? .zero
  475. let dx = label.center.x - location.x
  476. let dy = label.center.y - location.y
  477. initialAngle = atan2(dy, dx)
  478. let angleDifference = initialAngle - atan2(label.transform.b, label.transform.a)
  479. label.transform = label.transform.rotated(by: angleDifference)
  480. case .changed:
  481. let location = recognizer.location(in: superview)
  482. let scale = distance(from: location, to: moveBeginCenter) / distance(from: moveBeginPoint, to: moveBeginCenter)
  483. var bounds = moveBeginBounds
  484. bounds.size.width = bounds.size.width * scale
  485. bounds.size.height = bounds.size.height * scale
  486. imageWatermarkPreView?.preImageView?.bounds = bounds
  487. imageWatermarkPreView?.setNeedsDisplay()
  488. let dx = label.center.x - location.x
  489. let dy = label.center.y - location.y
  490. let angle = atan2(dy, dx)
  491. label.transform = CGAffineTransform(rotationAngle: angle)
  492. imageWaterModel?.watermarkRotation = (angle) * 180 / CGFloat.pi
  493. imageTileViewRefresh()
  494. imageWatermarkPreView?.setNeedsDisplay()
  495. default:
  496. break
  497. }
  498. }
  499. @objc func rotationWatermarkLabel(_ recognizer: UIPanGestureRecognizer) {
  500. guard let label = textWatermarkPreView?.preLabel,
  501. let superview = textWatermarkPreView?.documentView else {
  502. return
  503. }
  504. switch recognizer.state {
  505. case .began:
  506. let location = recognizer.location(in: superview)
  507. moveBeginPoint = location
  508. moveBeginCenter = textWatermarkPreView?.preLabel?.center ?? .zero
  509. rotateBeginTransform = textWatermarkPreView?.preLabel?.transform ?? .identity
  510. moveBeginFontSize = textWatermarkPreView?.preLabel?.font.pointSize ?? 0
  511. let dx = label.center.x - location.x
  512. let dy = label.center.y - location.y
  513. initialAngle = atan2(dy, dx)
  514. let angleDifference = initialAngle - atan2(label.transform.b, label.transform.a)
  515. label.transform = label.transform.rotated(by: angleDifference)
  516. moveRotateBeginCenter = textWatermarkPreView?.rotationBtn?.center ?? .zero
  517. case .changed:
  518. let location = recognizer.location(in: superview)
  519. let scale = distance(from: location, to: moveBeginCenter) / distance(from: moveBeginPoint, to: moveBeginCenter)
  520. let fn = textWatermarkPreView?.preLabel?.font.fontName ?? "Helvetica"
  521. let font = UIFont(name: fn, size: moveBeginFontSize*scale)?.pointSize ?? 14
  522. if font < 14.0 {
  523. return
  524. }
  525. textWatermarkPreView?.preLabel?.font = UIFont(name: fn, size: moveBeginFontSize*scale)
  526. textWaterModel?.watermarkScale = textWatermarkPreView?.preLabel?.font.pointSize ?? 14
  527. textWatermarkPreView?.preLabel?.sizeToFit()
  528. textWatermarkPreView?.setNeedsDisplay()
  529. var bounds = textWatermarkPreView?.preLabel?.bounds
  530. bounds = adaptWidth(with: (textWatermarkPreView?.preLabel)!, fontSize: textWaterModel!.watermarkScale)
  531. textWatermarkPreView?.preLabel?.bounds = bounds!
  532. let dx = label.center.x - location.x
  533. let dy = label.center.y - location.y
  534. let angle = atan2(dy, dx)
  535. label.transform = CGAffineTransform(rotationAngle: angle)
  536. textWaterModel?.watermarkRotation = (angle) * 180 / CGFloat.pi
  537. textTileViewRefresh()
  538. self.textWatermarkPreView?.setNeedsDisplay()
  539. default:
  540. break
  541. }
  542. }
  543. // MARK: - CPDFTextWatermarkSettingViewControllerDelegate
  544. func textWatermarkSettingViewControllerSetting(_ textWatermarkSettingViewController: CPDFTextWatermarkSettingViewController, Color color: UIColor) {
  545. textWaterModel?.textColor = color
  546. textWatermarkPreView?.preLabel?.textColor = textWaterModel?.textColor
  547. textTileViewRefresh()
  548. }
  549. func textWatermarkSettingViewControllerSetting(_ textWatermarkSettingViewController: CPDFTextWatermarkSettingViewController, Opacity opacity: CGFloat) {
  550. textWaterModel?.watermarkOpacity = opacity
  551. textWatermarkPreView?.preLabel?.alpha = opacity
  552. textTileViewRefresh()
  553. }
  554. func textWatermarkSettingViewControllerSetting(_ textWatermarkSettingViewController: CPDFTextWatermarkSettingViewController, IsFront isFront: Bool) {
  555. textWaterModel?.isFront = isFront
  556. }
  557. func textWatermarkSettingViewControllerSetting(_ textWatermarkSettingViewController: CPDFTextWatermarkSettingViewController, IsTile isTile: Bool) {
  558. textWaterModel?.isTile = isTile
  559. textWatermarkPreView?.textTileView?.isHidden = !isTile
  560. }
  561. func textWatermarkSettingViewControllerSetting(_ textWatermarkSettingViewController: CPDFTextWatermarkSettingViewController, FamilyName familyName: String, FontStyleName styleName: String) {
  562. textWaterModel?.fontName = familyName
  563. textWaterModel?.fontStyleName = styleName
  564. let cFont = CPDFFont(familyName: familyName, fontStyle: styleName)
  565. textWatermarkPreView?.preLabel?.font = UIFont(name: CPDFFont.convertAppleFont(cFont) ?? "Helvetica", size: textWaterModel?.watermarkScale ?? 0)
  566. textTileViewRefresh()
  567. textWatermarkPreView?.setNeedsDisplay()
  568. var bounds = textWatermarkPreView?.preLabel?.bounds
  569. bounds = adaptWidth(with: (textWatermarkPreView?.preLabel)!, fontSize: textWaterModel?.watermarkScale ?? 0)
  570. textWatermarkPreView?.preLabel?.bounds = bounds ?? .zero
  571. }
  572. func textWatermarkSettingViewControllerSetting(_ textWatermarkSettingViewController: CPDFTextWatermarkSettingViewController, FontSize fontSize: CGFloat) {
  573. let familyName = textWaterModel?.fontName
  574. let styleName = textWaterModel?.fontStyleName
  575. let cFont = CPDFFont(familyName: familyName ?? "Helvetica", fontStyle: styleName ?? "")
  576. textWaterModel?.watermarkScale = fontSize
  577. textWatermarkPreView?.preLabel?.font = UIFont(name: CPDFFont.convertAppleFont(cFont) ?? "Helvetica", size: fontSize)
  578. textTileViewRefresh()
  579. textWatermarkPreView?.setNeedsDisplay()
  580. var bounds = textWatermarkPreView?.preLabel?.bounds
  581. bounds = adaptWidth(with: (textWatermarkPreView?.preLabel)!, fontSize: textWaterModel?.watermarkScale ?? 0)
  582. textWatermarkPreView?.preLabel?.bounds = bounds ?? .zero
  583. }
  584. func textWatermarkSettingViewControllerSetting(_ imageWatermarkSettingViewController: CPDFTextWatermarkSettingViewController, PageRange pageRange: String) {
  585. textWaterModel?.pageString = pageRange
  586. }
  587. // MARK: - CPDFImageWatermarkSettingViewControllerDelegate
  588. func imageWatermarkSettingViewControllerSetting(_ imageWatermarkSettingViewController: CPDFImageWatermarkSettingViewController, Image image: UIImage) {
  589. imageWatermarkPreView?.preImageView?.image = imageWithImageSimple(image)
  590. imageWatermarkPreView?.preImageView?.sizeToFit()
  591. imageWaterModel?.image = imageWithImageSimple(image)
  592. imageTileViewRefresh()
  593. imageWatermarkPreView?.setNeedsDisplay()
  594. }
  595. func imageWatermarkSettingViewControllerSetting(_ imageWatermarkSettingViewController: CPDFImageWatermarkSettingViewController, Opacity opacity: CGFloat) {
  596. imageWatermarkPreView?.preImageView?.alpha = opacity
  597. imageWaterModel?.watermarkOpacity = opacity
  598. imageTileViewRefresh()
  599. }
  600. func imageWatermarkSettingViewControllerSetting(_ imageWatermarkSettingViewController: CPDFImageWatermarkSettingViewController, IsTile isTile: Bool) {
  601. imageWaterModel?.isTile = isTile
  602. imageWatermarkPreView?.imageTileView?.isHidden = !isTile
  603. }
  604. func imageWatermarkSettingViewControllerSetting(_ imageWatermarkSettingViewController: CPDFImageWatermarkSettingViewController, IsFront isFront: Bool) {
  605. imageWaterModel?.isFront = isFront
  606. }
  607. func imageWatermarkSettingViewControllerSetting(_ imageWatermarkSettingViewController: CPDFImageWatermarkSettingViewController, PageRange pageRange: String) {
  608. imageWaterModel?.pageString = pageRange
  609. }
  610. }