KMMeasureSideVC.swift 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074
  1. //
  2. // KMMeasureSideVC.swift
  3. // Cisdem PDFMaster
  4. //
  5. // Created by wanjun on 2024/7/15.
  6. //
  7. import Cocoa
  8. private enum KMMeasureType: Int {
  9. case line = 0
  10. case multilines
  11. case polygon
  12. case rectangle
  13. }
  14. @objcMembers
  15. class KMMeasureSideVC: NSViewController {
  16. // Preview
  17. @IBOutlet private weak var previewImageBox: NSBox!
  18. @IBOutlet private weak var previewImageView: NSImageView!
  19. // Type
  20. @IBOutlet private weak var typeView: NSView!
  21. @IBOutlet private weak var typeSubView1: NSView!
  22. @IBOutlet private weak var typeButton1: NSButton!
  23. @IBOutlet private weak var typeSubView2: NSView!
  24. @IBOutlet private weak var typeButton2: NSButton!
  25. @IBOutlet private weak var typeSubView3: NSView!
  26. @IBOutlet private weak var typeButton3: NSButton!
  27. @IBOutlet private weak var typeSubView4: NSView!
  28. @IBOutlet private weak var typeButton4: NSButton!
  29. @IBOutlet private weak var verticalLine1: NSBox!
  30. @IBOutlet private weak var verticalLine2: NSBox!
  31. @IBOutlet private weak var verticalLine3: NSBox!
  32. @IBOutlet private weak var type_TopConstant: NSLayoutConstraint!
  33. // Border & Fill Color
  34. @IBOutlet private weak var fillColorView: NSView!
  35. @IBOutlet private weak var fillColorLabel: NSTextField!
  36. @IBOutlet private weak var fillColorPickerView: KMColorPickerView!
  37. @IBOutlet private weak var fillColorViewTopConstraint: NSLayoutConstraint!
  38. // Opacity
  39. @IBOutlet private weak var opacityView: NSView! // 透明度
  40. @IBOutlet private weak var opacityLabel: NSTextField!
  41. @IBOutlet private weak var opacitySlider: NSSlider!
  42. @IBOutlet private weak var opacityComboBox: KMComboBox!
  43. // Color
  44. @IBOutlet private weak var colorView: NSView! // 颜色
  45. @IBOutlet private weak var colorTitleLabel: NSTextField!
  46. @IBOutlet private weak var borderColorLabel: NSTextField!
  47. @IBOutlet private weak var borderColorBox: NSBox!
  48. @IBOutlet private weak var borderColorPickerView: KMColorPickerView!
  49. // Thickness
  50. @IBOutlet private weak var borderAndLineView: NSView! // 边框
  51. @IBOutlet private weak var borderLabel: NSTextField!
  52. @IBOutlet private weak var lineWidthSlider: NSSlider!
  53. @IBOutlet private weak var lineWidthComboBox: KMComboBox!
  54. // Line Style
  55. @IBOutlet private weak var lineStyle_View: NSView!
  56. @IBOutlet private weak var lineStyle_Label: NSTextField!
  57. @IBOutlet private weak var lineStyle_SolidButton: NSButton!
  58. @IBOutlet private weak var lineStyle_SolidImageView: NSImageView!
  59. @IBOutlet private weak var lineStyle_DottedButton: NSButton!
  60. @IBOutlet private weak var lineStyle_DottedImageView: NSImageView!
  61. @IBOutlet private weak var lineStyle_DashComBox: KMComboBox!
  62. @IBOutlet private weak var lineStyle_TopConstant: NSLayoutConstraint!
  63. // Start & End
  64. @IBOutlet private weak var startEnd_View: NSView!
  65. @IBOutlet private weak var startEnd_Label: NSTextField!
  66. @IBOutlet private weak var startEnd_StartPopUpButton: KMPopUpButton!
  67. @IBOutlet private weak var startEnd_EndPopUpButton: KMPopUpButton!
  68. @IBOutlet private weak var startEnd_TopConstant: NSLayoutConstraint!
  69. // Font
  70. @IBOutlet private weak var font_View: NSView!
  71. @IBOutlet private weak var font_Label: NSTextField!
  72. @IBOutlet private weak var font_PopUpButton: KMPopUpButton!
  73. @IBOutlet private weak var fontColorPickerView: KMColorPickerView!
  74. @IBOutlet private weak var font_StylePopUpButton: KMPopUpButton!
  75. @IBOutlet private weak var font_SizeComboBox: KMComboBox!
  76. var annotation: CPDFAnnotation?
  77. weak var pdfView: CPDFListView?
  78. var _annotationModel: CPDFAnnotationModel?
  79. var _annotations: [Any] = []
  80. private var measureType: KMMeasureType = .line
  81. deinit {
  82. NotificationCenter.default.removeObserver(self)
  83. borderColorPickerView.target = nil
  84. borderColorPickerView.action = nil
  85. fillColorPickerView.target = nil
  86. fillColorPickerView.action = nil
  87. fontColorPickerView.target = nil
  88. fontColorPickerView.action = nil
  89. NSColorPanel.shared.setTarget(nil)
  90. NSColorPanel.shared.setAction(nil)
  91. }
  92. override func viewDidLoad() {
  93. super.viewDidLoad()
  94. // Do view setup here.
  95. if annotationType == .line {
  96. if pdfView?.toolMode == .measureToolMode {
  97. measureType = .line
  98. }
  99. } else if annotationType == .square {
  100. if pdfView?.toolMode == .measureToolMode {
  101. measureType = .rectangle
  102. }
  103. } else if annotationType == .polyGon {
  104. measureType = .polygon
  105. } else if annotationType == .polyLine {
  106. measureType = .multilines
  107. }
  108. languageLocalization()
  109. uiInitialize()
  110. layoutConstraintRefresh()
  111. updateViewColor()
  112. DistributedNotificationCenter.default().addObserver(self, selector: #selector(themeChanged(notification:)), name: NSNotification.Name("AppleInterfaceThemeChangedNotification"), object: nil)
  113. }
  114. @objc func themeChanged(notification: NSNotification) {
  115. DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [self] in
  116. updateViewColor()
  117. }
  118. }
  119. // MARK: Privately Methods
  120. private func languageLocalization() -> Void {
  121. // if measureType == .polygon {
  122. // border_Label.stringValue = NSLocalizedString("Fill", comment: "")
  123. // } else {
  124. // border_Label.stringValue = NSLocalizedString("Border", comment: "")
  125. // }
  126. colorTitleLabel.stringValue = NSLocalizedString("Color", comment: "")
  127. borderColorLabel.stringValue = NSLocalizedString("Line Color", comment: "")
  128. fillColorLabel.stringValue = NSLocalizedString("Fill Color", comment: "")
  129. opacityLabel.stringValue = NSLocalizedString("Opacity", comment: "")
  130. borderLabel.stringValue = NSLocalizedString("Line", comment: "")
  131. lineStyle_Label.stringValue = NSLocalizedString("Line Style", comment: "")
  132. startEnd_Label.stringValue = NSLocalizedString("Start & End", comment: "")
  133. font_Label.stringValue = NSLocalizedString("Font", comment: "")
  134. }
  135. private func uiInitialize() -> Void {
  136. borderColorPickerView.annotationType = .lineColors
  137. fillColorPickerView.annotationType = .lineFillColors
  138. borderColorPickerView.isCallColorPanelAction = true
  139. fillColorPickerView.isCallColorPanelAction = true
  140. fontColorPickerView.annotationType = .freeTextColors
  141. fontColorPickerView.isCallColorPanelAction = true
  142. borderColorLabel.textColor = KMAppearance.Layout.h0Color()
  143. borderColorLabel.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
  144. fillColorLabel.textColor = KMAppearance.Layout.h0Color()
  145. fillColorLabel.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
  146. opacityLabel.textColor = KMAppearance.Layout.h0Color()
  147. opacityLabel.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
  148. borderLabel.textColor = KMAppearance.Layout.h0Color()
  149. borderLabel.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
  150. lineStyle_Label.textColor = KMAppearance.Layout.h0Color()
  151. lineStyle_Label.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
  152. startEnd_Label.textColor = KMAppearance.Layout.h0Color()
  153. startEnd_Label.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
  154. font_Label.textColor = KMAppearance.Layout.h0Color()
  155. font_Label.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
  156. opacityComboBox.type = .none
  157. opacityComboBox.comboxRect = opacityComboBox.bounds
  158. lineWidthComboBox.type = .none
  159. lineWidthComboBox.comboxRect = lineWidthComboBox.bounds
  160. lineStyle_DashComBox.type = .none
  161. lineStyle_DashComBox.comboxRect = lineStyle_DashComBox.bounds
  162. font_PopUpButton.type = .arrowDown
  163. font_PopUpButton.removeAllItems()
  164. font_PopUpButton.type = .arrowDown
  165. font_PopUpButton.removeAllItems()
  166. font_SizeComboBox.type = .none
  167. lineStyle_SolidImageView.image = NSImage(named: "KMImageNameLifeStyle")
  168. lineStyle_DottedImageView.image = NSImage(named: "KMImageNameLifeStyle2")
  169. lineStyle_DashComBox.isEnabled = false
  170. if annotationModel.dashPattern().count > 0 {
  171. lineStyle_DashComBox.stringValue = (annotationModel.dashPattern().first as! NSNumber).description
  172. } else {
  173. lineStyle_DashComBox.stringValue = "5"
  174. }
  175. annotationFontReload()
  176. if measureType == .line {
  177. previewImageView.image = NSImage(named: "ImageNameToolbarMeasureLine")
  178. startEnd_StartPopUpButton.type = .arrowDown
  179. startEnd_StartPopUpButton.removeAllItems()
  180. startEnd_EndPopUpButton.type = .arrowDown
  181. startEnd_EndPopUpButton.removeAllItems()
  182. let startMenu = NSMenu()
  183. _ = startMenu.addItem(withTitle: "", action: #selector(startMenuItemAction(_:)), target: self, tag: 0)
  184. _ = startMenu.addItem(withTitle: "", action: #selector(startMenuItemAction(_:)), target: self, tag: 1)
  185. _ = startMenu.addItem(withTitle: "", action: #selector(startMenuItemAction(_:)), target: self, tag: 2)
  186. _ = startMenu.addItem(withTitle: "", action: #selector(startMenuItemAction(_:)), target: self, tag: 3)
  187. _ = startMenu.addItem(withTitle: "", action: #selector(startMenuItemAction(_:)), target: self, tag: 4)
  188. _ = startMenu.addItem(withTitle: "", action: #selector(startMenuItemAction(_:)), target: self, tag: 5)
  189. startEnd_StartPopUpButton.menu = startMenu
  190. let endMenu = NSMenu()
  191. _ = endMenu.addItem(withTitle: "", action: #selector(endMenuItemAction(_:)), target: self, tag: 0)
  192. _ = endMenu.addItem(withTitle: "", action: #selector(endMenuItemAction(_:)), target: self, tag: 1)
  193. _ = endMenu.addItem(withTitle: "", action: #selector(endMenuItemAction(_:)), target: self, tag: 2)
  194. _ = endMenu.addItem(withTitle: "", action: #selector(endMenuItemAction(_:)), target: self, tag: 3)
  195. _ = endMenu.addItem(withTitle: "", action: #selector(endMenuItemAction(_:)), target: self, tag: 4)
  196. _ = endMenu.addItem(withTitle: "", action: #selector(endMenuItemAction(_:)), target: self, tag: 5)
  197. startEnd_EndPopUpButton.menu = endMenu
  198. let startPopMenu = startEnd_StartPopUpButton.menu
  199. let endPopMenu = startEnd_EndPopUpButton.menu
  200. let startLineStyle = annotationModel.startLineStyle()
  201. let endLineStyle = annotationModel.endLineStyle()
  202. let startArr = self.startLineStyle()
  203. let endArr = self.endLineStyle()
  204. for i in 0..<startArr.count {
  205. let item = startPopMenu!.item(withTag: i)
  206. item?.image = startArr[i]
  207. }
  208. for i in 0..<endArr.count {
  209. let item = endPopMenu!.item(withTag: i)
  210. item?.image = endArr[i]
  211. }
  212. if let line = annotation?.isKind(of: CPDFLineAnnotation.self), line {
  213. startEnd_StartPopUpButton.selectItem(at: (annotation as! CPDFLineAnnotation).startLineStyle.rawValue)
  214. startEnd_EndPopUpButton.selectItem(at: (annotation as! CPDFLineAnnotation).endLineStyle.rawValue)
  215. } else {
  216. startEnd_StartPopUpButton.selectItem(at: startLineStyle.rawValue)
  217. startEnd_EndPopUpButton.selectItem(at: endLineStyle.rawValue)
  218. }
  219. thicknessViewRefresh()
  220. } else if measureType == .multilines {
  221. previewImageView.image = NSImage(named: "ImageNameToolbarPolyline")
  222. thicknessViewRefresh()
  223. } else if measureType == .polygon {
  224. previewImageView.image = NSImage(named: "ImageNameToolbarPolygon")
  225. lineColorViewRefresh()
  226. thicknessViewRefresh()
  227. } else if measureType == .rectangle {
  228. previewImageView.image = NSImage(named: "ImageNameToolbarMeasureSquare")
  229. lineColorViewRefresh()
  230. }
  231. fontColorPickerView.color = annotationModel.fontColor()
  232. font_SizeComboBox.stringValue = String(format: "%.f pt", annotationModel.fontSize())
  233. borderColorViewRefresh()
  234. typeViewRefresh()
  235. opacityViewRefresh()
  236. lineStyleViewRefresh()
  237. }
  238. private func typeViewRefresh() -> Void {
  239. verticalLine1.isHidden = false
  240. verticalLine2.isHidden = false
  241. verticalLine3.isHidden = false
  242. typeSubView1.backgroundColor(.clear)
  243. typeSubView2.backgroundColor(.clear)
  244. typeSubView3.backgroundColor(.clear)
  245. typeSubView4.backgroundColor(.clear)
  246. typeButton1.image = NSImage(named: "ImageNameToolbarMeasureLine")
  247. typeButton2.image = NSImage(named: "ImageNameToolbarPolyline")
  248. typeButton3.image = NSImage(named: "ImageNameToolbarPolygon")
  249. typeButton4.image = NSImage(named: "ImageNameToolbarMeasureSquare")
  250. // typeButton1.isEnabled = false
  251. // typeButton2.isEnabled = false
  252. // typeButton3.isEnabled = false
  253. // typeButton4.isEnabled = false
  254. if measureType == .line {
  255. verticalLine1.isHidden = true
  256. typeSubView1.backgroundColor(NSColor.km_init(hex: "#477EDE", alpha: 0.1))
  257. typeButton1.isEnabled = true
  258. } else if measureType == .multilines {
  259. verticalLine1.isHidden = true
  260. verticalLine2.isHidden = true
  261. typeSubView2.backgroundColor(NSColor.km_init(hex: "#477EDE", alpha: 0.1))
  262. typeButton2.isEnabled = true
  263. } else if measureType == .polygon {
  264. verticalLine2.isHidden = true
  265. verticalLine3.isHidden = true
  266. typeSubView3.backgroundColor(NSColor.km_init(hex: "#477EDE", alpha: 0.1))
  267. typeButton3.isEnabled = false
  268. } else if measureType == .rectangle {
  269. verticalLine3.isHidden = true
  270. typeSubView4.backgroundColor(NSColor.km_init(hex: "#477EDE", alpha: 0.1))
  271. }
  272. }
  273. private func borderColorViewRefresh() -> Void {
  274. if measureType == .polygon || measureType == .rectangle {
  275. if annotation is CPDFPolygonAnnotation {
  276. let newAnnotation = (annotation as! CPDFPolygonAnnotation)
  277. borderColorPickerView.color = annotationModel.interiorColor()
  278. }
  279. } else {
  280. borderColorPickerView.color = annotationModel.color()
  281. }
  282. }
  283. private func lineColorViewRefresh() -> Void {
  284. fillColorPickerView.color = annotationModel.color()
  285. }
  286. private func fontColorViewRefresh() -> Void {
  287. fontColorPickerView.color = annotationModel.fontColor()
  288. }
  289. private func opacityViewRefresh() -> Void {
  290. opacitySlider.floatValue = Float(annotationModel.opacity())
  291. opacitySlider.toolTip = "\(Int(Float(annotationModel.opacity()) * 100))%"
  292. opacityComboBox.stringValue = "\(Int(Float(annotationModel.opacity()) * 100))%"
  293. }
  294. private func thicknessViewRefresh() -> Void {
  295. lineWidthSlider.floatValue = Float(annotationModel.lineWidth())
  296. lineWidthSlider.toolTip = "\(Int(Float(annotationModel.lineWidth())))"
  297. lineWidthComboBox.stringValue = "\(Int(Float(annotationModel.lineWidth())))"
  298. }
  299. private func lineStyleViewRefresh() -> Void {
  300. if annotationModel.style() == .solid {
  301. lineStyle_SolidButton.image = NSImage(named: "KMImageNameCheckboxRadiSel")
  302. lineStyle_DottedButton.image = NSImage(named: "KMImageNameCheckboxRadi")
  303. lineStyle_DashComBox.isEnabled = false
  304. } else {
  305. lineStyle_SolidButton.image = NSImage(named: "KMImageNameCheckboxRadi")
  306. lineStyle_DottedButton.image = NSImage(named: "KMImageNameCheckboxRadiSel")
  307. lineStyle_DashComBox.isEnabled = true
  308. }
  309. }
  310. private func layoutConstraintRefresh() -> Void {
  311. colorView.isHidden = false
  312. fillColorView.isHidden = false
  313. opacityView.isHidden = false
  314. borderAndLineView.isHidden = false
  315. lineStyle_View.isHidden = false
  316. startEnd_View.isHidden = false
  317. font_View.isHidden = false
  318. if measureType == .line {
  319. fillColorView.isHidden = true
  320. } else if measureType == .multilines {
  321. fillColorView.isHidden = true
  322. startEnd_View.isHidden = true
  323. } else if measureType == .polygon {
  324. startEnd_View.isHidden = true
  325. } else if measureType == .rectangle {
  326. startEnd_View.isHidden = true
  327. }
  328. fillColorViewTopConstraint.constant = !fillColorView.isHidden ? 92.0 : 10.0
  329. lineStyle_TopConstant.constant = !lineStyle_View.isHidden ? 0.0 : -CGRectGetHeight(lineStyle_View.bounds)
  330. startEnd_TopConstant.constant = !startEnd_View.isHidden ? 0.0 : -CGRectGetHeight(startEnd_View.bounds)
  331. }
  332. private func setFontStyle(fontName: String, currentStyle style: String?) -> UInt {
  333. var selectIndex: UInt = 0
  334. let menu = NSMenu()
  335. let fontStyleNames = CPDFFont.fontNames(forFamilyName: fontName)
  336. for i in 0..<fontStyleNames.count {
  337. let styleName = fontStyleNames[i]
  338. if style == styleName {
  339. selectIndex = UInt(i)
  340. }
  341. // let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: fontName, NSFontDescriptor.AttributeName.face: styleName])
  342. // let font = NSFont(descriptor: attributeFontDescriptor, size: 12.0)
  343. // let attrited = [NSAttributedString.Key.font: font]
  344. // let string = NSAttributedString(string: styleName, attributes: attrited as [NSAttributedString.Key : Any])
  345. //
  346. // let item = NSMenuItem()
  347. // item.attributedTitle = string
  348. let item = NSMenuItem()
  349. item.title = styleName
  350. menu.addItem(item)
  351. }
  352. if style == nil {
  353. selectIndex = 0
  354. }
  355. font_StylePopUpButton.menu = menu
  356. return selectIndex
  357. }
  358. private func annotationFontReload() {
  359. DispatchQueue.global(qos: .default).async { [weak self] in
  360. guard let self = self else { return }
  361. let fonts = CPDFFont.familyNames
  362. let menu = NSMenu()
  363. var selectedIndex = 0
  364. for (index, fontName) in fonts.enumerated() {
  365. if let font = NSFont(name: fontName, size: 12.0) {
  366. let attributedString = NSAttributedString(string: fontName, attributes: [.font: font])
  367. let item = NSMenuItem()
  368. item.attributedTitle = attributedString
  369. menu.addItem(item)
  370. if [.line, .polyGon, .polyLine, .square].contains(self.annotationType),
  371. let modelFontName = self.annotationModel.fontName(),
  372. modelFontName == font.fontName {
  373. selectedIndex = index
  374. }
  375. }
  376. }
  377. if [.line, .polyGon, .polyLine, .square].contains(self.annotationType),
  378. let data = self.annotationModel.fontName() {
  379. let freetextFont = NSFont(name: data, size: 16) ?? NSFont.systemFont(ofSize: 16)
  380. if let family = freetextFont.fontDescriptor.object(forKey: .family) as? String,
  381. let style = freetextFont.fontDescriptor.object(forKey: .face) as? String {
  382. DispatchQueue.main.async { [weak self] in
  383. guard let self = self else { return }
  384. self.font_PopUpButton.menu = menu
  385. self.font_PopUpButton.selectItem(at: selectedIndex)
  386. let selectedStyleIndex = self.setFontStyle(fontName: family, currentStyle: style)
  387. self.font_StylePopUpButton.selectItem(at: Int(selectedStyleIndex))
  388. }
  389. }
  390. }
  391. }
  392. }
  393. @IBAction private func colorPanelAction1(_ sender: NSButton) {
  394. if measureType == .polygon || measureType == .rectangle {
  395. for tAnnotation in annotations {
  396. if tAnnotation is CPDFPolygonAnnotation {
  397. let newAnnotation = (tAnnotation as! CPDFPolygonAnnotation)
  398. newAnnotation.interiorColor = NSColorPanel.shared.color
  399. }
  400. }
  401. } else {
  402. annotationModel.setColor(NSColorPanel.shared.color)
  403. }
  404. borderColorViewRefresh()
  405. updateAnnotation()
  406. }
  407. @IBAction private func colorPanelAction2(_ sender: NSButton) {
  408. lineColorViewRefresh()
  409. annotationModel.setInteriorColor(NSColorPanel.shared.color)
  410. updateAnnotation()
  411. }
  412. @IBAction private func colorPanelAction3(_ sender: NSButton) {
  413. fontColorViewRefresh()
  414. annotationModel.setFontColor(NSColorPanel.shared.color)
  415. updateAnnotation()
  416. }
  417. func updateViewColor() {
  418. if KMAppearance.isDarkMode() {
  419. let darkColor = NSColor(red: 57/255.0, green: 60/255.0, blue: 62/255.0, alpha: 1.0).cgColor
  420. let borderColor = NSColor(red: 86/255.0, green: 88/255.0, blue: 90/255.0, alpha: 1.0).cgColor
  421. setViewColor(font_PopUpButton, darkColor, borderColor)
  422. setViewColor(font_SizeComboBox, darkColor, borderColor)
  423. setViewColor(font_StylePopUpButton, darkColor, borderColor)
  424. setViewColor(lineWidthComboBox, darkColor, borderColor)
  425. setViewColor(opacityComboBox, darkColor, borderColor)
  426. setViewColor(opacityComboBox, darkColor, borderColor)
  427. } else {
  428. let lightColor = NSColor.white.cgColor
  429. let borderColor = NSColor(red: 218/255.0, green: 219/255.0, blue: 222/255.0, alpha: 1.0).cgColor
  430. setViewColor(font_PopUpButton, lightColor, borderColor)
  431. setViewColor(font_SizeComboBox, lightColor, borderColor)
  432. setViewColor(font_StylePopUpButton, lightColor, borderColor)
  433. setViewColor(lineWidthComboBox, lightColor, borderColor)
  434. setViewColor(opacityComboBox, lightColor, borderColor)
  435. setViewColor(opacityComboBox, lightColor, borderColor)
  436. }
  437. }
  438. func setViewColor(_ view: NSView, _ backgroundColor: CGColor, _ borderColor: CGColor) {
  439. view.wantsLayer = true
  440. view.layer?.backgroundColor = backgroundColor
  441. view.layer?.borderColor = borderColor
  442. }
  443. private func updateAnnotation() {
  444. if annotationModel.annotation != nil {
  445. for tAnnotation in annotations {
  446. pdfView?.setNeedsDisplayAnnotationViewFor((tAnnotation as AnyObject).page)
  447. }
  448. }
  449. }
  450. private func startLineStyle() -> [NSImage] {
  451. let size = NSSize(width: 100.0, height: 12.0)
  452. let image1 = NSImage.image(with: size) { rect in
  453. let path = NSBezierPath()
  454. path.move(to: NSPoint(x: 93.0, y: 6.0))
  455. path.line(to: NSPoint(x: 6.0, y: 6.0))
  456. path.lineWidth = 2.0
  457. NSColor.labelColor.setStroke()
  458. path.stroke()
  459. return true
  460. }
  461. let image2 = NSImage.image(with: size) { dstRect in
  462. let path = NSBezierPath()
  463. path.move(to: NSPoint(x: 93.0, y: 6.0))
  464. path.line(to: NSPoint(x: 12.0, y: 6.0))
  465. path.appendRect(NSRect(x: 6.0, y: 3.0, width: 6.0, height: 6.0))
  466. path.lineWidth = 2.0
  467. NSColor.labelColor.setStroke()
  468. path.stroke()
  469. return true
  470. }
  471. let image3 = NSImage.image(with: size) { dstRect in
  472. let path = NSBezierPath()
  473. path.move(to: NSPoint(x: 93.0, y: 6.0))
  474. path.line(to: NSPoint(x: 12.0, y: 6.0))
  475. path.appendOval(in: NSRect(x: 6.0, y: 3.0, width: 6.0, height: 6.0))
  476. path.lineWidth = 2.0
  477. NSColor.labelColor.setStroke()
  478. path.stroke()
  479. return true
  480. }
  481. let image4 = NSImage.image(with: size) { dstRect in
  482. let path = NSBezierPath()
  483. path.move(to: NSPoint(x: 93.0, y: 6.0))
  484. path.line(to: NSPoint(x: 14.0, y: 6.0))
  485. path.move(to: NSPoint(x: 14.0, y: 6.0))
  486. path.line(to: NSPoint(x: 10.0, y: 10.0))
  487. path.line(to: NSPoint(x: 6.0, y: 6.0))
  488. path.line(to: NSPoint(x: 10.0, y: 2.0))
  489. path.close()
  490. NSColor.labelColor.setStroke()
  491. path.lineWidth = 2.0
  492. path.stroke()
  493. return true
  494. }
  495. let image5 = NSImage.image(with: size) { dstRect in
  496. let path = NSBezierPath()
  497. path.move(to: NSPoint(x: 93.0, y: 6.0))
  498. path.line(to: NSPoint(x: 6.0, y: 6.0))
  499. path.move(to: NSPoint(x: 15.0, y: 3.0))
  500. path.line(to: NSPoint(x: 6.0, y: 6.0))
  501. path.line(to: NSPoint(x: 15.0, y: 9.0))
  502. path.lineWidth = 2.0
  503. NSColor.labelColor.setStroke()
  504. path.stroke()
  505. return true
  506. }
  507. let image6 = NSImage.image(with: size) { dstRect in
  508. let path = NSBezierPath()
  509. path.move(to: NSPoint(x: 93.0, y: 6.0))
  510. path.line(to: NSPoint(x: 6.0, y: 6.0))
  511. path.move(to: NSPoint(x: 15.0, y: 3.0))
  512. path.line(to: NSPoint(x: 6.0, y: 6.0))
  513. path.line(to: NSPoint(x: 15.0, y: 9.0))
  514. path.close()
  515. path.lineWidth = 2.0
  516. NSColor.labelColor.setStroke()
  517. path.stroke()
  518. return true
  519. }
  520. return [image1, image5, image6, image2, image3, image4]
  521. }
  522. private func endLineStyle() -> [NSImage] {
  523. let size = NSSize(width: 100.0, height: 12.0)
  524. let image1 = NSImage.image(with: size) { rect in
  525. let path = NSBezierPath()
  526. path.move(to: NSPoint(x: 6.0, y: 6.0))
  527. path.line(to: NSPoint(x: 93.0, y: 6.0))
  528. path.lineWidth = 2.0
  529. NSColor.labelColor.setStroke()
  530. path.stroke()
  531. return true
  532. }
  533. let image2 = NSImage.image(with: size) { rect in
  534. let path = NSBezierPath()
  535. path.move(to: NSPoint(x: 6.0, y: 6.0))
  536. path.line(to: NSPoint(x: 87.0, y: 6.0))
  537. path.appendRect(NSRect(x: 87.0, y: 3.0, width: 6.0, height: 6.0))
  538. path.lineWidth = 2.0
  539. NSColor.labelColor.setStroke()
  540. path.stroke()
  541. return true
  542. }
  543. let image3 = NSImage.image(with: size) { rect in
  544. let path = NSBezierPath()
  545. path.move(to: NSPoint(x: 6.0, y: 6.0))
  546. path.line(to: NSPoint(x: 87.0, y: 6.0))
  547. path.appendOval(in: NSRect(x: 87.0, y: 3.0, width: 6.0, height: 6.0))
  548. path.lineWidth = 2.0
  549. NSColor.labelColor.setStroke()
  550. path.stroke()
  551. return true
  552. }
  553. let image4 = NSImage.image(with: size) { rect in
  554. let path = NSBezierPath()
  555. path.move(to: NSPoint(x: 6.0, y: 6.0))
  556. path.line(to: NSPoint(x: 87.0, y: 6.0))
  557. path.move(to: NSPoint(x: 87.0, y: 6.0))
  558. path.line(to: NSPoint(x: 91.0, y: 10.0))
  559. path.line(to: NSPoint(x: 95.0, y: 6.0))
  560. path.line(to: NSPoint(x: 91.0, y: 2.0))
  561. path.close()
  562. NSColor.labelColor.setStroke()
  563. path.lineWidth = 2.0
  564. path.stroke()
  565. return true
  566. }
  567. let image5 = NSImage.image(with: size) { rect in
  568. let path = NSBezierPath()
  569. path.move(to: NSPoint(x: 6.0, y: 6.0))
  570. path.line(to: NSPoint(x: 93.0, y: 6.0))
  571. path.move(to: NSPoint(x: 84.0, y: 3.0))
  572. path.line(to: NSPoint(x: 93.0, y: 6.0))
  573. path.line(to: NSPoint(x: 84.0, y: 9.0))
  574. path.lineWidth = 2.0
  575. NSColor.labelColor.setStroke()
  576. path.stroke()
  577. return true
  578. }
  579. let image6 = NSImage.image(with: size) { rect in
  580. let path = NSBezierPath()
  581. path.move(to: NSPoint(x: 6.0, y: 6.0))
  582. path.line(to: NSPoint(x: 93.0, y: 6.0))
  583. path.move(to: NSPoint(x: 84.0, y: 3.0))
  584. path.line(to: NSPoint(x: 93.0, y: 6.0))
  585. path.line(to: NSPoint(x: 84.0, y: 9.0))
  586. path.close()
  587. path.lineWidth = 2.0
  588. NSColor.labelColor.setStroke()
  589. path.stroke()
  590. return true
  591. }
  592. return [image1, image5, image6, image2, image3, image4]
  593. }
  594. private func isNumericUsingNSRegularExpression(_ input: String) -> Bool {
  595. let pattern = "^[0-9]+$"
  596. do {
  597. let regex = try NSRegularExpression(pattern: pattern)
  598. let matches = regex.matches(in: input, range: NSRange(location: 0, length: input.utf16.count))
  599. return matches.count > 0
  600. } catch {
  601. print("Invalid regex pattern")
  602. return false
  603. }
  604. }
  605. // MARK: Publicly Methods
  606. // MARK: Action
  607. @IBAction func typeButtonAction(_ sender: NSButton) {
  608. }
  609. @IBAction func borderColorPickerViewAction(_ sender: Any) {
  610. var fillColor = NSColor.clear
  611. var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
  612. if let borderColor = borderColorPickerView.color {
  613. borderColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  614. let color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: opacity)
  615. fillColor = color
  616. }
  617. if measureType == .polygon || measureType == .rectangle {
  618. annotationModel.setInteriorColor(fillColor)
  619. annotationModel.setOpacity(opacity)
  620. } else {
  621. annotationModel.setColor(fillColor)
  622. }
  623. annotationModel.setOpacity(opacity)
  624. opacityViewRefresh()
  625. updateAnnotation()
  626. }
  627. @IBAction func fillColorPickerViewAction(_ sender: Any) {
  628. var fillColor = NSColor.clear
  629. var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
  630. if let borderColor = fillColorPickerView.color {
  631. borderColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  632. let color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: opacity)
  633. fillColor = color
  634. }
  635. if measureType == .polygon || measureType == .rectangle {
  636. for tAnnotation in annotations {
  637. if tAnnotation is CPDFPolygonAnnotation {
  638. if opacity == 0 {
  639. annotationModel.setInteriorMesColor(nil)
  640. } else {
  641. annotationModel.setInteriorMesColor(fillColor)
  642. }
  643. let newAnnotation = (tAnnotation as! CPDFPolygonAnnotation)
  644. newAnnotation.interiorOpacity = opacity
  645. }
  646. }
  647. }
  648. opacityViewRefresh()
  649. lineColorViewRefresh()
  650. updateAnnotation()
  651. }
  652. @IBAction func fontColorPickerViewAction(_ sender: Any) {
  653. var fillColor = NSColor.clear
  654. var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
  655. if let borderColor = fillColorPickerView.color {
  656. borderColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  657. let color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: opacity)
  658. fillColor = color
  659. }
  660. fontColorViewRefresh()
  661. annotationModel.setFontColor(fillColor)
  662. updateAnnotation()
  663. }
  664. @IBAction func customColorAction(_ sender: NSButton) {
  665. NSColorPanel.shared.setAction(nil)
  666. NSColorPanel.shared.setTarget(nil)
  667. NSColorPanel.shared.setTarget(self)
  668. NSColorPanel.shared.showsAlpha = true
  669. if sender.tag == 0 {
  670. NSColorPanel.shared.setAction(#selector(colorPanelAction1(_:)))
  671. } else if sender.tag == 1 {
  672. NSColorPanel.shared.setAction(#selector(colorPanelAction2(_:)))
  673. } else if sender.tag == 2 {
  674. NSColorPanel.shared.setAction(#selector(colorPanelAction3(_:)))
  675. }
  676. NSColorPanel.shared.orderFront(nil)
  677. }
  678. @IBAction func opacitySliderAction(_ sender: Any) {
  679. var opcity = CGFloat(opacitySlider.floatValue)
  680. if opcity == 0 {
  681. opcity = 0.0001
  682. }
  683. annotationModel.setOpacity(opcity)
  684. opacityViewRefresh()
  685. updateAnnotation()
  686. }
  687. @IBAction func opacityComboBoxAction(_ sender: Any) {
  688. opacitySlider.floatValue = Float(opacityComboBox.floatValue / 100)
  689. var opcity = CGFloat(opacitySlider.floatValue)
  690. if opcity == 0 {
  691. opcity = 0.0001
  692. }
  693. annotationModel.setOpacity(opcity)
  694. opacityViewRefresh()
  695. updateAnnotation()
  696. }
  697. @IBAction func thicknessSliderAction(_ sender: Any) {
  698. let thickness = CGFloat(lineWidthSlider.floatValue)
  699. annotationModel.setLineWidth(thickness)
  700. thicknessViewRefresh()
  701. updateAnnotation()
  702. }
  703. @IBAction func thicknessComboBoxAction(_ sender: Any) {
  704. lineWidthSlider.floatValue = Float(lineWidthComboBox.floatValue)
  705. let thickness = CGFloat(lineWidthSlider.floatValue)
  706. annotationModel.setLineWidth(thickness)
  707. thicknessViewRefresh()
  708. updateAnnotation()
  709. }
  710. @IBAction func lineStyleButtonAction(_ sender: NSButton) {
  711. if sender.tag == 0 {
  712. annotationModel.setStyle(.solid)
  713. } else {
  714. annotationModel.setStyle(.dashed)
  715. annotation?.setDashPattern(annotationModel.dashPattern())
  716. }
  717. lineStyleViewRefresh()
  718. updateAnnotation()
  719. }
  720. @IBAction func startMenuItemAction(_ sender: NSMenuItem) {
  721. let startType: CPDFLineStyle = (CPDFLineStyle(rawValue: sender.tag) ?? CPDFLineStyle(rawValue: 0))!
  722. annotationModel.setStart(startType)
  723. updateAnnotation()
  724. }
  725. @IBAction func endMenuItemAction(_ sender: NSMenuItem) {
  726. let endType: CPDFLineStyle = (CPDFLineStyle(rawValue: sender.tag) ?? CPDFLineStyle(rawValue: 0))!
  727. annotationModel.setEnd(endType)
  728. updateAnnotation()
  729. }
  730. @IBAction func fontButtonAction(_ sender: NSButton) {
  731. let selectItem = font_PopUpButton.selectedItem
  732. guard let selectItem = selectItem else { return }
  733. let resultAtt = NSMutableAttributedString(attributedString: selectItem.attributedTitle!)
  734. let familyString = resultAtt.string
  735. let styleString = font_StylePopUpButton.selectedItem?.title ?? ""
  736. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [.family: familyString, .face: styleString as Any])
  737. let fontSizeString = font_SizeComboBox.stringValue.replacingOccurrences(of: " pt", with: "")
  738. let newFont = NSFont(descriptor: attributeFontDescriptor, size: fontSizeString.stringToCGFloat())
  739. let fontModel = KMFontModel(fontName: familyString, fontWeight: styleString, fontSize: fontSizeString.stringToCGFloat(), fontColor: fontColorPickerView.color ?? .black, fontAlignment: .left, annotationType: annotationModel.annotationType)
  740. let fontWindowController = KMAnnotationFontWindowController.initWindowController(fontModel)
  741. fontWindowController.isHidenAlignmentLabel = true
  742. let window = fontWindowController.window
  743. fontWindowController.callback = { [weak self] model in
  744. self?.fontColorPickerView.color = model.fontColor
  745. DispatchQueue.global(qos: .default).async { [self]
  746. let fonts = NSFontManager.shared.availableFontFamilies
  747. let menu = NSMenu()
  748. var selectedIndex = 0
  749. for (index, fontName) in fonts.enumerated() {
  750. if let font = NSFont(name: fontName, size: 12.0) {
  751. let attributedString = NSAttributedString(string: fontName, attributes: [.font: font])
  752. let item = NSMenuItem()
  753. item.attributedTitle = attributedString
  754. menu.addItem(item)
  755. if let family = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String,
  756. let style = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.face) as? String {
  757. if model.fontName == family {
  758. selectedIndex = index
  759. }
  760. }
  761. }
  762. }
  763. DispatchQueue.main.async {
  764. self?.font_PopUpButton.menu = menu
  765. self?.font_PopUpButton.selectItem(at: selectedIndex)
  766. }
  767. }
  768. let selectedStyleIndex = self?.setFontStyle(fontName: model.fontName, currentStyle: model.fontWeight) ?? 0
  769. self?.font_StylePopUpButton.selectItem(at: Int(selectedStyleIndex))
  770. self?.font_SizeComboBox.stringValue = String(format: "%.f pt", model.fontSize)
  771. if self?.annotationModel.annotations != nil {
  772. let cfont = CPDFFont(familyName: model.fontName, fontStyle: model.fontWeight)
  773. for tAnnotation in self?.annotations ?? [] {
  774. if tAnnotation is CPDFLineAnnotation {
  775. let newAnnotation = (tAnnotation as! CPDFLineAnnotation)
  776. newAnnotation.cFont = cfont
  777. newAnnotation.fontSize = model.fontSize
  778. newAnnotation.fontColor = model.fontColor
  779. } else if tAnnotation is CPDFPolygonAnnotation {
  780. let newAnnotation = (tAnnotation as! CPDFPolygonAnnotation)
  781. newAnnotation.cFont = cfont
  782. newAnnotation.fontSize = model.fontSize
  783. newAnnotation.fontColor = model.fontColor
  784. } else if tAnnotation is CPDFPolylineAnnotation {
  785. let newAnnotation = (tAnnotation as! CPDFPolylineAnnotation)
  786. newAnnotation.cFont = cfont
  787. newAnnotation.fontSize = model.fontSize
  788. newAnnotation.fontColor = model.fontColor
  789. }
  790. }
  791. self?.updateAnnotation()
  792. } else {
  793. self?.annotationModel.setFontName(model.fontName)
  794. self?.annotationModel.setFontSize(model.fontSize)
  795. self?.annotationModel.setFontColor(model.fontColor)
  796. }
  797. }
  798. window?.orderFront(sender)
  799. }
  800. @IBAction func fontPopUpButtonAction(_ sender: NSPopUpButton) {
  801. guard let selectedItem = font_PopUpButton.selectedItem else { return }
  802. let resultAtt = NSMutableAttributedString(attributedString: selectedItem.attributedTitle!)
  803. let familyString = resultAtt.string
  804. let selectIndex = setFontStyle(fontName: familyString, currentStyle: nil)
  805. guard let styleString = font_StylePopUpButton.selectedItem?.title else { return }
  806. font_StylePopUpButton.selectItem(at: Int(selectIndex))
  807. for tAnnotation in annotations {
  808. if tAnnotation is CPDFLineAnnotation {
  809. let newAnnotation = (tAnnotation as! CPDFLineAnnotation)
  810. newAnnotation.cFont = CPDFFont(familyName: familyString, fontStyle: styleString)
  811. } else if tAnnotation is CPDFPolygonAnnotation {
  812. let newAnnotation = (tAnnotation as! CPDFPolygonAnnotation)
  813. newAnnotation.cFont = CPDFFont(familyName: familyString, fontStyle: styleString)
  814. } else if tAnnotation is CPDFPolylineAnnotation {
  815. let newAnnotation = (tAnnotation as! CPDFPolylineAnnotation)
  816. newAnnotation.cFont = CPDFFont(familyName: familyString, fontStyle: styleString)
  817. }
  818. }
  819. pdfView?.setNeedsDisplay(annotation)
  820. }
  821. @IBAction func fontSizeComboBoxAction(_ sender: NSComboBox) {
  822. if annotationModel.annotations != nil {
  823. for tAnnotation in annotations {
  824. if tAnnotation is CPDFLineAnnotation {
  825. let newAnnotation = (tAnnotation as! CPDFLineAnnotation)
  826. newAnnotation.fontSize = CGFloat(font_SizeComboBox.floatValue)
  827. } else if tAnnotation is CPDFPolygonAnnotation {
  828. let newAnnotation = (tAnnotation as! CPDFPolygonAnnotation)
  829. newAnnotation.fontSize = CGFloat(font_SizeComboBox.floatValue)
  830. } else if tAnnotation is CPDFPolylineAnnotation {
  831. let newAnnotation = (tAnnotation as! CPDFPolylineAnnotation)
  832. newAnnotation.fontSize = CGFloat(font_SizeComboBox.floatValue)
  833. }
  834. }
  835. } else {
  836. if annotationType == .line || annotationType == .polyGon || annotationType == .polyLine {
  837. if let data = annotationModel.fontName() {
  838. let font = NSFont(name: data, size: annotationModel.fontSize()) ?? NSFont.systemFont(ofSize: 16)
  839. let newFont = NSFont(name: font.fontName, size: CGFloat(font_SizeComboBox.floatValue))
  840. if let newFont = newFont {
  841. annotationModel.setFontName(newFont.fontName)
  842. annotationModel.setFontSize(newFont.pointSize)
  843. }
  844. }
  845. }
  846. }
  847. updateAnnotation()
  848. }
  849. //字重 NSFontWeight
  850. @IBAction func fontStylePopUpButtonAction(_ sender: NSPopUpButton) {
  851. if let styleString = font_StylePopUpButton.selectedItem?.title {
  852. if annotationModel.annotations != nil {
  853. for tAnnotation in self.annotations {
  854. if tAnnotation is CPDFLineAnnotation {
  855. let newAnnotation = (tAnnotation as! CPDFLineAnnotation)
  856. newAnnotation.cFont = CPDFFont(familyName: newAnnotation.cFont.familyName, fontStyle: styleString)
  857. } else if tAnnotation is CPDFPolygonAnnotation {
  858. let newAnnotation = (tAnnotation as! CPDFPolygonAnnotation)
  859. newAnnotation.cFont = CPDFFont(familyName: newAnnotation.cFont.familyName, fontStyle: styleString)
  860. } else if tAnnotation is CPDFPolylineAnnotation {
  861. let newAnnotation = (tAnnotation as! CPDFPolylineAnnotation)
  862. newAnnotation.cFont = CPDFFont(familyName: newAnnotation.cFont.familyName, fontStyle: styleString)
  863. }
  864. }
  865. } else {
  866. if annotationType == .line || annotationType == .polyGon || annotationType == .polyLine {
  867. if let data = annotationModel.fontName() {
  868. let font = NSFont(name: data, size: annotationModel.fontSize()) ?? NSFont.systemFont(ofSize: 16)
  869. if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? Int,
  870. let familyString = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String {
  871. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
  872. if let newFont = NSFont(descriptor: attributeFontDescriptor, size: CGFloat(fontSize)) {
  873. annotationModel.setFontName(newFont.fontName)
  874. annotationModel.setFontSize(newFont.pointSize)
  875. }
  876. }
  877. }
  878. }
  879. }
  880. }
  881. updateAnnotation()
  882. }
  883. @IBAction func lineDashComboBoxAction(_ sender: NSComboBox) {
  884. let number = NSNumber(value: lineStyle_DashComBox.floatValue)
  885. var lineDashPattern: [Any] = annotationModel.dashPattern()
  886. let array: [NSNumber]
  887. if annotationModel.dashPattern() is [NSNumber] {
  888. if lineDashPattern.isEmpty {
  889. array = [number]
  890. } else {
  891. lineDashPattern[0] = number
  892. array = lineDashPattern as! [NSNumber]
  893. }
  894. } else {
  895. array = [number]
  896. }
  897. annotation?.setDashPattern(array)
  898. updateAnnotation()
  899. }
  900. // MARK: Set & Get
  901. var annotations: [Any] {
  902. set {
  903. _annotations = newValue
  904. self.annotation = (newValue.first as? CPDFAnnotation)
  905. }
  906. get {
  907. return _annotations
  908. }
  909. }
  910. var annotationModel: CPDFAnnotationModel {
  911. get {
  912. return _annotationModel!
  913. }
  914. set {
  915. _annotationModel = newValue
  916. if _annotationModel?.annotations != nil {
  917. if annotationModel.annotations.count > 0 {
  918. annotations = _annotationModel?.annotations as! [CPDFAnnotation]
  919. }
  920. }
  921. }
  922. }
  923. var annotationType: CAnnotationType {
  924. get {
  925. if let ann = annotation?.isKind(of: CPDFLineAnnotation.self), ann {
  926. if (annotation as! CPDFLineAnnotation).isMeasure {
  927. return .line
  928. }
  929. } else if let ann = annotation?.isKind(of: CPDFPolygonAnnotation.self), ann {
  930. if pdfView?.annotationType == .square {
  931. return .square
  932. }
  933. return .polyGon
  934. } else if let ann = annotation?.isKind(of: CPDFPolylineAnnotation.self), ann {
  935. return .polyLine
  936. }
  937. return .unkown
  938. }
  939. }
  940. }