// // KMBOTAAnnotationTool.swift // PDF Reader Pro // // Created by lizhe on 2023/4/6. // import Cocoa class KMBOTAAnnotationTool: NSObject { static func fetchCellHeight(annotation: CPDFAnnotation, maxSize: CGSize) -> CGFloat { var height: CGFloat = 48 let contentLabelString = self.fetchContentLabelString(annotation: annotation) if contentLabelString.count != 0 { height += 4 height += KMBOTAAnnotationTool.fetchContentLabelHeight(string: contentLabelString, maxSize: maxSize) } if annotation.isKind(of: CPDFInkAnnotation.self) { height += 4 height += KMBOTAAnnotationTool.fetchContentImageHeight() } let noteLabelString = self.fetchNoteLabelString(annotation: annotation) if noteLabelString.count != 0 { height = height + 4 height += KMBOTAAnnotationTool.fetchNoteHeight(string: noteLabelString, maxSize: maxSize) } return height } static func fetchTextHeight(string: String, maxSize: CGSize) -> CGFloat { var height = 0.0 let attributes = KMBOTAAnnotationTool.fetchTextAttributed(annotation: nil) let text : String = self.fetchText(text: string) if text.count > 0 { let size = NSString(string: text).boundingRect(with: maxSize, options: NSString.DrawingOptions(rawValue: 3), attributes: attributes).size height += size.height } return height } static func fetchText(text: String) -> String { var string = text.trimmingCharacters(in: .whitespacesAndNewlines) while string.hasPrefix("\n") { string = string.filter{ $0 != "\n" } } while string.hasPrefix("\r") { string = string.filter{ $0 != "\r" } } while string.hasPrefix("\n") { string = string.filter{ $0 != "\n" } } while string.hasPrefix("\r") { string = string.filter{ $0 != "\r" } } return string } static func fetchTextAttributed(annotation: CPDFAnnotation?) -> [NSAttributedString.Key : Any] { let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineHeightMultiple = 1.32 paragraphStyle.alignment = .left let attributes = [NSAttributedString.Key.paragraphStyle: paragraphStyle, NSAttributedString.Key.font : NSFont.SFProTextRegularFont(14.0)] return attributes } static func fetchContentLabelString(annotation: CPDFAnnotation) -> String { var contentString: String = "" if annotation.contents != nil { if annotation.isKind(of: CPDFMarkupAnnotation.self) { var markupString : String = annotation.contents if markupString.count == 0 { let exproString = KMOCToolClass.exproString(annotation: annotation) if exproString.count > 0 { markupString = exproString } } contentString = markupString } else if annotation.isKind(of: CPDFFreeTextAnnotation.self) { contentString = annotation.contents } else if annotation.isKind(of: CPDFTextAnnotation.self) { contentString = annotation.contents } contentString = KMBOTAAnnotationTool.fetchText(text: contentString) } if annotation.string() != nil { if annotation.isKind(of: CPDFLineAnnotation.self) { if (annotation as! CPDFLineAnnotation).isMeasure { contentString = annotation.string() } } else if annotation.isKind(of: CPDFPolygonAnnotation.self) { contentString = annotation.string() } else if annotation.isKind(of: CPDFPolylineAnnotation.self) { contentString = annotation.string() } contentString = KMBOTAAnnotationTool.fetchText(text: contentString) } return contentString } static func fetchContentLabelHeight(string: String, maxSize: CGSize) -> CGFloat { return KMBOTAAnnotationTool.fetchTextHeight(string: string, maxSize: maxSize) } static func fetchContentImageHeight() -> CGFloat { return 58 } static func fetchNoteLabelString(annotation: CPDFAnnotation) -> String { var contentString: String = "" if annotation.contents != nil { contentString = annotation.contents if annotation.isKind(of: CPDFMarkupAnnotation.self) { var markupString: String = (annotation as! CPDFMarkupAnnotation).markupText() ?? "" contentString = contentString.replacingOccurrences(of: " ", with: "") markupString = markupString.replacingOccurrences(of: " ", with: "") if contentString == markupString { contentString = "" } else { contentString = markupString } } else if annotation.isKind(of: CPDFFreeTextAnnotation.self) { contentString = "" } else if annotation.isKind(of: CPDFTextAnnotation.self) { contentString = "" } contentString = KMBOTAAnnotationTool.fetchText(text: contentString) return contentString } return contentString } static func fetchNoteHeight(string: String, maxSize: CGSize) -> CGFloat { return KMBOTAAnnotationTool.fetchTextHeight(string: string, maxSize: maxSize) + 8 } }