KMWatermarkModel.swift 28 KB

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