KMWatermarkModel.swift 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. //
  2. // KMWatermarkModel.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by tangchao on 2022/12/19.
  6. //
  7. import Cocoa
  8. @objcMembers class KMWatermarkModel: KMWatermarkAdjectiveBaseModel {
  9. var text: String = NSLocalizedString("Watermark", comment: "")
  10. var image: NSImage!
  11. var imagePath: String = ""
  12. var textAligement: NSTextAlignment = .left
  13. var rotation: CGFloat = 0.0
  14. var opacity: CGFloat = 1.0
  15. var scale: CGFloat = 1.0
  16. /**
  17. (Top:0 Middle:1 Bottom:2)
  18. */
  19. var verticalMode: Int = 1
  20. var verticalSpace: CGFloat = 0.0
  21. /**
  22. (Left:0 Middle:1 Right:2)
  23. */
  24. var horizontalMode: Int = 1
  25. var horizontalSpace: CGFloat = 0.0
  26. var tileHorizontalSpace: CGFloat = 60
  27. var tileVerticalSpace: CGFloat = 60
  28. var pagesString: String = ""
  29. var isFront: Bool = true
  30. var isTilePage: Bool = false
  31. var tag: String = ""
  32. var creatTemplateDate: String = ""
  33. var watermark: CPDFWatermark!
  34. var watermarkID: String = ""
  35. override func copy() -> Any {
  36. let model = KMWatermarkModel()
  37. model.text = self.text
  38. model.image = self.image
  39. model.imagePath = self.imagePath
  40. model.textColor = self.textColor
  41. model.textFont = self.textFont
  42. model.rotation = self.rotation
  43. model.opacity = self.opacity
  44. model.scale = self.scale
  45. model.verticalMode = self.verticalMode
  46. model.verticalSpace = self.verticalSpace
  47. model.horizontalMode = self.horizontalMode
  48. model.horizontalSpace = self.horizontalSpace
  49. model.tileHorizontalSpace = self.tileHorizontalSpace
  50. model.tileVerticalSpace = self.tileVerticalSpace
  51. model.pagesString = self.pagesString
  52. model.isFront = self.isFront
  53. model.isTilePage = self.isTilePage
  54. model.tag = self.tag
  55. model.pageRangeType = self.pageRangeType
  56. model.creatTemplateDate = self.creatTemplateDate
  57. model.watermark = self.watermark
  58. model.watermarkID = self.watermarkID
  59. return model
  60. }
  61. func updateData(document: CPDFDocument) {
  62. if (self.watermark == nil) {
  63. var scale: CGFloat = self.scale
  64. if (!self.text.isEmpty) {
  65. self.watermark = CPDFWatermark(document: document, type: .text)
  66. self.watermark.text = self.text
  67. self.watermark.textColor = self.getTextColor()
  68. scale = self.getTextFont().pointSize / 24.0
  69. } else {
  70. self.watermark = CPDFWatermark(document: document, type: .image)
  71. self.watermark.image = self.image
  72. }
  73. } else {
  74. if (!self.text.isEmpty) {
  75. self.watermark.text = self.text
  76. self.watermark.textColor = self.getTextColor()
  77. scale = self.getTextFont().pointSize / 24.0
  78. } else {
  79. self.watermark.image = self.image
  80. }
  81. }
  82. self.watermark.scale = scale
  83. self.watermark.rotation = -self.rotation
  84. self.watermark.opacity = self.opacity
  85. self.watermark.tx = self.horizontalSpace
  86. self.watermark.ty = self.verticalSpace
  87. self.watermark.isFront = self.isFront
  88. self.watermark.pageString = self.pagesString
  89. self.watermark.isTilePage = self.isTilePage
  90. self.watermark.horizontalSpacing = self.tileHorizontalSpace / scale
  91. self.watermark.verticalSpacing = self.tileVerticalSpace / scale
  92. if (self.verticalMode == 0) {
  93. self.watermark.verticalPosition = .top
  94. } else if (self.verticalMode == 1) {
  95. self.watermark.verticalPosition = .center
  96. } else if (self.verticalMode == 2) {
  97. self.watermark.verticalPosition = .bottom
  98. }
  99. if (self.horizontalMode == 0) {
  100. self.watermark.horizontalPosition = .left
  101. } else if (self.horizontalMode == 1) {
  102. self.watermark.horizontalPosition = .center
  103. } else if (self.horizontalMode == 2) {
  104. self.watermark.horizontalPosition = .right
  105. }
  106. }
  107. func drawImage(rect: CGRect) -> NSImage {
  108. var size: NSSize = NSZeroSize
  109. var drawRect: CGRect = NSMakeRect(0, 0, 128, 160)
  110. if (!self.text.isEmpty) {
  111. var font = NSFont.systemFont(ofSize: 48)
  112. if (self.isTilePage) {
  113. font = self.getTextFont()
  114. }
  115. var style = NSMutableParagraphStyle()
  116. style.alignment = self.textAligement
  117. style.lineBreakMode = .byCharWrapping
  118. let dictionary = [NSAttributedString.Key.paragraphStyle : style, NSAttributedString.Key.font : font]
  119. size = self.text.boundingRect(with: NSSize(width: 1000, height: 1000), options: NSString.DrawingOptions(rawValue: 3), attributes: dictionary).size
  120. } else if (self.image != nil) {
  121. size = self.image.size
  122. size.width = size.width * self.scale
  123. size.height = size.height * self.scale
  124. }
  125. let radian = self.rotation * (Double.pi/180.0)
  126. let t: CGAffineTransform = CGAffineTransform(rotationAngle: radian)
  127. if (!self.isTilePage) {
  128. drawRect = NSMakeRect(0, 0, size.width+40, size.height+40).applying(t);
  129. }
  130. let image = NSImage(size: drawRect.size)
  131. image.lockFocus()
  132. NSGraphicsContext.current?.imageInterpolation = .high
  133. NSGraphicsContext.saveGraphicsState()
  134. NSColor.clear.set()
  135. drawRect.fill()
  136. NSGraphicsContext.restoreGraphicsState()
  137. let context: CGContext = NSGraphicsContext.current!.cgContext
  138. let imageSize: NSSize = NSMakeSize(drawRect.size.width, drawRect.size.height)
  139. if (context != nil) {
  140. NSGraphicsContext.current = NSGraphicsContext(cgContext: context, flipped: false)
  141. }
  142. NSGraphicsContext.saveGraphicsState()
  143. if (!self.text.isEmpty) {
  144. var font = NSFont.systemFont(ofSize: 48)
  145. if (self.isTilePage) {
  146. font = self.getTextFont()
  147. }
  148. var color = NSColor.black
  149. if (self.textColor != nil) {
  150. color = self.getTextColor()
  151. }
  152. var red: CGFloat = 0
  153. var green: CGFloat = 0
  154. var blue: CGFloat = 0
  155. color.usingColorSpaceName(NSColorSpaceName.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: nil)
  156. color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: 1.0)
  157. var size = NSZeroSize
  158. let style = NSMutableParagraphStyle()
  159. style.alignment = self.textAligement
  160. style.lineBreakMode = .byCharWrapping
  161. let dictionary = [NSAttributedString.Key.paragraphStyle : style, NSAttributedString.Key.foregroundColor : color, NSAttributedString.Key.font : font]
  162. size = self.text.boundingRect(with: NSSize(width: 1000, height: 1000), options: NSString.DrawingOptions(rawValue: 3), attributes: dictionary).size
  163. let radian: CGFloat = self.rotation * (Double.pi / 180.0)
  164. let t: CGAffineTransform = CGAffineTransform(rotationAngle: radian)
  165. var textRect = NSMakeRect(0, 0, size.width, size.height).applying(t)
  166. if (self.isTilePage) {
  167. let width = sqrt(image.size.height * image.size.height + image.size.width * image.size.width)
  168. let newRect = NSMakeRect(-(width - image.size.width)/2, -(width - image.size.height)/2, width, width)
  169. let new_w = NSWidth(newRect)
  170. let new_h = NSHeight(newRect)
  171. context.translateBy(x: image.size.width/2,y: image.size.height/2);
  172. context.concatenate(t);
  173. context.translateBy(x: -(image.size.width/2), y: -(image.size.height/2));
  174. let verticalWidth: CGFloat = size.width + self.tileHorizontalSpace/3.0
  175. let horizontalHeight: CGFloat = size.height + self.tileVerticalSpace/3.0
  176. let line: Int = Int(((new_h - self.tileHorizontalSpace/3.0)/horizontalHeight) + 1)
  177. let row: Int = Int((new_w - self.tileVerticalSpace/3.0) / verticalWidth + 1)
  178. let point = NSPoint(x: image.size.width/2 - size.width/2+self.horizontalSpace/3.0, y: image.size.height/2 - size.height/2+self.verticalSpace/3.0)
  179. for i in 0 ..< line {
  180. for j in 0 ..< row {
  181. self.text.draw(in: NSRect(x: point.x+CGFloat(j)*verticalWidth, y: point.y+CGFloat(i)*horizontalHeight, width: size.width, height: size.height), withAttributes: dictionary)
  182. }
  183. }
  184. for i in 1 ..< line {
  185. for j in 0 ..< row {
  186. self.text.draw(in: NSRect(x: point.x+CGFloat(j)*verticalWidth, y: point.y-CGFloat(i)*horizontalHeight, width: size.width, height: size.height), withAttributes: dictionary)
  187. }
  188. }
  189. for i in 0 ..< line {
  190. for j in 1 ..< row {
  191. self.text.draw(in: NSRect(x: point.x-CGFloat(j)*verticalWidth, y: point.y+CGFloat(i)*horizontalHeight, width: size.width, height: size.height), withAttributes: dictionary)
  192. }
  193. }
  194. for i in 1 ..< line {
  195. for j in 1 ..< row {
  196. self.text.draw(in: NSRect(x: point.x-CGFloat(j)*verticalWidth, y: point.y-CGFloat(i)*horizontalHeight, width: size.width, height: size.height), withAttributes: dictionary)
  197. }
  198. }
  199. } else {
  200. if (self.verticalMode == 0) {
  201. textRect.origin.y = imageSize.height-textRect.size.height
  202. } else if (self.verticalMode == 1) {
  203. textRect.origin.y = (imageSize.height-textRect.size.height) * 0.5
  204. } else {
  205. textRect.origin.y = 0
  206. }
  207. if (self.horizontalMode == 0) {
  208. textRect.origin.x = 0
  209. } else if (self.horizontalMode == 1) {
  210. textRect.origin.x = (imageSize.width-textRect.size.width) * 0.5
  211. } else {
  212. textRect.origin.x = imageSize.width-textRect.size.width
  213. }
  214. textRect.origin.x += self.horizontalSpace
  215. textRect.origin.y += self.verticalSpace
  216. let contextCenter = CGPoint(x: textRect.midX, y: textRect.midY)
  217. context.translateBy(x: contextCenter.x, y: contextCenter.y)
  218. context.rotate(by: radian)
  219. context.translateBy(x: -contextCenter.x, y: -contextCenter.y)
  220. let testRect = NSMakeRect(textRect.origin.x+(textRect.size.width-size.width)/2.0,
  221. textRect.origin.y+(textRect.size.height-size.height)/2.0,
  222. size.width, size.height)
  223. self.text.draw(in: NSMakeRect(textRect.origin.x+(textRect.size.width-size.width)/2.0,
  224. textRect.origin.y+(textRect.size.height-size.height)/2.0,
  225. size.width, size.height), withAttributes: dictionary)
  226. }
  227. } else if (self.image != nil) {
  228. var size = self.image.size
  229. size.width *= self.scale
  230. size.height *= self.scale
  231. let width: CGFloat = sqrt(image.size.height * image.size.height + image.size.width * image.size.width)
  232. let newRect = NSMakeRect(-(width - image.size.width)/2, -(width - image.size.height)/2, width, width)
  233. let new_w = newRect.size.width
  234. let new_h = newRect.size.height
  235. let radian: CGFloat = self.rotation * (Double.pi / 180.0)
  236. let t: CGAffineTransform = CGAffineTransform(rotationAngle: radian)
  237. if (self.isTilePage) {
  238. context.translateBy(x: image.size.width/2,y: image.size.height/2)
  239. context.concatenate(t)
  240. context.translateBy(x: -(image.size.width/2), y: -(image.size.height/2))
  241. let verticalWidth: CGFloat = size.width + self.tileHorizontalSpace * self.scale
  242. let horizontalHeight: CGFloat = size.height + self.tileVerticalSpace * self.scale
  243. let line: Int = Int((new_h - self.tileVerticalSpace * self.scale) / horizontalHeight + 1)
  244. let row: Int = Int((new_w - self.tileHorizontalSpace * self.scale) / verticalWidth + 1)
  245. let point = NSPoint(x: image.size.width/2 - size.width/2+self.horizontalSpace*self.scale, y: image.size.height/2 - size.height/2+self.verticalSpace * self.scale)
  246. for i in 0 ..< (line/2+1) {
  247. for j in 0 ..< row {
  248. let area = CGRect(x: point.x + CGFloat(j) * verticalWidth, y: point.y + CGFloat(i)*horizontalHeight, width: size.width, height: size.height)
  249. self.image.draw(in: area, from: NSZeroRect, operation: .overlay, fraction: self.opacity)
  250. }
  251. }
  252. for i in 1 ..< (line/2+1) {
  253. for j in 0 ..< row {
  254. let area = CGRect(x: point.x + CGFloat(j) * verticalWidth, y: point.y - CGFloat(i)*horizontalHeight, width: size.width, height: size.height)
  255. self.image.draw(in: area, from: NSZeroRect, operation: .overlay, fraction: self.opacity)
  256. }
  257. }
  258. for i in 0 ..< (line/2+1) {
  259. for j in 1 ..< row {
  260. let area = CGRect(x: point.x - CGFloat(j) * verticalWidth, y: point.y + CGFloat(i)*horizontalHeight, width: size.width, height: size.height)
  261. self.image.draw(in: area, from: NSZeroRect, operation: .overlay, fraction: self.opacity)
  262. }
  263. }
  264. for i in 1 ..< (line/2+1) {
  265. for j in 1 ..< row {
  266. let area = CGRect(x: point.x - CGFloat(j) * verticalWidth, y: point.y - CGFloat(i)*horizontalHeight, width: size.width, height: size.height)
  267. self.image.draw(in: area, from: NSZeroRect, operation: .overlay, fraction: self.opacity)
  268. }
  269. }
  270. } else {
  271. var size = self.image.size
  272. size.width *= self.scale
  273. size.height *= self.scale
  274. let radian: CGFloat = self.rotation * (Double.pi / 180.0)
  275. let t: CGAffineTransform = CGAffineTransform(rotationAngle: radian)
  276. var imageRect = NSMakeRect(0, 0, size.width, size.height).applying(t)
  277. if (self.verticalMode == 0) {
  278. imageRect.origin.y = imageSize.height-imageRect.size.height
  279. } else if (self.verticalMode == 1) {
  280. imageRect.origin.y = (imageSize.height-imageRect.size.height) * 0.5
  281. } else {
  282. imageRect.origin.y = 0
  283. }
  284. if (self.horizontalMode == 0) {
  285. imageRect.origin.x = 0
  286. } else if (self.horizontalMode == 1) {
  287. imageRect.origin.x = (imageSize.width-imageRect.size.width) * 0.5
  288. } else {
  289. imageRect.origin.x = imageSize.width-imageRect.size.width
  290. }
  291. let contextCenter = CGPoint(x: rect.midX, y: rect.midY)
  292. context.translateBy(x: contextCenter.x, y: contextCenter.y)
  293. context.rotate(by: radian)
  294. context.translateBy(x: -contextCenter.x, y: -contextCenter.y)
  295. let finalRect = NSMakeRect(imageRect.origin.x+(imageRect.size.width-size.width)/2.0,
  296. imageRect.origin.y+(imageRect.size.height-size.height)/2.0,
  297. size.width, size.height)
  298. self.image.draw(in: finalRect, from: NSZeroRect, operation: .overlay, fraction: self.opacity)
  299. }
  300. }
  301. NSGraphicsContext.restoreGraphicsState()
  302. NSGraphicsContext.current?.imageInterpolation = .default
  303. image.unlockFocus()
  304. return image
  305. }
  306. class func drawImageAtpageRect(rect: NSRect, data: KMWatermarkModel) -> NSImage? {
  307. var size = NSZeroSize
  308. let text: String = data.text
  309. if text.count > 0 {
  310. var font = NSFont.systemFont(ofSize: 52)
  311. if data.isTilePage {
  312. font = NSFont.systemFont(ofSize: data.getTextFontSize())
  313. }
  314. let style = NSMutableParagraphStyle()
  315. style.alignment = .center
  316. style.lineBreakMode = .byCharWrapping
  317. let attributes: [NSAttributedString.Key: Any] = [ .paragraphStyle: style, .font: font ]
  318. size = text.boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude), options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: attributes).size
  319. } else if let image = data.image {
  320. size = image.size
  321. size.width *= data.scale
  322. size.height *= data.scale
  323. }
  324. let radian = data.rotation * (CGFloat.pi/180)
  325. let t = CGAffineTransform(rotationAngle: radian)
  326. var newRect = rect
  327. if !data.isTilePage {
  328. newRect = CGRectApplyAffineTransform(CGRect(x: 0, y: 0, width: size.width + 40, height: size.height + 40), t)
  329. }
  330. let image = NSImage(size: newRect.size)
  331. image.lockFocus()
  332. NSGraphicsContext.current?.imageInterpolation = .high
  333. NSGraphicsContext.saveGraphicsState()
  334. NSColor.clear.set()
  335. rect.fill()
  336. NSGraphicsContext.restoreGraphicsState()
  337. guard let context = NSGraphicsContext.current?.cgContext else { return nil }
  338. let imageSize = newRect.size
  339. NSGraphicsContext.current = NSGraphicsContext(cgContext: context, flipped: false)
  340. NSGraphicsContext.saveGraphicsState()
  341. if text.count > 0 {
  342. var font = NSFont.systemFont(ofSize: 52)
  343. if data.isTilePage {
  344. font = NSFont.systemFont(ofSize: data.getTextFontSize())
  345. }
  346. var color = data.getTextColor()
  347. var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0
  348. // color.usingColorSpace(NSColorSpace.rg)?.getRed(&red, green: &green, blue: &blue, alpha: nil)
  349. color.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: nil)
  350. color = NSColor.init(calibratedRed: red, green: green, blue: blue, alpha: data.opacity)
  351. size = .zero
  352. let alpha = data.opacity
  353. let tileHorizontalSpace = data.tileHorizontalSpace
  354. let tileVerticalSpace = data.tileVerticalSpace
  355. let horizontalSpace = data.horizontalSpace
  356. let verticalSpace = data.verticalSpace
  357. let style = NSMutableParagraphStyle()
  358. style.alignment = .center
  359. style.lineBreakMode = .byCharWrapping
  360. let attributes: [NSAttributedString.Key: Any] = [ .paragraphStyle: style, .foregroundColor: NSColor(calibratedRed: red, green: green, blue: blue, alpha: alpha), .font: font ]
  361. size = text.boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude), options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: attributes).size
  362. let textRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
  363. if data.isTilePage {
  364. let width = sqrt(image.size.height * image.size.height + image.size.width * image.size.width)
  365. let newRect = CGRect(x: -(width - image.size.width) / 2, y: -(width - image.size.height) / 2, width: width, height: width)
  366. let new_w = newRect.size.width
  367. let new_h = newRect.size.height
  368. context.translateBy(x: image.size.width / 2, y: image.size.height / 2)
  369. context.concatenate(CGAffineTransform(rotationAngle: radian))
  370. context.translateBy(x: -(image.size.width / 2), y: -(image.size.height / 2))
  371. let verticalWidth = size.width + tileHorizontalSpace / 3.0
  372. let horizontalHeight = size.height + tileVerticalSpace / 3.0
  373. let line: Int = Int((new_h - tileHorizontalSpace / 3.0) / horizontalHeight + 1)
  374. let row: Int = Int((new_w - tileVerticalSpace / 3.0) / verticalWidth + 1)
  375. let point = CGPoint(x: image.size.width / 2 - size.width / 2 + horizontalSpace / 3.0, y: image.size.height / 2 - size.height / 2 + verticalSpace / 3.0)
  376. for i in 0..<line {
  377. for j in 0..<row {
  378. let drawRect = CGRect(x: point.x + CGFloat(j) * verticalWidth, y: point.y + CGFloat(i) * horizontalHeight, width: size.width, height: size.height)
  379. text.draw(in: drawRect, withAttributes: attributes)
  380. }
  381. }
  382. for i in 1..<line {
  383. for j in 0..<row {
  384. let drawRect = CGRect(x: point.x + CGFloat(j) * verticalWidth, y: point.y - CGFloat(i) * horizontalHeight, width: size.width, height: size.height)
  385. text.draw(in: drawRect, withAttributes: attributes)
  386. }
  387. }
  388. for i in 0..<line {
  389. for j in 1..<row {
  390. let drawRect = CGRect(x: point.x - CGFloat(j) * verticalWidth, y: point.y + CGFloat(i) * horizontalHeight, width: size.width, height: size.height)
  391. text.draw(in: drawRect, withAttributes: attributes)
  392. }
  393. }
  394. for i in 1..<line {
  395. for j in 1..<row {
  396. let drawRect = CGRect(x: point.x - CGFloat(j) * verticalWidth, y: point.y - CGFloat(i) * horizontalHeight, width: size.width, height: size.height)
  397. text.draw(in: drawRect, withAttributes: attributes)
  398. }
  399. }
  400. } else {
  401. var textRect = textRect
  402. if data.verticalMode == 0 {
  403. textRect.origin.y = imageSize.height - textRect.size.height
  404. } else if data.verticalMode == 1 {
  405. textRect.origin.y = (imageSize.height - textRect.size.height) / 2.0
  406. } else {
  407. textRect.origin.y = 0
  408. }
  409. if data.horizontalMode == 0 {
  410. textRect.origin.x = 0
  411. } else if data.horizontalMode == 1{
  412. textRect.origin.x = (imageSize.width - textRect.size.width) / 2.0
  413. } else {
  414. textRect.origin.x = imageSize.width - textRect.size.width
  415. }
  416. let contextCenter = CGPoint(x: textRect.midX, y: textRect.midY)
  417. context.translateBy(x: contextCenter.x, y: contextCenter.y)
  418. context.rotate(by: radian)
  419. context.translateBy(x: -contextCenter.x, y: -contextCenter.y)
  420. data.text.draw(in: CGRect(x: textRect.origin.x + (textRect.size.width - size.width) / 2.0, y: textRect.origin.y + (textRect.size.height - size.height) / 2.0, width: size.width, height: size.height), withAttributes: attributes)
  421. }
  422. }else if let image = data.image {
  423. var size = image.size
  424. size.width *= data.scale
  425. size.height *= data.scale
  426. let width = sqrt(image.size.height * image.size.height + image.size.width * image.size.width)
  427. let newRect = CGRect(x: -(width - image.size.width)/2, y: -(width - image.size.height)/2, width: width, height: width)
  428. let new_w = newRect.size.width
  429. let new_h = newRect.size.height
  430. let radian = data.rotation * (CGFloat.pi / 180)
  431. let t = CGAffineTransform(rotationAngle: radian)
  432. if data.isTilePage {
  433. context.translateBy(x: image.size.width/2, y: image.size.height/2)
  434. context.concatenate(t)
  435. context.translateBy(x: -(image.size.width/2), y: -(image.size.height/2))
  436. let verticalWidth = size.width + data.tileHorizontalSpace * data.scale
  437. let horizontalHeight = size.height + data.tileVerticalSpace * data.scale
  438. let line: Int = Int((new_h - data.tileVerticalSpace * data.scale)/horizontalHeight + 1)
  439. let row: Int = Int((new_w - data.tileHorizontalSpace * data.scale) / verticalWidth + 1)
  440. let point = CGPoint(x: image.size.width/2 - size.width/2 + data.horizontalSpace*data.scale, y:image.size.height/2 - size.height/2 + data.verticalSpace * data.scale)
  441. for i in 0..<line/2+1 {
  442. for j in 0..<row {
  443. let area = CGRect(x: point.x + CGFloat(j) * verticalWidth, y: point.y + CGFloat(i) * horizontalHeight, width: size.width, height: size.height)
  444. data.image.draw(in: area, from: NSZeroRect, operation: .sourceOver, fraction: data.opacity)
  445. }
  446. }
  447. for i in 1..<line/2+1 {
  448. for j in 0..<row {
  449. let area = CGRect(x: point.x + CGFloat(j) * verticalWidth, y: point.y - CGFloat(i) * horizontalHeight, width: size.width, height: size.height)
  450. data.image.draw(in: area, from: NSZeroRect, operation: .sourceOver, fraction: data.opacity)
  451. }
  452. }
  453. for i in 0..<line/2+1 {
  454. for j in 1..<row {
  455. let area = CGRect(x: point.x - CGFloat(j) * verticalWidth, y: point.y + CGFloat(i) * horizontalHeight, width: size.width, height: size.height)
  456. data.image.draw(in: area, from: NSZeroRect, operation: .sourceOver, fraction: data.opacity)
  457. }
  458. }
  459. for i in 1..<(line/2 + 1) {
  460. for j in 1..<row {
  461. let area = CGRect(x: point.x - CGFloat(j)*verticalWidth, y: point.y - CGFloat(i)*horizontalHeight, width: size.width, height: size.height)
  462. data.image.draw(in: area, from: NSZeroRect, operation: .sourceOver, fraction: data.opacity)
  463. }
  464. }
  465. }else {
  466. var size = data.image.size
  467. size.width *= data.scale
  468. size.height *= data.scale
  469. let radian = data.rotation * (CGFloat.pi / 180)
  470. let t = CGAffineTransform(rotationAngle: radian)
  471. var imageRect = CGRect(origin: .zero, size: size).applying(t)
  472. if data.verticalMode == 0 {
  473. imageRect.origin.y = imageSize.height - imageRect.size.height
  474. } else if data.verticalMode == 1 {
  475. imageRect.origin.y = (imageSize.height - imageRect.size.height) / 2.0
  476. } else {
  477. imageRect.origin.y = 0
  478. }
  479. if data.horizontalMode == 0 {
  480. imageRect.origin.x = 0
  481. } else if data.horizontalMode == 1 {
  482. imageRect.origin.x = (imageSize.width - imageRect.size.width) / 2.0
  483. } else {
  484. imageRect.origin.x = imageSize.width - imageRect.size.width
  485. }
  486. let contextCenter = CGPoint(x: imageRect.midX, y: imageRect.midY)
  487. context.translateBy(x: contextCenter.x, y: contextCenter.y)
  488. context.rotate(by: radian)
  489. context.translateBy(x: -contextCenter.x, y: -contextCenter.y)
  490. data.image.draw(in: CGRect(x: imageRect.origin.x+(imageRect.size.width-size.width)/2.0, y: imageRect.origin.y+(imageRect.size.height-size.height)/2.0, width: size.width, height: size.height), from: NSZeroRect, operation: .sourceOver, fraction: data.opacity)
  491. }
  492. }
  493. NSGraphicsContext.restoreGraphicsState()
  494. NSGraphicsContext.current?.imageInterpolation = .default
  495. image.unlockFocus()
  496. return image
  497. }
  498. }