KMCropPreviewController.swift 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. //
  2. // KMCropPreviewController.swift
  3. // PDF Master
  4. //
  5. // Created by tangchao on 2022/12/29.
  6. //
  7. import Cocoa
  8. import PDFKit
  9. extension CPDFPage {
  10. var cropDrawingPage: CPDFPage? {
  11. get {
  12. return (objc_getAssociatedObject(self, "drawingPage") as! CPDFPage)
  13. }
  14. set {
  15. objc_setAssociatedObject(self, "drawingPage", newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
  16. }
  17. }
  18. var cropOffsetX: CGFloat {
  19. get {
  20. return objc_getAssociatedObject(self, "cropOffsetX") as! CGFloat
  21. }
  22. set {
  23. objc_setAssociatedObject(self, "cropOffsetX", newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
  24. }
  25. }
  26. var cropOffsetY: CGFloat {
  27. get {
  28. return objc_getAssociatedObject(self, "cropOffsetY") as! CGFloat
  29. }
  30. set {
  31. objc_setAssociatedObject(self, "cropOffsetY", newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
  32. }
  33. }
  34. var isChangePageSize: Bool {
  35. get {
  36. return objc_getAssociatedObject(self, "isChangePageSize") as! Bool
  37. }
  38. set {
  39. objc_setAssociatedObject(self, "isChangePageSize", newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
  40. }
  41. }
  42. var cropRect: NSRect {
  43. get {
  44. return objc_getAssociatedObject(self, "cropRect") as! NSRect
  45. }
  46. set {
  47. objc_setAssociatedObject(self, "cropRect", newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
  48. }
  49. }
  50. }
  51. class KMCropInfo: NSObject {
  52. var drawPage: CPDFPage!
  53. var cropOffsetX: CGFloat = 0
  54. var cropOffsetY: CGFloat = 0
  55. var isChangePageSize: Bool = false
  56. var cropRect: NSRect!
  57. }
  58. class KMCropPDFView: CPDFView {
  59. var drawInfo: Array<KMCropInfo> = []
  60. override func draw(_ page: CPDFPage!, to context: CGContext!) {
  61. super.draw(page, to: context)
  62. if (self.drawInfo.count > 0) {
  63. drawCropPage(page, to: context)
  64. }
  65. }
  66. private func drawCropPage(_ cropPage: CPDFPage, to context: CGContext!) {
  67. // let myPage: KMCropPDFPage = cropPage as! KMCropPDFPage
  68. let info: KMCropInfo = self.drawInfo[Int(self.document.index(for: cropPage))]
  69. if (info.drawPage != nil) {
  70. let originalRect = cropPage.bounds(for: .mediaBox)
  71. let drawPage = info.drawPage
  72. let cropRect = drawPage!.bounds(for: .mediaBox)
  73. /// 原始page的宽度(不管有没有旋转,都是旋转度数等于0)
  74. let orgPageWidth: CGFloat = NSWidth(cropRect)
  75. /// 原始page的高度
  76. let orgPageHeight: CGFloat = NSHeight(cropRect)
  77. let spaceX = info.cropOffsetX
  78. let spaceY = info.cropOffsetY
  79. let scale: CGFloat = min(NSWidth(originalRect)/orgPageWidth, NSHeight(originalRect)/orgPageHeight)
  80. NSGraphicsContext.saveGraphicsState()
  81. context.translateBy(x: spaceX,y: spaceY)
  82. context.scaleBy(x: scale, y: scale)
  83. if #available(macOS 10.12, *) {
  84. drawPage?.draw(with: .cropBox, to: context)
  85. drawPage?.transform(context, for: .cropBox)
  86. } else {
  87. NSGraphicsContext.saveGraphicsState()
  88. NSGraphicsContext.current = NSGraphicsContext(cgContext: context, flipped: false)
  89. drawPage?.draw(with: .cropBox, to: context)
  90. drawPage?.transform(context, for: .cropBox)
  91. }
  92. if (info.isChangePageSize) {
  93. let tCropRect: NSRect = cropPage.cropRect
  94. let w1: CGFloat = orgPageWidth-(tCropRect.size.width)-(tCropRect.origin.x)
  95. context.setFillColor(red: 0, green: 0, blue: 0, alpha: 0.3)
  96. let rect1: NSRect = NSMakeRect(0, 0, orgPageWidth, (tCropRect.origin.y))
  97. let rect2: NSRect = NSMakeRect(0, (tCropRect.origin.y)+(tCropRect.size.height), orgPageWidth, orgPageHeight - tCropRect.origin.y-tCropRect.size.height)
  98. let rect3: NSRect = NSMakeRect(0, tCropRect.origin.y,tCropRect.origin.x,tCropRect.size.height);
  99. var rect4Y = w1
  100. if (w1 > 0) {
  101. rect4Y = 0
  102. }
  103. let rect4: NSRect = NSMakeRect(tCropRect.origin.x+tCropRect.size.width, tCropRect.origin.y,rect4Y,tCropRect.size.height)
  104. context.fill(rect1)
  105. context.fill(rect2)
  106. context.fill(rect3)
  107. context.fill(rect4)
  108. }
  109. NSGraphicsContext.restoreGraphicsState()
  110. }
  111. }
  112. }
  113. class KMCropPDFPage: CPDFPage {
  114. // var drawingPage: CPDFPage!
  115. // var cropOffsetX: CGFloat = 0
  116. // var cropOffsetY: CGFloat = 0
  117. // var isChangePageSize: Bool = false
  118. // var cropRect: NSRect!
  119. override func draw(with box: CPDFDisplayBox, to context: CGContext!) {
  120. super.draw(with: box, to: context)
  121. let pageSize: NSSize = self.bounds(for: .mediaBox).size
  122. drawPage(with: context, page: self.cropDrawingPage!, pageSize: pageSize)
  123. }
  124. private func drawPage(with context: CGContext, page: CPDFPage, pageSize: NSSize) {
  125. let myPage: KMCropPDFPage = page as! KMCropPDFPage
  126. var originalSize: NSSize = page.bounds(for: .mediaBox).size
  127. //如果page的旋转角度为90,或者270,宽高交换
  128. if (page.rotation % 180 != 0) {
  129. originalSize = NSMakeSize(originalSize.height, originalSize.width)
  130. }
  131. context.saveGState()
  132. context.translateBy(x: myPage.cropOffsetX, y: myPage.cropOffsetY)
  133. if #available(macOS 10.12, *) {
  134. page.draw(with: .cropBox, to: context)
  135. page.transform(context, for: .cropBox)
  136. } else {
  137. NSGraphicsContext.saveGraphicsState()
  138. NSGraphicsContext.current = NSGraphicsContext(cgContext: context, flipped: true)
  139. page.draw(with: .cropBox, to: context)
  140. NSGraphicsContext.restoreGraphicsState()
  141. page.transform(context, for: .cropBox)
  142. }
  143. context.restoreGState()
  144. }
  145. }
  146. class KMCropPreviewController: KMWatermarkAdjectivePreViewBaseController {
  147. // var testPreView: PDFView!
  148. var tipView = KMCropTipView()
  149. var windowController: KMCropSettingWindowController!
  150. override func viewDidLoad() {
  151. super.viewDidLoad()
  152. let itemTitles = [["裁剪"]]
  153. var itemModels: Array<Array<KMWatermarkAdjectiveTopBarItemModel>> = []
  154. for items in itemTitles {
  155. var array: Array<KMWatermarkAdjectiveTopBarItemModel> = []
  156. for title in items {
  157. let model = KMWatermarkAdjectiveTopBarItemModel()
  158. model.iconName = ""
  159. model.itemTitle = title
  160. array.append(model)
  161. }
  162. itemModels.append(array)
  163. }
  164. self.topBarView.initItemData(itemArrays: itemModels)
  165. let preView: CPDFListView = CPDFListView()
  166. self.preView = preView
  167. self.preView.frame = self.preViewBox.contentView!.bounds
  168. self.preView.autoresizingMask = NSView.AutoresizingMask(rawValue: 18)
  169. self.preViewBox.contentView?.addSubview(self.preView)
  170. self.preView.autoScales = true
  171. self.preView.displaysAsBook = true
  172. self.preView.delegate = self
  173. let myPreView: CPDFListView = self.preView as! CPDFListView
  174. myPreView.pdfListViewDelegate = self
  175. // NotificationCenter.default.addObserver(self, selector: #selector(preViewSelectionDidChange), name: NSNotification.Name.CPDFViewSelectionChanged, object: nil)
  176. // self.testPreView = PDFView()
  177. // self.testPreView.frame = self.preViewBox.contentView!.bounds
  178. // self.testPreView.autoresizingMask = NSView.AutoresizingMask(rawValue: 18)
  179. // self.preViewBox.contentView?.addSubview(self.testPreView)
  180. self.topBarView.isCanApply(can: false)
  181. self.tipView.frame = self.tipBox.contentView!.frame
  182. self.tipView.autoresizingMask = NSView.AutoresizingMask(rawValue: 18)
  183. self.tipBox.addSubview(self.tipView)
  184. self.tipBox.isHidden = true
  185. self.tipView.enterAction = {
  186. () in
  187. let myPreView: CPDFListView = self.preView as! CPDFListView
  188. var rect = NSIntegralRect(myPreView.currentSelectionRect())
  189. if (NSIsEmptyRect(rect)) {
  190. return
  191. }
  192. let window = KMCropSettingWindowController(windowNibName: "KMCropSettingWindowController")
  193. self.view.window?.beginSheet(window.window!)
  194. self.windowController = window
  195. window.itemClick = { [self]
  196. (index: Int) in
  197. if (index == 1) { /// 取消
  198. self.view.window?.endSheet((self.windowController?.window)!)
  199. self.windowController = nil
  200. return
  201. }
  202. let pageRangeType = self.windowController.pageRangeIndex
  203. let pageCount: Int = Int(self.preView.document.pageCount)
  204. var pages: Array<Int> = []
  205. if (pageRangeType == 0) { /// 当前页面
  206. pages.append(self.preView.currentPageIndex)
  207. } else if (pageRangeType == 1) { /// 全部页面
  208. for i in 0 ..< pageCount {
  209. pages.append(i)
  210. }
  211. } else if (pageRangeType == 2) { /// 奇数页面
  212. var string: String = ""
  213. for i in 0 ..< pageCount {
  214. if (i % 2 == 1) {
  215. continue
  216. }
  217. pages.append(i)
  218. }
  219. } else if (pageRangeType == 3) { /// 偶数页面
  220. var string: String = ""
  221. for i in 0 ..< pageCount {
  222. if (i % 2 == 0) {
  223. continue
  224. }
  225. pages.append(i)
  226. }
  227. } else { /// 自定义
  228. for i in self.windowController.pageRangePages {
  229. pages.append(i)
  230. }
  231. }
  232. if (pages.count < 0) {
  233. let alert = NSAlert()
  234. alert.messageText = "请选择页面"
  235. alert.runModal()
  236. return
  237. }
  238. var pageSize: NSSize = NSZeroSize
  239. if (self.windowController.pageSize == "None") {
  240. } else {
  241. pageSize = KMCropTools.getPageSizeValue(self.windowController.pageSize)
  242. }
  243. for i in pages {
  244. let myPreView: CPDFListView = self.preView as! CPDFListView
  245. var page: CPDFPage = self.preView.document.page(at: UInt(i))
  246. var rect = NSIntegralRect(myPreView.selectionRect)
  247. if (NSIsEmptyRect(rect)) {
  248. rect = getPageForegroundBox(page)
  249. }
  250. var newRect = NSIntersectionRect(rect, (page.bounds(for: .mediaBox)))
  251. page.setBounds(newRect, for: .cropBox)
  252. if (pageSize.width == 0 && pageSize.height == 0) {
  253. } else {
  254. let tiffData = page.PDFListViewTIFFData(for: rect)
  255. let index: UInt = (page.pageIndex())
  256. // let newPage: CPDFPage = CPDFPage(image: NSImage(data: tiffData!))
  257. self.preView.document.removePage(at: index)
  258. // newPage.setBounds(NSMakeRect(0, 0, pageSize.width, pageSize.height), for: .cropBox)
  259. // let result = self.preView.document.insertPageObject(newPage, at: index)
  260. let result = self.preView.document.insertPage(pageSize, at: index)
  261. }
  262. }
  263. /// 保存到临时路径
  264. let toPath: String = self.preView.document.documentURL.path
  265. let documentPath = NSTemporaryDirectory()
  266. let tempPath: String = "\(documentPath)/\(toPath.lastPathComponent)"
  267. if (FileManager.default.fileExists(atPath: tempPath)) {
  268. try?FileManager.default.removeItem(atPath: tempPath)
  269. }
  270. let result = self.preView.document.write(to: URL(fileURLWithPath: tempPath))
  271. if (result) {
  272. if (FileManager.default.fileExists(atPath: toPath)) {
  273. try?FileManager.default.removeItem(atPath: toPath)
  274. }
  275. try?FileManager.default.moveItem(atPath: tempPath, toPath: toPath)
  276. } else {
  277. try?FileManager.default.removeItem(atPath: tempPath)
  278. }
  279. DispatchQueue.main.async {
  280. let myPreView: CPDFListView = self.preView as! CPDFListView
  281. myPreView.toolMode = .textToolMode
  282. /// 刷新预览视图
  283. self.preView.layoutDocumentView()
  284. self.preView.displayBox = .cropBox
  285. }
  286. /// 裁剪
  287. self.view.window?.endSheet((self.windowController?.window)!)
  288. self.windowController = nil
  289. // self.cropCurrentPage(in: NSZeroSize)
  290. let count: Int = Int(self.preView.document!.pageCount)
  291. // let PDFView = KMCropPDFView()
  292. // PDFView.frame = self.preView.bounds
  293. // self.preView.superview?.addSubview(PDFView)
  294. // PDFView.document = CPDFDocument(url: self.preView.document.documentURL)
  295. // for i in 0 ..< count {
  296. // let page: KMCropPDFPage = KMCropPDFPage()
  297. // page.setBounds(NSMakeRect(0, 0, 200, 200), for: .mediaBox)
  298. // let cropPage = self.preView.document.page(at: UInt(i))
  299. // page.cropDrawingPage = cropPage
  300. //// self.preView.document.insertPageObject(page, at: UInt(i))
  301. //// self.preView.document.removePage(at: UInt(i))
  302. // let currentPage = page.cropDrawingPage
  303. // let drawInfo = KMCropInfo()
  304. // drawInfo.drawPage = cropPage
  305. // PDFView.drawInfo.append(drawInfo)
  306. // PDFView.document.insertPageObject(page, at: UInt(i))
  307. // }
  308. /// 保存到临时路径
  309. // let toPath: String = self.preView.document.documentURL.lastPathComponent
  310. // let documentPath = NSTemporaryDirectory()
  311. // let tempPath: String = "\(documentPath)/\(toPath)"
  312. // if (FileManager.default.fileExists(atPath: tempPath)) {
  313. // try?FileManager.default.removeItem(atPath: tempPath)
  314. // }
  315. //
  316. // let result = PDFView.document.write(to: URL(fileURLWithPath: tempPath))
  317. //
  318. // DispatchQueue.main.async {
  319. // let myPreView: CPDFListView = self.preView as! CPDFListView
  320. // myPreView.toolMode = .textToolMode
  321. //
  322. // self.preView.layoutDocumentView()
  323. // }
  324. }
  325. }
  326. }
  327. // @objc func preViewSelectionDidChange(sender: NSNotification) {
  328. // if (self.preView.isEqual(to: sender.object)) {
  329. //// self.preView.currentSelection
  330. // print("1111111111")
  331. //
  332. //// NSUInteger eventMask = NSEventMaskLeftMouseUp | NSEventMaskLeftMouseDragged;
  333. //// let theEvent = [self.view.window.nextEventMatchingMask:NSEventMaskLeftMouseUp];
  334. //// let theEvent = self.view.window?.nextEvent(matching: .leftMouseUp.union(.rightMouseUp).union(.otherMouseUp))
  335. //// if (theEvent?.type == .leftMouseUp) {
  336. // let myPreview: CPDFListView = self.preView as! CPDFListView
  337. // if (NSIsEmptyRect(myPreview.selectionRect)) {
  338. // print("end")
  339. // }
  340. // }
  341. // }
  342. override func viewDidAppear() {
  343. super.viewDidAppear()
  344. // if (self.documentURL != nil) {
  345. // self.testPreView.document = PDFDocument(url: self.documentURL)
  346. // }
  347. }
  348. override func topItemClick(index: Int) {
  349. let menu = NSMenu()
  350. let titles = ["裁剪当前页面 - 白边距", "裁剪所有页面 - 自动", "自定义裁剪区域"]
  351. for title in titles {
  352. let item = NSMenuItem(title: title, action: #selector(itemAction), target: self)
  353. item.tag = titles.firstIndex(of: title)!
  354. menu.addItem(item)
  355. }
  356. menu.popUp(positioning: nil, at: NSPoint(x: self.topBarView.frame.midX-100, y: 0), in: self.topBarView)
  357. }
  358. @objc private func itemAction(sender: NSMenuItem) {
  359. if (sender.tag == 0) {
  360. /// 裁剪当前页面 - 白边距
  361. self.tipBox.isHidden = true
  362. cropCurrentPage()
  363. return
  364. }
  365. if (sender.tag == 1) {
  366. /// 裁剪所有页面 - 自动
  367. self.tipBox.isHidden = true
  368. cropAllPate()
  369. return
  370. }
  371. //// 自定义裁剪区域
  372. let myPreView: CPDFListView = self.preView as! CPDFListView
  373. myPreView.toolMode = .selectToolMode
  374. self.preView.autoScales = true
  375. self.preView.autoScales = false
  376. var pageHeight: CGFloat = NSHeight(self.preView.currentPage().bounds(for: self.preView.displayBox))
  377. if (self.preView.displaysPageBreaks) {
  378. pageHeight += 8
  379. }
  380. var scaleFactor: CGFloat = fmax(self.preView.minimumScaleFactor, NSHeight(self.preView.frame)/pageHeight)
  381. // if (scaleFactor < self.preView.scaleFactor) {
  382. self.preView.scaleFactor = scaleFactor
  383. // }
  384. self.tipBox.isHidden = false
  385. self.tipView.setString(string: "请框选裁剪区域")
  386. }
  387. private func cropCurrentPage(in pageSize: NSSize) {
  388. let myPreView: CPDFListView = self.preView as! CPDFListView
  389. var rect = NSIntegralRect(myPreView.currentSelectionRect())
  390. var page: CPDFPage?
  391. if ((myPreView.currentSelectionPage()) != nil) {
  392. page = myPreView.currentSelectionPage()
  393. } else {
  394. page = myPreView.currentPage()
  395. }
  396. if (NSIsEmptyRect(rect)) {
  397. rect = getPageForegroundBox(page!)
  398. }
  399. let tiffData = page!.PDFListViewTIFFData(for: rect)
  400. let index: UInt = (page?.pageIndex())!
  401. var newRect = NSIntersectionRect(rect, (page?.bounds(for: .mediaBox))!)
  402. page?.setBounds(newRect, for: .cropBox)
  403. self.preView.document.removePage(at: index)
  404. // let newPage: CPDFPage = CPDFPage(image: NSImage(data: tiffData!))
  405. // newPage.setBounds(NSMakeRect(0, 0, pageSize.width, pageSize.height), for: .cropBox)
  406. // let result = self.preView.document.insertPageObject(newPage, at: index)
  407. let result = self.preView.document.insertPage(pageSize, at: index)
  408. // var newDoc = CPDFDocument()
  409. /// 刷新预览视图
  410. self.preView.layoutDocumentView()
  411. self.preView.displayBox = .cropBox
  412. }
  413. private func cropAllPate() {
  414. var size = NSZeroSize
  415. for i in 0 ..< self.preView.document.pageCount {
  416. let page = self.preView.document.page(at: i)
  417. var rect = getPageForegroundBox(page!)
  418. size.width = fmax(size.width, NSWidth(rect))
  419. size.height = fmax(size.height, NSHeight(rect))
  420. }
  421. var rectArray: Array<NSRect> = []
  422. for i in 0 ..< self.preView.document.pageCount {
  423. let page = self.preView.document.page(at: i)
  424. var rect = getPageForegroundBox(page!)
  425. var bounds: NSRect = (page?.bounds(for: .mediaBox))!
  426. if (rect.minX - bounds.minX > bounds.maxX-rect.maxX) {
  427. rect.origin.x = rect.maxX-size.width
  428. }
  429. rect.origin.y = rect.maxY-size.height
  430. rect.size = size
  431. if (NSWidth(rect) > NSWidth(bounds)) {
  432. rect.size.width = NSWidth(bounds)
  433. }
  434. if (NSHeight(rect) > NSHeight(bounds)) {
  435. rect.size.height = NSHeight(bounds)
  436. }
  437. if (NSMinX(rect) < NSMinX(bounds)) {
  438. rect.origin.x = NSMinX(bounds)
  439. } else if (NSMaxX(rect) > NSMaxX(bounds)) {
  440. rect.origin.x = NSMaxX(bounds) - NSWidth(rect)
  441. }
  442. if (NSMinY(rect) < NSMinY(bounds)) {
  443. rect.origin.y = NSMinY(bounds)
  444. } else if (NSMaxY(rect) > NSMaxY(bounds)) {
  445. rect.origin.y = NSMaxY(bounds) - NSHeight(rect)
  446. }
  447. rectArray.append(rect)
  448. }
  449. cropPages(to: rectArray)
  450. }
  451. private func cropPages(to rects: Array<NSRect>) {
  452. let currentPage = self.preView.currentPage()
  453. let visibleRect: NSRect = self.preView.convert(self.preView.convert(self.preView.documentView().visibleRect, from: self.preView.documentView()), to: self.preView.currentPage())
  454. var oldRectArray: Array<NSRect> = []
  455. for i in 0 ..< self.preView.document.pageCount {
  456. let page = self.preView.document.page(at: i)
  457. var rect = NSIntersectionRect(rects[Int(i)], (page?.bounds(for: .mediaBox))!)
  458. let oldRect = page?.bounds(for: .cropBox)
  459. oldRectArray.append(oldRect!)
  460. page?.setBounds(rect, for: .cropBox)
  461. }
  462. /// 刷新预览视图
  463. self.preView.layoutDocumentView()
  464. self.preView.displayBox = .cropBox
  465. self.preView.go(to: currentPage)
  466. self.preView.go(to: visibleRect, on: currentPage)
  467. }
  468. private func cropCurrentPage() {
  469. let myPreView: CPDFListView = self.preView as! CPDFListView
  470. var rect = NSIntegralRect(myPreView.currentSelectionRect())
  471. var page: CPDFPage?
  472. if ((myPreView.currentSelectionPage()) != nil) {
  473. page = myPreView.currentSelectionPage()
  474. } else {
  475. page = myPreView.currentPage()
  476. }
  477. if (NSIsEmptyRect(rect)) {
  478. rect = getPageForegroundBox(page!)
  479. }
  480. let index: UInt = (page?.pageIndex())!
  481. cropPage(at: index, in: rect)
  482. }
  483. func cropPage(at index: UInt, in rect: NSRect) {
  484. let oldRect = self.preView.document.page(at: index)?.bounds(for: .cropBox)
  485. /// undo \ redo 处理
  486. // NSUndoManager *undoManager = [[self document] undoManager];
  487. // let undoManager = UndoManager()
  488. // (undoManager.prepare(withInvocationTarget: self) as! KMCropPreviewController).cropPage(at: index, in: oldRect!)
  489. // undoManager.setActionName(NSLocalizedString("Crop Page", comment: "Undo action name"))
  490. // [[self document] undoableActionIsDiscardable];
  491. var page = self.preView.document.page(at: index)
  492. var newRect = NSIntersectionRect(rect, (page?.bounds(for: .mediaBox))!)
  493. page?.setBounds(newRect, for: .cropBox)
  494. /// 刷新预览视图
  495. self.preView.layoutDocumentView()
  496. self.preView.displayBox = .cropBox
  497. }
  498. private func getPageForegroundBox(_ page: CPDFPage) -> NSRect {
  499. let marginWidth: CGFloat = 10
  500. let marginHeight: CGFloat = 10
  501. let imageRep = newBitmapImageRepForBox(page, .mediaBox)
  502. let bounds = page.bounds(for: .mediaBox)
  503. var foregroundBox = imageRep.foregroundRect()
  504. if (imageRep == nil) {
  505. foregroundBox = bounds
  506. } else if (NSIsEmptyRect(foregroundBox)) {
  507. let centerPoint = NSPoint(x: bounds.midX, y: bounds.midY)
  508. let origin = NSPoint(x: round(centerPoint.x), y: round(centerPoint.y))
  509. foregroundBox.origin = origin
  510. foregroundBox.size = NSZeroSize
  511. } else {
  512. let origin = NSPoint(x: foregroundBox.origin.x+bounds.origin.x, y: foregroundBox.origin.y+bounds.origin.y)
  513. foregroundBox.origin = origin
  514. }
  515. return NSIntegralRect(NSInsetRect(foregroundBox, -marginWidth, -marginHeight))
  516. }
  517. private func newBitmapImageRepForBox(_ page: CPDFPage, _ box: CPDFDisplayBox) -> NSBitmapImageRep {
  518. let bounds = page.bounds(for: box)
  519. var imageRep = NSBitmapImageRep(bitmapDataPlanes: nil,
  520. pixelsWide: Int(NSWidth(bounds)),
  521. pixelsHigh: Int(NSHeight(bounds)),
  522. bitsPerSample: 8,
  523. samplesPerPixel: 4,
  524. hasAlpha: true,
  525. isPlanar: false,
  526. colorSpaceName: .calibratedRGB,
  527. bitmapFormat: NSBitmapImageRep.Format(rawValue: 0),
  528. bytesPerRow: 0,
  529. bitsPerPixel: 32)
  530. if (imageRep != nil) {
  531. NSGraphicsContext.saveGraphicsState()
  532. NSGraphicsContext.current = NSGraphicsContext.init(bitmapImageRep: imageRep!)
  533. NSGraphicsContext.current?.imageInterpolation = .none
  534. NSGraphicsContext.current?.shouldAntialias = false
  535. if (page.rotation != 0) {
  536. var transform = NSAffineTransform()
  537. if (page.rotation == 90) {
  538. transform.translateX(by: NSWidth(bounds), yBy: 0)
  539. } else if (page.rotation == 180) {
  540. transform.translateX(by: NSHeight(bounds), yBy: NSWidth(bounds))
  541. } else if (page.rotation == 270) {
  542. transform.translateX(by: 0, yBy: NSHeight(bounds))
  543. }
  544. transform.rotate(byDegrees: CGFloat(page.rotation))
  545. transform.concat()
  546. }
  547. page.draw(with: box, to: (NSGraphicsContext.current?.cgContext as! CGContext))
  548. // page.draw(with: box)
  549. NSGraphicsContext.current?.imageInterpolation = .default
  550. NSGraphicsContext.restoreGraphicsState()
  551. }
  552. return imageRep!
  553. }
  554. }
  555. extension KMCropPreviewController: CPDFViewDelegate {
  556. func pdfViewEditingSelectionDidChanged(_ pdfView: CPDFView!) {
  557. }
  558. }
  559. extension KMCropPreviewController: CPDFListViewDelegate {
  560. func pdfListViewDidSelectionEnd(_ pdfListView: CPDFListView!) {
  561. if (self.preView.isEqual(to: pdfListView)) {
  562. self.tipView.setString(string: "请按 Enter 键确定裁剪区域")
  563. }
  564. }
  565. }
  566. //extension PDFPage {
  567. // func getPageForegroundBox() -> NSRect {
  568. // let marginWidth: CGFloat = 10
  569. // let marginHeight: CGFloat = 10
  570. //
  571. // let imageRep = newBitmapImageRepForBox(.mediaBox)
  572. // let bounds = bounds(for: .mediaBox)
  573. // var foregroundBox = imageRep.foregroundRect()
  574. // if (imageRep == nil) {
  575. // foregroundBox = bounds
  576. // } else if (NSIsEmptyRect(foregroundBox)) {
  577. // let centerPoint = NSPoint(x: bounds.midX, y: bounds.midY)
  578. // let origin = NSPoint(x: round(centerPoint.x), y: round(centerPoint.y))
  579. // foregroundBox.origin = origin
  580. // foregroundBox.size = NSZeroSize
  581. // } else {
  582. // let origin = NSPoint(x: foregroundBox.origin.x+bounds.origin.x, y: foregroundBox.origin.y+bounds.origin.y)
  583. // foregroundBox.origin = origin
  584. // }
  585. //
  586. // return NSIntegralRect(NSInsetRect(foregroundBox, -marginWidth, -marginHeight))
  587. // }
  588. //
  589. // func newBitmapImageRepForBox(_ box: PDFDisplayBox) -> NSBitmapImageRep {
  590. // let bounds = bounds(for: box)
  591. // let imageRep = NSBitmapImageRep(bitmapDataPlanes: nil,
  592. // pixelsWide: Int(NSWidth(bounds)),
  593. // pixelsHigh: Int(NSHeight(bounds)),
  594. // bitsPerSample: 8,
  595. // samplesPerPixel: 4,
  596. // hasAlpha: true,
  597. // isPlanar: false,
  598. // colorSpaceName: .calibratedRGB,
  599. // bitmapFormat: NSBitmapImageRep.Format(rawValue: 0),
  600. // bytesPerRow: 0,
  601. // bitsPerPixel: 32)
  602. //
  603. // if (imageRep != nil) {
  604. // NSGraphicsContext.saveGraphicsState()
  605. // NSGraphicsContext.current = NSGraphicsContext.init(bitmapImageRep: imageRep!)
  606. // NSGraphicsContext.current?.imageInterpolation = .none
  607. // NSGraphicsContext.current?.shouldAntialias = false
  608. // if (self.rotation != 0) {
  609. // let transform = NSAffineTransform()
  610. // if (self.rotation == 90) {
  611. // transform.translateX(by: NSWidth(bounds), yBy: 0)
  612. // } else if (self.rotation == 180) {
  613. // transform.translateX(by: NSHeight(bounds), yBy: NSWidth(bounds))
  614. // } else if (self.rotation == 270) {
  615. // transform.translateX(by: 0, yBy: NSHeight(bounds))
  616. // }
  617. //
  618. // transform.rotate(byDegrees: CGFloat(self.rotation))
  619. // transform.concat()
  620. // }
  621. //
  622. // draw(with: box)
  623. // NSGraphicsContext.current?.imageInterpolation = .default
  624. // NSGraphicsContext.restoreGraphicsState()
  625. // }
  626. //
  627. // return imageRep!
  628. // }
  629. //}