浏览代码

【CISDEM OEM】测量功能逻辑补充

wanjun 8 月之前
父节点
当前提交
77f07d8dd9
共有 26 个文件被更改,包括 1784 次插入93 次删除
  1. 14 0
      PDF Office/PDF Master/Class/DigtalSignature/CPDFDigtalView/Event/NSGeometry+PDFListView.h
  2. 4 10
      PDF Office/PDF Master/Class/Measure/Window/CAreaMeasureInfoWindowController.swift
  3. 18 2
      PDF Office/PDF Master/Class/Measure/Window/CAreaMeasureInfoWindowController.xib
  4. 3 1
      PDF Office/PDF Master/Class/Measure/Window/CAreaSettingWindowController.swift
  5. 4 4
      PDF Office/PDF Master/Class/Measure/Window/CAreaSettingWindowController.xib
  6. 32 17
      PDF Office/PDF Master/Class/Measure/Window/CDistanceMeasureInfoWindowController.swift
  7. 22 2
      PDF Office/PDF Master/Class/Measure/Window/CDistanceMeasureInfoWindowController.xib
  8. 5 4
      PDF Office/PDF Master/Class/Measure/Window/CDistanceSettingWindowController.swift
  9. 4 4
      PDF Office/PDF Master/Class/Measure/Window/CDistanceSettingWindowController.xib
  10. 6 13
      PDF Office/PDF Master/Class/Measure/Window/CPerimeterMeasureInfoWindowController.swift
  11. 18 2
      PDF Office/PDF Master/Class/Measure/Window/CPerimeterMeasureInfoWindowController.xib
  12. 36 0
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFKitExtensions/CPDFAnnotationExtensions/CPDFLineAnnotation+PDFListView.swift
  13. 143 0
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFKitExtensions/CPDFAnnotationExtensions/CPDFPolygonAnnotation+PDFListView.swift
  14. 95 0
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFKitExtensions/CPDFAnnotationExtensions/CPDFPolylineAnnotation+PDFListView.swift
  15. 16 0
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListView+Private.h
  16. 11 2
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListView.h
  17. 33 4
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListView.m
  18. 31 1
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListViewConfig.swift
  19. 893 18
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListViewExtension/CPDFListView+Event.m
  20. 6 0
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListViewExtension/CPDFListView+KeyEvent.m
  21. 4 0
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListViewExtension/CPDFListView+Tool.h
  22. 65 1
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListViewExtension/CPDFListView+Tool.m
  23. 195 8
      PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController+Action.swift
  24. 96 0
      PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController+UI.swift
  25. 14 0
      PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController.swift
  26. 16 0
      PDF Office/PDF Reader Pro.xcodeproj/project.pbxproj

+ 14 - 0
PDF Office/PDF Master/Class/DigtalSignature/CPDFDigtalView/Event/NSGeometry+PDFListView.h

@@ -21,6 +21,7 @@ typedef NS_OPTIONS(NSUInteger, CRectEdges) {
     CMaxXEdgeMask = (1UL << 2),
     CMaxYEdgeMask = (1UL << 3),
     CEditInEdgeMask = (1UL << 4),
+    CMidEdgeMask = (1UL << 5),
 };
 
 static inline NSPoint CPDFListViewIntegralPoint(NSPoint point) {
@@ -120,6 +121,19 @@ static inline BOOL CPDFListViewIntegralCircleRect(NSRect rect,NSPoint point) {
     return dis <= radius;
 }
 
+static inline NSArray<NSValue *> * getSquarePoints(CGRect bounds) {
+    NSMutableArray<NSValue *> *savePoints = [NSMutableArray array];
+    NSValue *minX = [NSValue valueWithPoint:bounds.origin];
+    [savePoints addObject:minX];
+    NSValue *minY = [NSValue valueWithPoint:NSMakePoint(bounds.origin.x + bounds.size.width, bounds.origin.y)];
+    [savePoints addObject:minY];
+    NSValue *maxY = [NSValue valueWithPoint:NSMakePoint(bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height)];
+    [savePoints addObject:maxY];
+    NSValue *maxX = [NSValue valueWithPoint:NSMakePoint(bounds.origin.x, bounds.origin.y + bounds.size.height)];
+    [savePoints addObject:maxX];
+    return savePoints;
+}
+
 #pragma mark -
 
 extern NSPoint CPDFListViewConstrainPointInRect(NSPoint point, NSRect boundary);

+ 4 - 10
PDF Office/PDF Master/Class/Measure/Window/CAreaMeasureInfoWindowController.swift

@@ -19,18 +19,12 @@ class CAreaMeasureInfoWindowController: NSWindowController {
     @IBOutlet weak var precisionLabel: NSTextField!
     @IBOutlet weak var angleLabel: NSTextField!
 
-    private(set) var measureInfo: CPDFAreaMeasureInfo
     weak var delegate: CAreaMeasureInfoWindowControllerDelegate?
 
-    @objc init(measureInfo: CPDFAreaMeasureInfo) {
-        self.measureInfo = measureInfo
-        super.init(window: nil)
-//        self.windowNibName = "CAreaMeasureInfoWindowController"
-        self.window?.level = .floating
-    }
-
-    required init?(coder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
+    var measureInfo: CPDFAreaMeasureInfo = CPDFAreaMeasureInfo()
+    
+    convenience init() {
+        self.init(windowNibName: "CAreaMeasureInfoWindowController")
     }
 
     func hideFloatingWindow() {

+ 18 - 2
PDF Office/PDF Master/Class/Measure/Window/CAreaMeasureInfoWindowController.xib

@@ -6,7 +6,7 @@
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
-        <customObject id="-2" userLabel="File's Owner" customClass="CAreaMeasureInfoWindowController">
+        <customObject id="-2" userLabel="File's Owner" customClass="CAreaMeasureInfoWindowController" customModule="PDF_Reader_Pro" customModuleProvider="target">
             <connections>
                 <outlet property="angleLabel" destination="YcG-qm-931" id="P3D-hi-1O5"/>
                 <outlet property="areaLabel" destination="C0Q-oq-d66" id="rYn-ds-xSN"/>
@@ -21,7 +21,7 @@
             <windowStyleMask key="styleMask" titled="YES"/>
             <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
             <rect key="contentRect" x="2242" y="1105" width="360" height="230"/>
-            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="1800" height="1125"/>
             <view key="contentView" id="se5-gp-TjO">
                 <rect key="frame" x="0.0" y="0.0" width="360" height="230"/>
                 <autoresizingMask key="autoresizingMask"/>
@@ -159,6 +159,20 @@ DQ
                             <action selector="buttonItemClick_Setting:" target="-2" id="C0Y-jH-ycy"/>
                         </connections>
                     </button>
+                    <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="FzA-5Y-Luz">
+                        <rect key="frame" x="187" y="9" width="79" height="32"/>
+                        <buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" controlSize="large" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="eWo-di-gcS">
+                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                            <font key="font" metaFont="system"/>
+                            <string key="keyEquivalent" base64-UTF8="YES">
+Gw
+</string>
+                        </buttonCell>
+                        <constraints>
+                            <constraint firstAttribute="width" constant="67" id="KZl-vC-61h"/>
+                            <constraint firstAttribute="height" constant="20" id="QGG-rF-oUh"/>
+                        </constraints>
+                    </button>
                 </subviews>
                 <constraints>
                     <constraint firstItem="4AM-g2-hiQ" firstAttribute="top" secondItem="Kag-pg-b5k" secondAttribute="bottom" constant="12" id="0kh-sU-aoJ"/>
@@ -167,6 +181,7 @@ DQ
                     <constraint firstItem="SiO-Wc-d1h" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="58" id="62g-1z-QTU"/>
                     <constraint firstItem="YcG-qm-931" firstAttribute="top" secondItem="GbN-aH-zzt" secondAttribute="bottom" constant="12" id="8DZ-oq-YQi"/>
                     <constraint firstAttribute="bottom" secondItem="Osm-N0-8Pg" secondAttribute="bottom" constant="15" id="9ET-RX-LnV"/>
+                    <constraint firstItem="Osm-N0-8Pg" firstAttribute="leading" secondItem="FzA-5Y-Luz" secondAttribute="trailing" constant="18" id="AXP-aJ-1cH"/>
                     <constraint firstItem="4AM-g2-hiQ" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="58" id="Af7-QD-eDO"/>
                     <constraint firstItem="GbN-aH-zzt" firstAttribute="leading" secondItem="Kag-pg-b5k" secondAttribute="trailing" constant="28" id="CpJ-Yp-e6L"/>
                     <constraint firstItem="GbN-aH-zzt" firstAttribute="top" secondItem="C0Q-oq-d66" secondAttribute="bottom" constant="12" id="MJM-P6-nUI"/>
@@ -180,6 +195,7 @@ DQ
                     <constraint firstItem="cee-VO-HNn" firstAttribute="leading" secondItem="v9s-IY-XsA" secondAttribute="trailing" constant="16" id="f2a-cN-Jzb"/>
                     <constraint firstItem="6j1-fh-lBh" firstAttribute="top" secondItem="cee-VO-HNn" secondAttribute="bottom" constant="25" id="gQm-50-qA3"/>
                     <constraint firstItem="6j1-fh-lBh" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="58" id="iJF-Er-wvV"/>
+                    <constraint firstItem="Osm-N0-8Pg" firstAttribute="centerY" secondItem="FzA-5Y-Luz" secondAttribute="centerY" id="n2S-yM-92u"/>
                     <constraint firstAttribute="trailing" secondItem="Osm-N0-8Pg" secondAttribute="trailing" constant="15" id="pqF-db-YYm"/>
                     <constraint firstItem="mC7-Nw-srr" firstAttribute="leading" secondItem="6j1-fh-lBh" secondAttribute="trailing" constant="52" id="vaL-Vf-7Ef"/>
                     <constraint firstItem="Kag-pg-b5k" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="58" id="y7Z-Or-evH"/>

+ 3 - 1
PDF Office/PDF Master/Class/Measure/Window/CAreaSettingWindowController.swift

@@ -31,6 +31,8 @@ class CAreaSettingWindowController: NSWindowController, NSTextFieldDelegate {
         self.measureInfo = measureInfo
         super.init(window: nil)
 //        self.windowNibName = "CAreaSettingWindowController"
+        Bundle.main.loadNibNamed("CAreaSettingWindowController", owner: self, topLevelObjects: nil)
+        commonInit()
     }
     
     required init?(coder: NSCoder) {
@@ -40,7 +42,7 @@ class CAreaSettingWindowController: NSWindowController, NSTextFieldDelegate {
     override func windowDidLoad() {
         super.windowDidLoad()
 
-        commonInit()
+//        commonInit()
     }
     
     private func commonInit() {

+ 4 - 4
PDF Office/PDF Master/Class/Measure/Window/CAreaSettingWindowController.xib

@@ -6,14 +6,14 @@
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
-        <customObject id="-2" userLabel="File's Owner" customClass="CAreaSettingWindowController">
+        <customObject id="-2" userLabel="File's Owner" customClass="CAreaSettingWindowController" customModule="PDF_Reader_Pro" customModuleProvider="target">
             <connections>
                 <outlet property="doneButton" destination="0St-WY-Hn5" id="d0k-Xd-GVe"/>
                 <outlet property="isAreaCaptionButton" destination="dYV-qw-kD8" id="8cU-rE-Bwu"/>
                 <outlet property="isLengthCaptionButton" destination="jTl-ke-b1S" id="mRa-KV-dYY"/>
                 <outlet property="precisionPopButton" destination="P3V-RB-m4R" id="GKY-g3-gVn"/>
                 <outlet property="rulerBasePopButton" destination="UpD-5M-EEE" id="s4N-CJ-CF9"/>
-                <outlet property="rulerBaseTexField" destination="tAa-Te-jB3" id="qpH-2P-NQG"/>
+                <outlet property="rulerBaseTextField" destination="tAa-Te-jB3" id="3Jw-z0-BeV"/>
                 <outlet property="rulerTranslatePopButton" destination="efk-5G-wt6" id="Mc2-5Q-3pf"/>
                 <outlet property="rulerTranslateTextField" destination="NIg-vU-5gd" id="SkK-vt-QJw"/>
                 <outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
@@ -241,8 +241,8 @@ DQ
                         </connections>
                     </button>
                     <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eK4-Xp-4u5">
-                        <rect key="frame" x="268" y="3" width="110" height="52"/>
-                        <buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="rcQ-sm-fWx">
+                        <rect key="frame" x="269" y="4" width="108" height="52"/>
+                        <buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" controlSize="large" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="rcQ-sm-fWx">
                             <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                             <font key="font" metaFont="system"/>
                             <string key="keyEquivalent" base64-UTF8="YES">

+ 32 - 17
PDF Office/PDF Master/Class/Measure/Window/CDistanceMeasureInfoWindowController.swift

@@ -9,6 +9,7 @@ import Cocoa
 
 protocol CDistanceMeasureInfoWindowControllerDelegate: AnyObject {
     func distanceMeasureInfoWindowControllerSetting(_ distanceMeasureInfoWindowController: CDistanceMeasureInfoWindowController)
+    func cancelMeasureInfoWindowControllerSetting(_ distanceMeasureInfoWindowController: CDistanceMeasureInfoWindowController)
 }
 
 @objcMembers
@@ -20,22 +21,28 @@ class CDistanceMeasureInfoWindowController: NSWindowController {
     @IBOutlet weak var angleLabel: NSTextField!
     @IBOutlet weak var xLabel: NSTextField!
     @IBOutlet weak var yLabel: NSTextField!
-    
+    @IBOutlet weak var cancelButton: NSButton!
+
     weak var delegate: CDistanceMeasureInfoWindowControllerDelegate?
     
-    private(set) var measureInfo: CPDFDistanceMeasureInfo
-    
-    init(measureInfo: CPDFDistanceMeasureInfo) {
-        self.measureInfo = measureInfo
-        super.init(window: nil)
-    }
+//    private(set) var measureInfo: CPDFDistanceMeasureInfo = CPDFDistanceMeasureInfo()
+    var measureInfo: CPDFDistanceMeasureInfo = CPDFDistanceMeasureInfo()
     
-    required init?(coder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
+    convenience init() {
+        self.init(windowNibName: "CDistanceMeasureInfoWindowController")
     }
-    
+//    init(measureInfo: CPDFDistanceMeasureInfo) {
+//        self.measureInfo = measureInfo
+//        super.init(window: nil)
+//    }
+//
+//    required init?(coder: NSCoder) {
+//        fatalError("init(coder:) has not been implemented")
+//    }
     override func windowDidLoad() {
         super.windowDidLoad()
+        
+        cancelButton.stringValue = NSLocalizedString("Cancel", comment: "")
 
         self.window?.level = .floating
         commonInit()
@@ -49,11 +56,7 @@ class CDistanceMeasureInfoWindowController: NSWindowController {
         self.measureInfo = measureInfo
         updateLabels()
     }
-    
-    @IBAction func buttonItemClick_Setting(_ sender: Any) {
-        delegate?.distanceMeasureInfoWindowControllerSetting(self)
-    }
-    
+        
     private func commonInit() {
         updateLabels()
     }
@@ -77,7 +80,19 @@ class CDistanceMeasureInfoWindowController: NSWindowController {
         }
         
         let formatValue = measureInfo.formatValue
-        let range = formatValue.index(formatValue.startIndex, offsetBy: 4)..<formatValue.endIndex
-        lengthLabel.stringValue = String(formatValue[range])
+        if formatValue.count > 0 {
+            let range = formatValue.index(formatValue.startIndex, offsetBy: 4)..<formatValue.endIndex
+            lengthLabel.stringValue = String(formatValue[range])
+        }
+    }
+    
+    // MARK: Action
+    
+    @IBAction func buttonItemClick_Setting(_ sender: Any) {
+        delegate?.distanceMeasureInfoWindowControllerSetting(self)
+    }
+
+    @IBAction func buttonItemClick_Cancel(_ sender: Any) {
+        delegate?.cancelMeasureInfoWindowControllerSetting(self)
     }
 }

+ 22 - 2
PDF Office/PDF Master/Class/Measure/Window/CDistanceMeasureInfoWindowController.xib

@@ -6,9 +6,10 @@
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
-        <customObject id="-2" userLabel="File's Owner" customClass="CDistanceMeasureInfoWindowController">
+        <customObject id="-2" userLabel="File's Owner" customClass="CDistanceMeasureInfoWindowController" customModule="PDF_Reader_Pro" customModuleProvider="target">
             <connections>
                 <outlet property="angleLabel" destination="Gab-Do-JHB" id="VP9-HV-d0Z"/>
+                <outlet property="cancelButton" destination="J3O-9a-Yf8" id="KNs-Dv-4N0"/>
                 <outlet property="lengthLabel" destination="pNQ-XS-zSa" id="Hav-iL-DcO"/>
                 <outlet property="precisionLabel" destination="L6K-WZ-ufU" id="8y0-un-1rR"/>
                 <outlet property="scaleLabel" destination="WGH-zp-MrF" id="Hnm-Kh-hg0"/>
@@ -23,7 +24,7 @@
             <windowStyleMask key="styleMask" titled="YES"/>
             <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
             <rect key="contentRect" x="2242" y="1105" width="300" height="280"/>
-            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="1800" height="1125"/>
             <view key="contentView" id="se5-gp-TjO">
                 <rect key="frame" x="0.0" y="0.0" width="300" height="280"/>
                 <autoresizingMask key="autoresizingMask"/>
@@ -209,10 +210,28 @@ DQ
                             <action selector="buttonItemClick_Setting:" target="-2" id="WWZ-MY-WpD"/>
                         </connections>
                     </button>
+                    <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="J3O-9a-Yf8">
+                        <rect key="frame" x="127" y="9" width="79" height="32"/>
+                        <buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" controlSize="large" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="5Wc-fi-Tbr">
+                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                            <font key="font" metaFont="system"/>
+                            <string key="keyEquivalent" base64-UTF8="YES">
+Gw
+</string>
+                        </buttonCell>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="20" id="gDb-Bi-4Sv"/>
+                            <constraint firstAttribute="width" constant="67" id="jPC-Xb-gqp"/>
+                        </constraints>
+                        <connections>
+                            <action selector="buttonItemClick_Cancel:" target="-2" id="X3Y-FR-GUg"/>
+                        </connections>
+                    </button>
                 </subviews>
                 <constraints>
                     <constraint firstItem="UR2-Nl-Rfq" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="18" id="3IR-er-uMJ"/>
                     <constraint firstItem="cj2-uv-leJ" firstAttribute="top" secondItem="xmh-zp-Pme" secondAttribute="bottom" constant="12" id="54Z-Ql-yIA"/>
+                    <constraint firstItem="uof-N3-MWI" firstAttribute="centerY" secondItem="J3O-9a-Yf8" secondAttribute="centerY" id="6Iu-cM-e4A"/>
                     <constraint firstItem="kUi-Hy-7fS" firstAttribute="leading" secondItem="vPQ-p5-Hhs" secondAttribute="trailing" constant="79" id="8QP-Ty-gb5"/>
                     <constraint firstItem="yJ2-cI-hDJ" firstAttribute="top" secondItem="Gab-Do-JHB" secondAttribute="bottom" constant="12" id="8vN-jK-i2E"/>
                     <constraint firstItem="MLG-e9-AAe" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="12" id="Ccv-BI-nig"/>
@@ -222,6 +241,7 @@ DQ
                     <constraint firstItem="bkr-Me-ofi" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="58" id="Kh9-OF-dVO"/>
                     <constraint firstItem="NiN-LM-nI2" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="58" id="SWg-De-edl"/>
                     <constraint firstItem="xmh-zp-Pme" firstAttribute="top" secondItem="NiN-LM-nI2" secondAttribute="bottom" constant="12" id="TyY-JA-v8n"/>
+                    <constraint firstItem="uof-N3-MWI" firstAttribute="leading" secondItem="J3O-9a-Yf8" secondAttribute="trailing" constant="18" id="Uu8-5k-M6L"/>
                     <constraint firstItem="kUi-Hy-7fS" firstAttribute="top" secondItem="yJ2-cI-hDJ" secondAttribute="bottom" constant="12" id="Vcu-5k-hS7"/>
                     <constraint firstItem="WGH-zp-MrF" firstAttribute="leading" secondItem="bkr-Me-ofi" secondAttribute="trailing" constant="52" id="Vgh-Hr-DSF"/>
                     <constraint firstItem="vPQ-p5-Hhs" firstAttribute="top" secondItem="mPW-Bh-h0a" secondAttribute="bottom" constant="12" id="Y8R-Yp-0Tm"/>

+ 5 - 4
PDF Office/PDF Master/Class/Measure/Window/CDistanceSettingWindowController.swift

@@ -32,25 +32,26 @@ import Cocoa
         self.distanceMeasureInfo = distanceMeasureInfo
         self.isDistance = true
         super.init(window: nil)
-//        self.windowNibName = NSNib.Name("CDistanceSettingWindowController")
+        Bundle.main.loadNibNamed("CDistanceSettingWindowController", owner: self, topLevelObjects: nil)
+        commonInit()
     }
     
     @objc init(perimeterMeasureInfo: CPDFPerimeterMeasureInfo) {
         self.perimeterMeasureInfo = perimeterMeasureInfo
         self.isDistance = false
         super.init(window: nil)
-//        self.windowNibName = NSNib.Name("CDistanceSettingWindowController")
+        Bundle.main.loadNibNamed("CDistanceSettingWindowController", owner: self, topLevelObjects: nil)
+        commonInit()
     }
     
     required init?(coder: NSCoder) {
         super.init(coder: coder)
     }
-
     
     override func windowDidLoad() {
         super.windowDidLoad()
 
-        commonInit()
+//        commonInit()
     }
     
     private func commonInit() {

+ 4 - 4
PDF Office/PDF Master/Class/Measure/Window/CDistanceSettingWindowController.xib

@@ -6,7 +6,7 @@
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
-        <customObject id="-2" userLabel="File's Owner" customClass="CDistanceSettingWindowController">
+        <customObject id="-2" userLabel="File's Owner" customClass="CDistanceSettingWindowController" customModule="PDF_Reader_Pro" customModuleProvider="target">
             <connections>
                 <outlet property="doneButton" destination="EVQ-Zh-Ylt" id="C5x-pN-BuG"/>
                 <outlet property="precisionPopButton" destination="vYM-aM-foH" id="Rxw-pg-AKv"/>
@@ -23,7 +23,7 @@
             <windowStyleMask key="styleMask" titled="YES"/>
             <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
             <rect key="contentRect" x="1356" y="682" width="520" height="280"/>
-            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="1800" height="1125"/>
             <view key="contentView" id="se5-gp-TjO">
                 <rect key="frame" x="0.0" y="0.0" width="520" height="280"/>
                 <autoresizingMask key="autoresizingMask"/>
@@ -182,8 +182,8 @@
                         </constraints>
                     </box>
                     <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="cJq-ui-HiL">
-                        <rect key="frame" x="268" y="18" width="110" height="52"/>
-                        <buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="avT-PE-okH">
+                        <rect key="frame" x="269" y="19" width="108" height="52"/>
+                        <buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" controlSize="large" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="avT-PE-okH">
                             <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                             <font key="font" metaFont="system"/>
                             <string key="keyEquivalent" base64-UTF8="YES">

+ 6 - 13
PDF Office/PDF Master/Class/Measure/Window/CPerimeterMeasureInfoWindowController.swift

@@ -7,7 +7,7 @@
 
 import Cocoa
 
-protocol PerimeterMeasureInfoWindowControllerDelegate: AnyObject {
+protocol CPerimeterMeasureInfoWindowControllerDelegate: AnyObject {
     func perimeterMeasureInfoWindowControllerSetting(_ perimeterMeasureInfoWindowController: CPerimeterMeasureInfoWindowController)
 }
 
@@ -19,20 +19,13 @@ class CPerimeterMeasureInfoWindowController: NSWindowController {
     @IBOutlet weak var precisionLabel: NSTextField!
     @IBOutlet weak var angleLabel: NSTextField!
     
-    weak var delegate: PerimeterMeasureInfoWindowControllerDelegate?
-    private(set) var measureInfo: CPDFPerimeterMeasureInfo
+    weak var delegate: CPerimeterMeasureInfoWindowControllerDelegate?
+    var measureInfo: CPDFPerimeterMeasureInfo = CPDFPerimeterMeasureInfo()
     
-    init(measureInfo: CPDFPerimeterMeasureInfo) {
-        self.measureInfo = measureInfo
-        super.init(window: nil)
-//        self.windowNibName = "PerimeterMeasureInfoWindowController"
-        self.window?.level = .floating
-    }
-    
-    required init?(coder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
+    convenience init() {
+        self.init(windowNibName: "CPerimeterMeasureInfoWindowController")
     }
-    
+
     override func windowDidLoad() {
         super.windowDidLoad()
 

+ 18 - 2
PDF Office/PDF Master/Class/Measure/Window/CPerimeterMeasureInfoWindowController.xib

@@ -6,7 +6,7 @@
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
-        <customObject id="-2" userLabel="File's Owner" customClass="CPerimeterMeasureInfoWindowController">
+        <customObject id="-2" userLabel="File's Owner" customClass="CPerimeterMeasureInfoWindowController" customModule="PDF_Reader_Pro" customModuleProvider="target">
             <connections>
                 <outlet property="angleLabel" destination="gE6-un-ONi" id="kGL-pr-10H"/>
                 <outlet property="lengthLabel" destination="Esk-Mt-wGg" id="tGT-uA-ElU"/>
@@ -21,7 +21,7 @@
             <windowStyleMask key="styleMask" titled="YES"/>
             <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
             <rect key="contentRect" x="2242" y="1105" width="300" height="230"/>
-            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="1800" height="1125"/>
             <view key="contentView" id="se5-gp-TjO">
                 <rect key="frame" x="0.0" y="0.0" width="300" height="230"/>
                 <autoresizingMask key="autoresizingMask"/>
@@ -159,6 +159,20 @@ DQ
                             <action selector="buttonItemClick_Setting:" target="-2" id="hqK-Ww-vbZ"/>
                         </connections>
                     </button>
+                    <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aSX-Nt-h63">
+                        <rect key="frame" x="127" y="9" width="79" height="32"/>
+                        <buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" controlSize="large" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="AQo-Cp-Fqj">
+                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                            <font key="font" metaFont="system"/>
+                            <string key="keyEquivalent" base64-UTF8="YES">
+Gw
+</string>
+                        </buttonCell>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="20" id="K9h-SK-6sK"/>
+                            <constraint firstAttribute="width" constant="67" id="ipO-Zw-sdb"/>
+                        </constraints>
+                    </button>
                 </subviews>
                 <constraints>
                     <constraint firstItem="D8T-iy-XgH" firstAttribute="leading" secondItem="mx9-KK-QVJ" secondAttribute="trailing" constant="28" id="0Su-zR-vCj"/>
@@ -172,8 +186,10 @@ DQ
                     <constraint firstItem="S8f-V0-Jcv" firstAttribute="top" secondItem="mx9-KK-QVJ" secondAttribute="bottom" constant="12" id="Ews-FC-6cx"/>
                     <constraint firstItem="mx9-KK-QVJ" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="58" id="GCw-3z-Jei"/>
                     <constraint firstItem="mx9-KK-QVJ" firstAttribute="top" secondItem="GMr-eD-dPe" secondAttribute="bottom" constant="12" id="QrC-ho-Jq2"/>
+                    <constraint firstItem="7fr-3C-l1g" firstAttribute="centerY" secondItem="aSX-Nt-h63" secondAttribute="centerY" id="RGr-8k-ahf"/>
                     <constraint firstItem="gE6-un-ONi" firstAttribute="leading" secondItem="S8f-V0-Jcv" secondAttribute="trailing" constant="51" id="SMR-Wh-NoQ"/>
                     <constraint firstItem="FkT-se-g48" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="58" id="Sv7-4f-CfJ"/>
+                    <constraint firstItem="7fr-3C-l1g" firstAttribute="leading" secondItem="aSX-Nt-h63" secondAttribute="trailing" constant="18" id="TiS-xD-6u8"/>
                     <constraint firstItem="D8T-iy-XgH" firstAttribute="top" secondItem="Esk-Mt-wGg" secondAttribute="bottom" constant="12" id="bLG-hD-8Ma"/>
                     <constraint firstItem="fuf-bl-vhH" firstAttribute="leading" secondItem="O2f-Vz-OLT" secondAttribute="trailing" constant="16" id="f7Q-Bc-txQ"/>
                     <constraint firstItem="Esk-Mt-wGg" firstAttribute="leading" secondItem="GMr-eD-dPe" secondAttribute="trailing" constant="43" id="hXv-jp-zAy"/>

+ 36 - 0
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFKitExtensions/CPDFAnnotationExtensions/CPDFLineAnnotation+PDFListView.swift

@@ -94,6 +94,10 @@ import Foundation
         self.endPoint = point
     }
     
+    func setObservedMeasureInfo(_ distanceMeasureInfo: CPDFDistanceMeasureInfo) {
+        self.measureInfo = distanceMeasureInfo
+    }
+    
     override func resizeHandleForPoint(_ point: NSPoint, scaleFactor: CGFloat) -> CRectEdges {
         if (!self.isResizable()) {
             return CRectEdges(rawValue: 0)
@@ -124,6 +128,38 @@ import Foundation
         return CPDFLineAnnotation._l_keys
     }
     
+    @objc func pointsFromMeasure(startPoint: CGPoint, endPoint: CGPoint) -> [NSValue] {
+        var pointValues = [NSValue]()
+        guard let distanceMeasureInfo = self.measureInfo else {
+            return pointValues
+        }
+        let normalVector = self.calculateNormalVector(startPoint: startPoint, endPoint: endPoint)
+        let translatedStartPoint = self.translate(point: startPoint, withNormalVector: normalVector, distance: distanceMeasureInfo.leadLength)
+        let translatedEndPoint = self.translate(point: endPoint, withNormalVector: normalVector, distance: distanceMeasureInfo.leadLength)
+        pointValues.append(NSValue(point: startPoint))
+        pointValues.append(NSValue(point: translatedStartPoint))
+        pointValues.append(NSValue(point: translatedEndPoint))
+        pointValues.append(NSValue(point: endPoint))
+        return pointValues
+    }
+
+    @objc func translate(point: CGPoint, withNormalVector normalVector: CGPoint, distance: CGFloat) -> CGPoint {
+        let translatedPoint = CGPoint(x: point.x + normalVector.x * distance, y: point.y + normalVector.y * distance)
+        return translatedPoint
+    }
+
+    @objc func calculateNormalVector(startPoint: CGPoint, endPoint: CGPoint) -> CGPoint {
+        let dx = endPoint.x - startPoint.x
+        let dy = endPoint.y - startPoint.y
+        let length = sqrt(dx * dx + dy * dy)
+        
+        if length > 0 {
+            return CGPoint(x: -dy / length, y: dx / length)
+        } else {
+            return CGPoint.zero
+        }
+    }
+
     class func annotationImage(annotationModel: CPDFAnnotationModel) -> NSImage? {
         let image = NSImage(size: CGSizeMake(50+annotationModel.lineWidth(), 50+annotationModel.lineWidth()))
         image.lockFocus()

+ 143 - 0
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFKitExtensions/CPDFAnnotationExtensions/CPDFPolygonAnnotation+PDFListView.swift

@@ -0,0 +1,143 @@
+//
+//  CPDFPolygonAnnotation+PDFListView.swift
+//  PDF Reader Pro
+//
+//  Created by wanjun on 2024/7/17.
+//
+
+import Foundation
+
+@objc extension CPDFPolygonAnnotation {
+    func drawSelectionHighlight(for pdfView: CPDFListView, in context: CGContext, isHover: Bool) {
+        guard !NSIsEmptyRect(self.bounds) else { return }
+
+        if self.isResizable() {
+            if (pdfView.activeAnnotations.count == 1 || pdfView.selectAnnotations.count > 0) || isHover {
+                guard let pointsArray = self.savePoints as? [NSValue] else { return }
+                let delta = 4.0 * pdfView.unitWidth(on: self.page)
+                for saveValue in pointsArray {
+                    let savePoint = saveValue.pointValue
+                    CPDFListViewDrawResizeHandle(context, savePoint, delta, true)
+                }
+            } else {
+                let rect = self.bounds
+                let lineWidth = pdfView.unitWidth(on: self.page)
+                context.saveGState()
+                let color = CPDFListViewConfig.defaultManager.annotationBorderColor.cgColor
+                context.setStrokeColor(color)
+                if isHover {
+                    let lengths: [CGFloat] = [5, 5]
+                    context.setLineDash(phase: 0, lengths: lengths)
+                    context.stroke(rect.insetBy(dx: 0, dy: 0), width: lineWidth)
+                } else {
+                    context.stroke(rect.insetBy(dx: 0, dy: 0), width: lineWidth)
+                }
+                context.restoreGState()
+            }
+        }
+        self.drawPolygonStart(in: context)
+    }
+
+    func borderRect(for pdfView: CPDFListView) -> CGRect {
+        let rect = pdfView.integralRect(self.bounds, on: self.page)
+        return rect
+    }
+
+    func resizeHandle(for point: NSPoint, scaleFactor: CGFloat) -> CRectEdges {
+        guard self.isResizable() else { return CRectEdges(rawValue: 0) }
+
+        let size = CPDFListViewMakeSquareSize(8 / scaleFactor)
+        if CPDFListViewConfig.defaultManager.isSquareFromPolygon {
+            guard let savePoints = self.savePoints as? [NSValue] else { return CRectEdges(rawValue: 0) }
+            for saveValue in savePoints {
+                let savePoint = saveValue.pointValue
+                if NSPointInRect(point, CPDFListViewRectFromCenterAndSize(savePoint, size)) {
+                    switch savePoints.firstIndex(of: saveValue) {
+                    case 3:
+                        return [.minXEdgeMask, .maxYEdgeMask]
+                    case 2:
+                        return [.maxXEdgeMask, .maxYEdgeMask]
+                    case 1:
+                        return [.maxXEdgeMask, .minYEdgeMask]
+                    case 0:
+                        return [.minXEdgeMask, .minYEdgeMask]
+                    default:
+                        return CRectEdges(rawValue: 0)
+                    }
+                }
+            }
+        } else {
+            guard let savePoints = self.savePoints as? [NSValue] else { return CRectEdges(rawValue: 0) }
+            for saveValue in savePoints {
+                let savePoint = saveValue.pointValue
+                if NSPointInRect(point, CPDFListViewRectFromCenterAndSize(savePoint, size)) {
+                    CPDFListViewConfig.defaultManager.polygonSelectIndex = savePoints.firstIndex(of: saveValue) ?? NSNotFound
+                    return .minXEdgeMask
+                }
+            }
+        }
+
+        if self.hitTest(point) {
+            return .editInEdgeMask
+        } else {
+            return CRectEdges(rawValue: 0)
+        }
+    }
+
+    override func isResizable() -> Bool {
+        return true
+    }
+
+    override func isMovable() -> Bool {
+        return true
+    }
+
+    override func hitTest(_ point: NSPoint) -> Bool {
+        let delta = max(4.0, 0.5 * self.lineWidth())
+        guard let pointsArray = self.savePoints as? [NSValue] else { return false }
+        if pointsArray.count >= 2 {
+            for i in 0..<pointsArray.count - 1 {
+                let pointValueA = pointsArray[i]
+                let pointValueB = pointsArray[i + 1]
+                let pointA = pointValueA.pointValue
+                let pointB = pointValueB.pointValue
+                if CPDFListViewPointNearLineFromPointToPoint(point, pointA, pointB, delta) {
+                    return self.shouldDisplay() && CPDFListViewPointNearLineFromPointToPoint(point, pointA, pointB, delta)
+                }
+            }
+            let startPoint = pointsArray.first!.pointValue
+            let endPoint = pointsArray.last!.pointValue
+            if CPDFListViewPointNearLineFromPointToPoint(point, startPoint, endPoint, delta) {
+                return self.shouldDisplay() && CPDFListViewPointNearLineFromPointToPoint(point, startPoint, endPoint, delta)
+            }
+        }
+        return false
+    }
+
+    override func keysForValuesToObserveForUndo() -> Set<AnyHashable> {
+        var superKeys = super.keysForValuesToObserveForUndo()
+        let additionalKeys: Set<AnyHashable> = ["cFont",
+                                                "fontColor",
+                                                "savePoints",
+                                                "interiorOpacity",
+                                                "interiorColor"]
+        superKeys!.formUnion(additionalKeys)
+        return superKeys!
+    }
+
+    func drawPolygonStart(in context: CGContext) {
+        guard let pointsArray = self.savePoints as? [NSValue], pointsArray.count == 2 else { return }
+        let startPoint = pointsArray.first!.pointValue
+        let endPoint = pointsArray.last!.pointValue
+        context.saveGState()
+        let color = self.color.cgColor
+        context.setStrokeColor(color)
+        let dashs: [CGFloat] = [5.0, 5.0]
+        context.setLineDash(phase: 0, lengths: dashs)
+        context.move(to: CGPoint(x: startPoint.x, y: startPoint.y))
+        context.addLine(to: CGPoint(x: endPoint.x, y: endPoint.y))
+        context.strokePath()
+        context.restoreGState()
+    }
+
+}

+ 95 - 0
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFKitExtensions/CPDFAnnotationExtensions/CPDFPolylineAnnotation+PDFListView.swift

@@ -0,0 +1,95 @@
+//
+//  CPDFPolylineAnnotation+PDFListView.swift
+//  PDF Reader Pro
+//
+//  Created by wanjun on 2024/7/17.
+//
+
+import Foundation
+
+@objc extension CPDFPolylineAnnotation {
+    func drawSelectionHighlight(for pdfView: CPDFListView, in context: CGContext, isHover: Bool) {
+        guard !NSIsEmptyRect(self.bounds) else { return }
+        if self.isResizable() {
+            if (pdfView.activeAnnotations.count == 1 || pdfView.selectAnnotations.count > 0) || isHover {
+                let pointsArray = self.savePoints()
+                let delta = 4.0 * pdfView.unitWidth(on: self.page)
+                for saveValue in pointsArray {
+                    let savePoint = saveValue.pointValue
+                    CPDFListViewDrawResizeHandle(context, savePoint, delta, true)
+                }
+            } else {
+                let rect = self.bounds
+                let lineWidth = pdfView.unitWidth(on: self.page)
+                context.saveGState()
+                let color = CPDFListViewConfig.defaultManager.annotationBorderColor.cgColor
+                context.setStrokeColor(color)
+                if isHover {
+                    let lengths: [CGFloat] = [5, 5]
+                    context.setLineDash(phase: 0, lengths: lengths)
+                    context.stroke(rect, width: lineWidth)
+                } else {
+                    context.stroke(rect.insetBy(dx: 0, dy: 0), width: lineWidth)
+                }
+                context.restoreGState()
+            }
+        }
+    }
+    
+    func resizeHandle(for point: NSPoint, scaleFactor: CGFloat) -> CRectEdges {
+        guard self.isResizable() else { return [] }
+        let size = CPDFListViewMakeSquareSize(8 / scaleFactor)
+        for saveValue in self.savePoints() {
+            let savePoint = saveValue.pointValue
+            if NSPointInRect(point, CPDFListViewRectFromCenterAndSize(savePoint, size)) {
+                CPDFListViewConfig.defaultManager.polylineSelectIndex = self.savePoints().firstIndex(of: saveValue)!
+                return .minXEdgeMask
+            }
+        }
+        
+        if self.hitTest(point) {
+            return .editInEdgeMask
+        } else {
+            return []
+        }
+    }
+    
+    override func keysForValuesToObserveForUndo() -> Set<AnyHashable> {
+        var superKeys = super.keysForValuesToObserveForUndo()
+        let additionalKeys: Set<AnyHashable> = ["cFont",
+                                                "fontColor",
+                                                "savePoints",
+                                                "interiorOpacity",
+                                                "interiorColor"]
+        superKeys!.formUnion(additionalKeys)
+        return superKeys!
+    }
+    
+    override func isResizable() -> Bool {
+        return true
+    }
+
+    override func isMovable() -> Bool {
+        return true
+    }
+    
+    override func hitTest(_ point: NSPoint) -> Bool {
+        let delta = max(4.0, 0.5 * self.lineWidth())
+        let pointsArray = self.savePoints()
+        if pointsArray.count >= 2 {
+            for i in 0..<pointsArray.count - 1 {
+                let pointValueA = pointsArray[i]
+                let pointValueB = pointsArray[i + 1]
+                let pointA = pointValueA.pointValue
+                let pointB = pointValueB.pointValue
+                
+                let isNear = CPDFListViewPointNearLineFromPointToPoint(pointA, pointB, point, delta)
+                if isNear {
+                    return self.shouldDisplay() && isNear
+                }
+            }
+        }
+        return false
+    }
+
+}

+ 16 - 0
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListView+Private.h

@@ -92,6 +92,22 @@ enum {
 
 @property (nonatomic,assign) BOOL isEditImage;
 
+@property (nonatomic, retain) CPDFPolylineAnnotation *clickPolylineAnnotation;
+
+@property (nonatomic, assign) NSUInteger polylineClickNumber;
+
+@property (nonatomic, retain) CPDFPolygonAnnotation *clickPolygonAnnotation;
+
+@property (nonatomic, retain) CPDFPolygonAnnotation *clickSquareFronPolygonAnnotation;
+
+@property (nonatomic, assign) BOOL isActiveSquare;
+
+@property (nonatomic, assign) NSPoint clickSquareFronPolygonOriginalPagePoint;
+
+@property (nonatomic, assign) NSRect clickSquareFronPolygonOriginalBounds;
+
+@property (nonatomic, assign) NSUInteger polygonClickNumber;
+
 - (void)updateIsRightActiveAnnotations:(NSArray<CPDFAnnotation *> *)activeAnnotations;
 
 - (void)addAnnotation:(CPDFAnnotation *)annotation toPage:(CPDFPage *)page;

+ 11 - 2
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListView.h

@@ -52,8 +52,8 @@ typedef NS_ENUM(NSInteger, CAnnotationType) {
     CAnnotationTypeArrow,
     CAnnotationTypeSquare,
     CAnnotationTypeCircle,
-    /*CAnnotationTypePolyGon,*/
-    /*CAnnotationTypePolyLine,*/
+    CAnnotationTypePolyGon,
+    CAnnotationTypePolyLine,
     CAnnotationTypeHighlight,
     CAnnotationTypeUnderline,
 //    CAnnotationTypeSquiggly,
@@ -102,6 +102,7 @@ typedef NS_ENUM(NSInteger, CToolMode) {
     CFormToolMode,
     CSelfSignMode,
     CRedactToolMode,
+    CMeasureToolMode,
     CRedactErasureToolMode,
     CEditPDFToolMode,
 };
@@ -221,6 +222,12 @@ enum {
 @property (nonatomic,retain) NSTextField  *tableTextField;
 @property (nonatomic, assign) NSPoint dragTablePoint;
 
+// Measurement attribute setting
+@property (nonatomic, retain) CPDFDistanceMeasureInfo *distanceMeasureInfo;
+@property (nonatomic, retain) CPDFPerimeterMeasureInfo *perimeterMeasureInfo;
+@property (nonatomic, retain) CPDFAreaMeasureInfo *polygonAreaMeasureInfo;
+@property (nonatomic, retain) CPDFAreaMeasureInfo *squareAreaMeasureInfo;
+
 - (CPDFAnnotation *)addAnnotationWithType:(CAnnotationType)annotationType selection:(CPDFSelection *)selection page:(CPDFPage *)page bounds:(NSRect)bounds;
 - (void)addAnnotationWithAnnotation:(CPDFAnnotation *)annotation toPage:(CPDFPage *)page;
 
@@ -335,4 +342,6 @@ enum {
 
 - (void)PDFListView:(CPDFListView *)pdfView documentDataDidChanged:(id)docData withInfo:(NSDictionary *)info;
 
+- (void)PDFListViewAnnotationMeasureInfoChange:(CPDFListView *)pdfListView withAnnotation:(CPDFAnnotation *)annotation;
+
 @end

+ 33 - 4
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListView.m

@@ -91,6 +91,11 @@ NSNotificationName const CPDFListViewDisplayModeChangeNotification = @"CPDFListV
     self.clickLineAnnotation = nil;
     self.isClickDoubleCreatLine = NO;
     
+    self.perimeterMeasureInfo = [[CPDFPerimeterMeasureInfo alloc] init];
+    self.polygonAreaMeasureInfo = [[CPDFAreaMeasureInfo alloc] init];
+    self.squareAreaMeasureInfo = [[CPDFAreaMeasureInfo alloc] init];
+    self.distanceMeasureInfo = [[CPDFDistanceMeasureInfo alloc] init];
+    
     NSArray *sendTypes = [NSArray arrayWithObjects:NSPasteboardTypePDF, NSPasteboardTypeTIFF, nil];
     [NSApp registerServicesMenuSendTypes:sendTypes returnTypes:[NSArray array]];
     
@@ -334,6 +339,10 @@ NSNotificationName const CPDFListViewDisplayModeChangeNotification = @"CPDFListV
         if(CAnnotationTypeLink == annotationType || CAnnotationTypeLink == _annotationType)
             [self setNeedsDisplayAnnotationViewForVisiblePages];
 
+        if(annotationType == CAnnotationTypeUnkown) {
+            [self endMeasureModeAddAnnotation];
+        }
+
         _annotationType = annotationType;
         
         if([self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewChangedAnnotationType:forAnnotationType:)])
@@ -694,15 +703,26 @@ NSNotificationName const CPDFListViewDisplayModeChangeNotification = @"CPDFListV
                 annotation.bounds = bounds;
                 break;
             case CAnnotationTypeSquare:
-                annotation = [[CPDFSquareAnnotation alloc]initWithPDFListViewNoteWith:self.document];
-                annotation.bounds = bounds;
+                if (CMeasureToolMode == self.toolMode) {
+                    annotation = [[CPDFPolygonAnnotation alloc] initWithDocument:self.document];
+                    [CPDFListViewConfig defaultManager].isSquareFromPolygon = NO;
+                    annotation.bounds = bounds;
+                } else {
+                    annotation = [[CPDFSquareAnnotation alloc] initWithPDFListViewNoteWith:self.document];
+                    annotation.bounds = bounds;
+                }
                 break;
             case CAnnotationTypeLine:
                 annotation = [[CPDFLineAnnotation alloc]initWithPDFListViewNoteWith:self.document annotationType:CAnnotationTypeLine];
                 [(CPDFLineAnnotation *)annotation setObservedStartPoint:CGPointMake(bounds.origin.x, bounds.origin.y)];
                 [(CPDFLineAnnotation *)annotation setObservedEndPoint:CGPointMake(bounds.origin.x + bounds.size.width,bounds.origin.y+ bounds.size.height)];
-                [(CPDFLineAnnotation *)annotation setStartLineStyle:CPDFLineStyleNone];
-                [(CPDFLineAnnotation *)annotation setEndLineStyle:CPDFLineStyleNone];
+                if (self.toolMode == CMeasureToolMode) {
+                    [(CPDFLineAnnotation *)annotation setStartLineStyle:CPDFLineStyleOpenArrow];
+                    [(CPDFLineAnnotation *)annotation setEndLineStyle:CPDFLineStyleOpenArrow];
+                } else if (self.toolMode == CNoteToolMode) {
+                    [(CPDFLineAnnotation *)annotation setStartLineStyle:CPDFLineStyleNone];
+                    [(CPDFLineAnnotation *)annotation setEndLineStyle:CPDFLineStyleNone];
+                }
                 break;
             case CAnnotationTypeArrow: {
                 annotation = [[CPDFLineAnnotation alloc]initWithPDFListViewNoteWith:self.document annotationType:CAnnotationTypeArrow];
@@ -754,6 +774,15 @@ NSNotificationName const CPDFListViewDisplayModeChangeNotification = @"CPDFListV
             case CAnnotationTypeRedact:
                 annotation = [self addRedactPDFSelection:selection];
                 break;
+            case CAnnotationTypePolyLine:
+                annotation = [[CPDFPolylineAnnotation alloc] initWithDocument:self.document];
+                annotation.bounds = bounds;
+                break;
+            case CAnnotationTypePolyGon:
+                annotation = [[CPDFPolygonAnnotation alloc] initWithDocument:self.document];
+                [CPDFListViewConfig defaultManager].isSquareFromPolygon = NO;
+                annotation.bounds = bounds;
+                break;
             default:
                 break;
         }

+ 31 - 1
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListViewConfig.swift

@@ -13,7 +13,10 @@ class CPDFListViewConfig: NSObject {
     var _annotationBorderColor: NSColor = NSColor(red: 82.0/255.0, green: 102.0/255.0, blue: 204.0/255.0, alpha: 1)
     var _dragHoverColor: NSColor = NSColor(red: 23/255.0, green: 112/255.0, blue: 244/255.0, alpha: 1.0)
     var isSaveDefault: Bool = false
-    
+    var _isSquareFromPolygon: Bool = false
+    var _polylineSelectIndex: Int = 0
+    var _polygonSelectIndex: Int = 0
+
     static let defaultManager: CPDFListViewConfig = {
         let config = CPDFListViewConfig()
         return config
@@ -47,4 +50,31 @@ class CPDFListViewConfig: NSObject {
             _dragHoverColor = newValue
         }
     }
+    
+    var isSquareFromPolygon: Bool {
+        get {
+            return _isSquareFromPolygon
+        }
+        set {
+            _isSquareFromPolygon = newValue
+        }
+    }
+    
+    var polylineSelectIndex: Int {
+        get {
+            return _polylineSelectIndex
+        }
+        set {
+            _polylineSelectIndex = newValue
+        }
+    }
+    
+    var polygonSelectIndex: Int {
+        get {
+            return _polygonSelectIndex
+        }
+        set {
+            _polygonSelectIndex = newValue
+        }
+    }
 }

文件差异内容过多而无法显示
+ 893 - 18
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListViewExtension/CPDFListView+Event.m


+ 6 - 0
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListViewExtension/CPDFListView+KeyEvent.m

@@ -115,6 +115,12 @@
             [self updateActiveAnnotations:@[]];
             [self setNeedsDisplayAnnotationViewForPage:page];
         }
+    } else if ((self.clickPolylineAnnotation ||
+                self.clickPolygonAnnotation ||
+                self.clickSquareFronPolygonAnnotation ||
+                (self.clickLineAnnotation && self.isClickDoubleCreatLine)) && eventChar == CPDFListEscapeCharacter) {
+        [self endMeasureModeAddAnnotation];
+        [self setNeedsDisplayAnnotationViewForVisiblePages];
     } else if (CAnnotationTypeUnkown != [self annotationType] && eventChar == CPDFListEscapeCharacter) {
         if ((self.toolMode == CEditPDFToolMode) && (self.annotationType == CAnnotationTypeAddText || self.annotationType == CAnnotationTypeAddImage)) {
 //            [[NSNotificationCenter defaultCenter] postNotificationName:@"CEditPDFToolModeChangeStateUnkown" object:self];

+ 4 - 0
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListViewExtension/CPDFListView+Tool.h

@@ -69,6 +69,8 @@ typedef NS_ENUM(NSInteger, CAnnotationAlignState) {
 
 -(void)hidenHUDHint;
 
+- (CGRect)borderRecctForSavePoints:(NSMutableArray<NSValue *> *)savePoints;
+
 // 缩放 鼠标滚轮
 - (void)magnifyWheel:(NSEvent *)theEvent;
 
@@ -87,5 +89,7 @@ typedef NS_ENUM(NSInteger, CAnnotationAlignState) {
 
 - (void)resetPDFToolTipRectsForAfterDelay;
 
+- (void)endMeasureModeAddAnnotation;
+
 @end
 

+ 65 - 1
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListViewExtension/CPDFListView+Tool.m

@@ -235,7 +235,8 @@
         CFormToolMode == self.toolMode ||
         CSelfSignMode == self.toolMode ||
         CRedactToolMode == self.toolMode ||
-        CRedactErasureToolMode == self.toolMode) {
+        CRedactErasureToolMode == self.toolMode ||
+        CMeasureToolMode == self.toolMode) {
         if (self.annotationType == CAnnotationTypeInk || self.annotationType == CAnnotationTypeEraser) {
             return NO;
         }
@@ -429,6 +430,45 @@
     }
 }
 
+- (void)endMeasureModeAddAnnotation {
+    if(self.clickPolylineAnnotation) {
+        NSMutableArray<NSValue *> *savePoints = [NSMutableArray arrayWithArray:self.clickPolylineAnnotation.savePoints];
+        if (savePoints.count >= 2) {
+            if (self.pdfListViewDelegate && [self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewAnnotationMeasureInfoChange:withAnnotation:)]) {
+                [self.pdfListViewDelegate PDFListViewAnnotationMeasureInfoChange:self withAnnotation:self.clickPolylineAnnotation];
+            }
+        }
+        
+        self.clickPolylineAnnotation = nil;
+        self.polylineClickNumber = 0;
+        [self updateActiveAnnotations:@[]];
+
+    } else if (self.clickPolygonAnnotation) {
+        NSMutableArray<NSValue *> *savePoints = [NSMutableArray arrayWithArray:self.clickPolygonAnnotation.savePoints];
+        if (savePoints.count > 2) {
+            if (self.pdfListViewDelegate && [self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewAnnotationMeasureInfoChange:withAnnotation:)]) {
+                [self.pdfListViewDelegate PDFListViewAnnotationMeasureInfoChange:self withAnnotation:self.clickPolygonAnnotation];
+            }
+            
+          
+        } else {
+            [self.clickPolygonAnnotation.page removeAnnotation:self.clickPolygonAnnotation];
+        }
+        self.clickPolygonAnnotation = nil;
+        self.polygonClickNumber = 0;
+        [self updateActiveAnnotations:@[]];
+    } else if (self.clickSquareFronPolygonAnnotation) {
+        if (self.pdfListViewDelegate && [self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewAnnotationMeasureInfoChange:withAnnotation:)]) {
+            [self.pdfListViewDelegate PDFListViewAnnotationMeasureInfoChange:self withAnnotation:self.clickSquareFronPolygonAnnotation];
+        }
+        self.clickSquareFronPolygonAnnotation = nil;
+        [self updateActiveAnnotations:@[]];
+    } else if (self.clickLineAnnotation && self.isClickDoubleCreatLine) {
+        self.clickLineAnnotation = nil;
+        self.isClickDoubleCreatLine = NO;
+    }
+}
+
 - (void)drawLineOfDashByCAShapeLayer:(CGRect)frame withAlignState:(CAnnotationAlignState)state {
     NSColor *lineColor = [CPDFListViewConfig defaultManager].dragHoverColor;
     CGFloat lineWidth = [self unitWidthOnPage:self.currentPage];
@@ -586,6 +626,30 @@
     [self.hoverPopOver close];
 }
 
+- (CGRect)borderRecctForSavePoints:(NSMutableArray<NSValue *> *)savePoints {
+    CGFloat minX = 0;
+    CGFloat minY = 0;
+    CGFloat maxX = 0;
+    CGFloat maxY = 0;
+    
+    for (NSValue *pointValue in savePoints) {
+        CGPoint point = [pointValue pointValue];
+        if (minX > point.x)
+            minX = point.x;
+        
+        if (maxX < point.x)
+            maxX = point.x;
+        
+        if (minY > point.y)
+            minY = point.y;
+            
+        if (maxY < point.y)
+            maxY = point.y;
+    }
+    
+    return CGRectMake(minX, minY, maxX-minX, maxY-minY);
+}
+
 - (void)magnifyWheel:(NSEvent *)theEvent {
     CGFloat dy = [theEvent deltaY];
     dy = dy > 0 ? fmin(0.2, dy) : fmax(-0.2, dy);

+ 195 - 8
PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController+Action.swift

@@ -4262,23 +4262,79 @@ extension KMMainViewController : KMMainToolbarControllerDelegate {
                     return
                 }
             } else if type == .measure {
-                if !IAPProductsManager.default().isAvailableAllFunction(){
-                    KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
-                    return
-                }
+//                if !IAPProductsManager.default().isAvailableAllFunction(){
+//                    KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
+//                    return
+//                }
                 
                 if !self.documentAllowsEdit() {
                     return
                 }
                 
+                self.listView.toolMode = .measureToolMode
+                
+                if distanceMeasureInfoWindowController?.window?.isVisible == true {
+                    distanceMeasureInfoWindowController?.hideFloatingWindow()
+                } else if perimeterMeasureInfoWindowController?.window?.isVisible == true {
+                    perimeterMeasureInfoWindowController?.hideFloatingWindow()
+                } else if areaMeasureInfoWindowController?.window?.isVisible == true {
+                    areaMeasureInfoWindowController?.hideFloatingWindow()
+                }
+
+                if distanceMeasureInfoWindowController == nil {
+                    let measureInfo = CPDFDistanceMeasureInfo()
+//                    distanceMeasureInfoWindowController = CDistanceMeasureInfoWindowController.init(measureInfo: measureInfo)
+                    distanceMeasureInfoWindowController = CDistanceMeasureInfoWindowController()
+                    distanceMeasureInfoWindowController?.measureInfo = measureInfo
+                    distanceMeasureInfoWindowController?.delegate = self
+                }
+                if perimeterMeasureInfoWindowController == nil {
+                    let measureInfo = CPDFPerimeterMeasureInfo()
+                    perimeterMeasureInfoWindowController = CPerimeterMeasureInfoWindowController()
+                    perimeterMeasureInfoWindowController?.measureInfo = measureInfo
+                    perimeterMeasureInfoWindowController?.delegate = self
+                }
+                if areaMeasureInfoWindowController == nil {
+                    let measureInfo = CPDFAreaMeasureInfo()
+                    areaMeasureInfoWindowController = CAreaMeasureInfoWindowController()
+                    areaMeasureInfoWindowController?.measureInfo = measureInfo
+                    areaMeasureInfoWindowController?.delegate = self
+                }
+                
                 if index == 1 {
-                    
+                    self.listView.annotationType = .line
+
+                    distanceMeasureInfoWindowController?.showWindow(nil)
+                    distanceMeasureInfoWindowController?.lengthLabel.stringValue = ""
+                    distanceMeasureInfoWindowController?.angleLabel.stringValue = ""
+                    distanceMeasureInfoWindowController?.xLabel.stringValue = ""
+                    distanceMeasureInfoWindowController?.yLabel.stringValue = ""
                 } else if index == 2 {
-                    
+                    self.listView.annotationType = .polyLine
+
+                    perimeterMeasureInfoWindowController?.showWindow(nil)
+                    perimeterMeasureInfoWindowController?.lengthLabel.stringValue = ""
+                    perimeterMeasureInfoWindowController?.angleLabel.stringValue = ""
                 } else if index == 3 {
-                    
+                    self.listView.annotationType = .polyGon
+
+                    areaMeasureInfoWindowController?.showWindow(nil)
+                    areaMeasureInfoWindowController?.areaLabel.stringValue = ""
+                    areaMeasureInfoWindowController?.angleLabel.stringValue = ""
                 } else if index == 4 {
-                    
+                    self.listView.annotationType = .square
+
+                    areaMeasureInfoWindowController?.showWindow(nil)
+                    areaMeasureInfoWindowController?.areaLabel.stringValue = ""
+                    areaMeasureInfoWindowController?.angleLabel.stringValue = ""
+                } else {
+                    if let isVisible = distanceMeasureInfoWindowController!.window?.isVisible, isVisible {
+                        distanceMeasureInfoWindowController?.hideFloatingWindow()
+                    } else if let isVisible = perimeterMeasureInfoWindowController!.window?.isVisible, isVisible {
+                        perimeterMeasureInfoWindowController?.hideFloatingWindow()
+                    } else if let isVisible = areaMeasureInfoWindowController!.window?.isVisible, isVisible {
+                        areaMeasureInfoWindowController?.hideFloatingWindow()
+                    }
                 }
             }
         }
@@ -4715,6 +4771,137 @@ extension KMMainViewController : KMMainToolbarControllerDelegate {
     }
 }
 
+// MARK: CDistanceMeasureInfoWindowControllerDelegate
+
+extension KMMainViewController : CDistanceMeasureInfoWindowControllerDelegate {
+    func distanceMeasureInfoWindowControllerSetting(_ distanceMeasureInfoWindowController: CDistanceMeasureInfoWindowController) {
+        let distanceSettingWC = CDistanceSettingWindowController(distanceMeasureInfo: self.distanceMeasureInfoWindowController!.measureInfo)
+        self.distanceMeasureInfoWindowController?.hideFloatingWindow()
+        distanceSettingWC.delegate = self
+        distanceSettingWC.startModal("")
+    }
+    
+    func cancelMeasureInfoWindowControllerSetting(_ distanceMeasureInfoWindowController: CDistanceMeasureInfoWindowController) {
+        
+    }
+}
+
+// MARK: CPerimeterMeasureInfoWindowControllerDelegate
+
+extension KMMainViewController : CPerimeterMeasureInfoWindowControllerDelegate {
+    func perimeterMeasureInfoWindowControllerSetting(_ perimeterMeasureInfoWindowController: CPerimeterMeasureInfoWindowController) {
+        let distanceSettingWC = CDistanceSettingWindowController(perimeterMeasureInfo: self.perimeterMeasureInfoWindowController!.measureInfo)
+        self.distanceMeasureInfoWindowController?.hideFloatingWindow()
+        distanceSettingWC.delegate = self
+        distanceSettingWC.startModal("")
+    }
+}
+
+// MARK: CAreaMeasureInfoWindowControllerDelegate
+
+extension KMMainViewController : CAreaMeasureInfoWindowControllerDelegate {
+    func areaMeasureInfoWindowControllerSetting(_ areaMeasureInfoWindowController: CAreaMeasureInfoWindowController) {
+        let areaSettingWC = CAreaSettingWindowController(measureInfo: self.areaMeasureInfoWindowController!.measureInfo)
+        self.areaMeasureInfoWindowController?.hideFloatingWindow()
+        areaSettingWC.delegate = self
+        areaSettingWC.startModal("")
+    }
+}
+
+// MARK: CDistanceSettingWindowControllerDelegate
+
+extension KMMainViewController : CDistanceSettingWindowControllerDelegate {
+    func distanceSettingWindowController(_ distanceSettingWindowController: CDistanceSettingWindowController, distanceMeasureInfo: CPDFDistanceMeasureInfo?) {
+        if distanceMeasureInfo != nil {
+            if self.listView.activeAnnotations.count > 0 {
+                if self.listView.activeAnnotation.isKind(of: CPDFLineAnnotation.self) {
+                    (self.listView.activeAnnotation as! CPDFLineAnnotation).measureInfo = distanceMeasureInfo
+                    self.listView.setNeedsDisplayAnnotationViewFor(self.listView.activeAnnotation.page)
+                }
+                self.distanceMeasureInfoWindowController?.reloadData(with: (self.listView.activeAnnotation as! CPDFLineAnnotation).measureInfo!)
+            } else {
+                distanceMeasureInfo?.leadLength = 0
+                self.listView.distanceMeasureInfo = distanceMeasureInfo
+                self.distanceMeasureInfoWindowController?.reloadData(with: self.listView.distanceMeasureInfo)
+                self.distanceMeasureInfoWindowController?.lengthLabel.stringValue = ""
+                self.distanceMeasureInfoWindowController?.angleLabel.stringValue = ""
+                self.distanceMeasureInfoWindowController?.xLabel.stringValue = ""
+                self.distanceMeasureInfoWindowController?.yLabel.stringValue = ""
+            }
+        }
+        self.distanceMeasureInfoWindowController?.showWindow(self)
+    }
+    
+    func distanceSettingWindowController(_ distanceSettingWindowController: CDistanceSettingWindowController, perimeterMeasureInfo: CPDFPerimeterMeasureInfo?) {
+        if perimeterMeasureInfo != nil {
+            if self.listView.activeAnnotations.count > 0 {
+                if self.listView.activeAnnotation.isKind(of: CPDFPolylineAnnotation.self) {
+                    (self.listView.activeAnnotation as! CPDFPolylineAnnotation).measureInfo = perimeterMeasureInfo
+                    self.listView.setNeedsDisplayAnnotationViewFor(self.listView.activeAnnotation.page)
+                }
+                self.perimeterMeasureInfoWindowController?.reloadData(with: (self.listView.activeAnnotation as! CPDFPolylineAnnotation).measureInfo!)
+            } else {
+                self.listView.perimeterMeasureInfo = perimeterMeasureInfo
+                self.perimeterMeasureInfoWindowController?.reloadData(with: self.listView.perimeterMeasureInfo)
+                self.perimeterMeasureInfoWindowController?.lengthLabel.stringValue = ""
+                self.perimeterMeasureInfoWindowController?.angleLabel.stringValue = ""
+            }
+        }
+        self.perimeterMeasureInfoWindowController?.showWindow(self)
+    }
+}
+
+// MARK: CAreaSettingWindowControllerDelegate
+
+extension KMMainViewController : CAreaSettingWindowControllerDelegate {
+    func areaSettingWindowController(_ areaSettingWindowController: CAreaSettingWindowController, measureInfo: CPDFAreaMeasureInfo?) {
+        if self.listView.annotationType == .square && self.listView.toolMode == .measureToolMode {
+            if measureInfo != nil {
+                if self.listView.activeAnnotations.count > 0 {
+                    if self.listView.activeAnnotation.isKind(of: CPDFPolygonAnnotation.self) {
+                        (self.listView.activeAnnotation as! CPDFPolygonAnnotation).measureInfo = measureInfo
+                        self.listView.setNeedsDisplayAnnotationViewFor(self.listView.activeAnnotation.page)
+                    }
+                    self.areaMeasureInfoWindowController?.reloadData((self.listView.activeAnnotation as! CPDFPolygonAnnotation).measureInfo!)
+                } else {
+                    self.listView.squareAreaMeasureInfo = measureInfo
+                    self.areaMeasureInfoWindowController?.reloadData(self.listView.squareAreaMeasureInfo)
+                    self.areaMeasureInfoWindowController?.areaLabel.stringValue = ""
+                    self.areaMeasureInfoWindowController?.angleLabel.stringValue = ""
+                }
+            }
+            self.areaMeasureInfoWindowController?.showWindow(self)
+        } else if self.listView.annotationType == .polyGon && self.listView.toolMode == .measureToolMode {
+            if measureInfo != nil {
+                if self.listView.activeAnnotations.count > 0 {
+                    if self.listView.activeAnnotation.isKind(of: CPDFPolygonAnnotation.self) {
+                        (self.listView.activeAnnotation as! CPDFPolygonAnnotation).measureInfo = measureInfo
+                        self.listView.setNeedsDisplayAnnotationViewFor(self.listView.activeAnnotation.page)
+                    }
+                    self.areaMeasureInfoWindowController?.reloadData((self.listView.activeAnnotation as! CPDFPolygonAnnotation).measureInfo!)
+                } else {
+                    self.listView.polygonAreaMeasureInfo = measureInfo
+                    self.areaMeasureInfoWindowController?.reloadData(self.listView.polygonAreaMeasureInfo)
+                    self.areaMeasureInfoWindowController?.areaLabel.stringValue = ""
+                    self.areaMeasureInfoWindowController?.angleLabel.stringValue = ""
+                }
+            }
+            self.areaMeasureInfoWindowController?.showWindow(self)
+        } else {
+            if measureInfo != nil {
+                if self.listView.activeAnnotations.count > 0 {
+                    if self.listView.activeAnnotation.isKind(of: CPDFPolygonAnnotation.self) {
+                        (self.listView.activeAnnotation as! CPDFPolygonAnnotation).measureInfo = measureInfo
+                        self.listView.setNeedsDisplayAnnotationViewFor(self.listView.activeAnnotation.page)
+                    }
+                    self.areaMeasureInfoWindowController?.reloadData((self.listView.activeAnnotation as! CPDFPolygonAnnotation).measureInfo!)
+                }
+            }
+            self.areaMeasureInfoWindowController?.showWindow(self)
+        }
+    }
+}
+
 // MARK: -
 // MARK: - Mouse
 extension KMMainViewController {

+ 96 - 0
PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController+UI.swift

@@ -1979,5 +1979,101 @@ extension KMMainViewController: CPDFViewDelegate,CPDFListViewDelegate {
         self.rightSideViewController.eidtPDFTextProperty.fontColorChangeAction()
 
     }
+    
+    @objc func PDFListViewAnnotationMeasureInfoChange(_ pdfListView: CPDFListView, with annotation: CPDFAnnotation) {
+          if let lineAnnotation = annotation as? CPDFLineAnnotation {
+              handleLineAnnotation(lineAnnotation)
+          } else if let polylineAnnotation = annotation as? CPDFPolylineAnnotation {
+              handlePolylineAnnotation(polylineAnnotation)
+          } else if let polygonAnnotation = annotation as? CPDFPolygonAnnotation {
+              handlePolygonAnnotation(polygonAnnotation)
+          }
+      }
+      
+      private func handleLineAnnotation(_ annotation: CPDFLineAnnotation) {
+          if perimeterMeasureInfoWindowController?.window?.isVisible == true {
+              perimeterMeasureInfoWindowController?.hideFloatingWindow()
+              distanceMeasureInfoWindowController?.showWindow(self)
+          } else if areaMeasureInfoWindowController?.window?.isVisible == true {
+              areaMeasureInfoWindowController?.hideFloatingWindow()
+              distanceMeasureInfoWindowController?.showWindow(self)
+          } else if distanceMeasureInfoWindowController?.window?.isVisible == false {
+              distanceMeasureInfoWindowController?.showWindow(self)
+          }
+          
+          let measureInfo = annotation.measureInfo
+          let startPoint = annotation.startPoint
+          let endPoint = annotation.endPoint
+          let angle = atan2(endPoint.y - startPoint.y, endPoint.x - startPoint.x) * (180.0 / .pi)
+          
+          distanceMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle))
+          distanceMeasureInfoWindowController?.xLabel.stringValue = String(format: "%.0f", abs(endPoint.x - startPoint.x))
+          distanceMeasureInfoWindowController?.yLabel.stringValue = String(format: "%.0f", abs(endPoint.y - startPoint.y))
+          distanceMeasureInfoWindowController?.reloadData(with: measureInfo!)
+      }
+      
+      private func handlePolylineAnnotation(_ annotation: CPDFPolylineAnnotation) {
+          if distanceMeasureInfoWindowController?.window?.isVisible == true {
+              distanceMeasureInfoWindowController?.hideFloatingWindow()
+              perimeterMeasureInfoWindowController?.showWindow(self)
+          } else if areaMeasureInfoWindowController?.window?.isVisible == true {
+              areaMeasureInfoWindowController?.hideFloatingWindow()
+              perimeterMeasureInfoWindowController?.showWindow(self)
+          } else if perimeterMeasureInfoWindowController?.window?.isVisible == false {
+              perimeterMeasureInfoWindowController?.showWindow(self)
+          }
+          
+          let measureInfo = annotation.measureInfo
+          let savePoints = annotation.savePoints()
+          var angle: CGFloat = 0
+          if savePoints.count >= 3 {
+              let count = savePoints.count
+              let startPoint = savePoints[count - 3].pointValue
+              let midPoint = savePoints[count - 2].pointValue
+              let endPoint = savePoints.last!.pointValue
+              
+              angle = angleBetweenPoints(startPoint, midPoint, endPoint)
+          }
+          
+          perimeterMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle))
+          perimeterMeasureInfoWindowController?.reloadData(with: measureInfo!)
+      }
+      
+      private func handlePolygonAnnotation(_ annotation: CPDFPolygonAnnotation) {
+          if distanceMeasureInfoWindowController?.window?.isVisible == true {
+              distanceMeasureInfoWindowController?.hideFloatingWindow()
+              areaMeasureInfoWindowController?.showWindow(self)
+          } else if perimeterMeasureInfoWindowController?.window?.isVisible == true {
+              perimeterMeasureInfoWindowController?.hideFloatingWindow()
+              areaMeasureInfoWindowController?.showWindow(self)
+          } else if areaMeasureInfoWindowController?.window?.isVisible == false {
+              areaMeasureInfoWindowController?.showWindow(self)
+          }
+          
+          let measureInfo = annotation.measureInfo
+          let savePoints = annotation.savePoints
+          var angle: CGFloat = 0
+          if savePoints.count >= 3 {
+              let count = savePoints.count
+              let startPoint = (savePoints[count - 3] as AnyObject).pointValue
+              let midPoint = (savePoints[count - 2] as AnyObject).pointValue
+              let endPoint = (savePoints.lastObject as AnyObject).pointValue
+              
+              angle = angleBetweenPoints(startPoint!, midPoint!, endPoint!)
+          }
+          
+          areaMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle))
+          areaMeasureInfoWindowController?.reloadData(measureInfo!)
+      }
+      
+      private func angleBetweenPoints(_ startPoint: CGPoint, _ midPoint: CGPoint, _ endPoint: CGPoint) -> CGFloat {
+          let vector1 = CGPoint(x: midPoint.x - startPoint.x, y: midPoint.y - startPoint.y)
+          let vector2 = CGPoint(x: endPoint.x - midPoint.x, y: endPoint.y - midPoint.y)
+          let dotProduct = vector1.x * vector2.x + vector1.y * vector2.y
+          let magnitude1 = sqrt(vector1.x * vector1.x + vector1.y * vector1.y)
+          let magnitude2 = sqrt(vector2.x * vector2.x + vector2.y * vector2.y)
+          
+          return acos(dotProduct / (magnitude1 * magnitude2)) * (180.0 / .pi)
+      }
 }
 

+ 14 - 0
PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController.swift

@@ -205,6 +205,10 @@ import Cocoa
         }
     }
     
+    var distanceMeasureInfoWindowController: CDistanceMeasureInfoWindowController?
+    var perimeterMeasureInfoWindowController: CPerimeterMeasureInfoWindowController?
+    var areaMeasureInfoWindowController: CAreaMeasureInfoWindowController?
+    
     deinit {
         NotificationCenter.default.removeObserver(self)
         
@@ -574,6 +578,16 @@ import Cocoa
             self.removeAllAnnotationsStore.store(t: self.listView)
         }
     }
+
+    @objc func cancelMeasureType() {
+        if distanceMeasureInfoWindowController?.window?.isVisible == true {
+            distanceMeasureInfoWindowController?.hideFloatingWindow()
+        } else if perimeterMeasureInfoWindowController?.window?.isVisible == true {
+            perimeterMeasureInfoWindowController?.hideFloatingWindow()
+        } else if areaMeasureInfoWindowController?.window?.isVisible == true {
+            areaMeasureInfoWindowController?.hideFloatingWindow()
+        }
+    }
     
     // MARK: Set Methods
     

+ 16 - 0
PDF Office/PDF Reader Pro.xcodeproj/project.pbxproj

@@ -664,6 +664,12 @@
 		9F41FDA92C464196008A6B82 /* CAreaSettingWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9F41FDA52C464196008A6B82 /* CAreaSettingWindowController.xib */; };
 		9F41FDAA2C464196008A6B82 /* CAreaSettingWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9F41FDA52C464196008A6B82 /* CAreaSettingWindowController.xib */; };
 		9F41FDAB2C464196008A6B82 /* CAreaSettingWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9F41FDA52C464196008A6B82 /* CAreaSettingWindowController.xib */; };
+		9F41FDAD2C47D719008A6B82 /* CPDFPolylineAnnotation+PDFListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F41FDAC2C47D719008A6B82 /* CPDFPolylineAnnotation+PDFListView.swift */; };
+		9F41FDAE2C47D719008A6B82 /* CPDFPolylineAnnotation+PDFListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F41FDAC2C47D719008A6B82 /* CPDFPolylineAnnotation+PDFListView.swift */; };
+		9F41FDAF2C47D719008A6B82 /* CPDFPolylineAnnotation+PDFListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F41FDAC2C47D719008A6B82 /* CPDFPolylineAnnotation+PDFListView.swift */; };
+		9F41FDB12C47DFD3008A6B82 /* CPDFPolygonAnnotation+PDFListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F41FDB02C47DFD3008A6B82 /* CPDFPolygonAnnotation+PDFListView.swift */; };
+		9F41FDB22C47DFD3008A6B82 /* CPDFPolygonAnnotation+PDFListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F41FDB02C47DFD3008A6B82 /* CPDFPolygonAnnotation+PDFListView.swift */; };
+		9F41FDB32C47DFD3008A6B82 /* CPDFPolygonAnnotation+PDFListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F41FDB02C47DFD3008A6B82 /* CPDFPolygonAnnotation+PDFListView.swift */; };
 		9F512CC72B4640AB00EC0BC3 /* KMPageDisplayCustomThemesCollectionViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F512CC52B4640AB00EC0BC3 /* KMPageDisplayCustomThemesCollectionViewItem.swift */; };
 		9F512CC82B4640AB00EC0BC3 /* KMPageDisplayCustomThemesCollectionViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F512CC52B4640AB00EC0BC3 /* KMPageDisplayCustomThemesCollectionViewItem.swift */; };
 		9F512CC92B4640AB00EC0BC3 /* KMPageDisplayCustomThemesCollectionViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F512CC52B4640AB00EC0BC3 /* KMPageDisplayCustomThemesCollectionViewItem.swift */; };
@@ -5585,6 +5591,8 @@
 		9F41FD9D2C463F6B008A6B82 /* CDistanceSettingWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CDistanceSettingWindowController.xib; sourceTree = "<group>"; };
 		9F41FDA42C464196008A6B82 /* CAreaSettingWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CAreaSettingWindowController.swift; sourceTree = "<group>"; };
 		9F41FDA52C464196008A6B82 /* CAreaSettingWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CAreaSettingWindowController.xib; sourceTree = "<group>"; };
+		9F41FDAC2C47D719008A6B82 /* CPDFPolylineAnnotation+PDFListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CPDFPolylineAnnotation+PDFListView.swift"; sourceTree = "<group>"; };
+		9F41FDB02C47DFD3008A6B82 /* CPDFPolygonAnnotation+PDFListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CPDFPolygonAnnotation+PDFListView.swift"; sourceTree = "<group>"; };
 		9F512CC52B4640AB00EC0BC3 /* KMPageDisplayCustomThemesCollectionViewItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMPageDisplayCustomThemesCollectionViewItem.swift; sourceTree = "<group>"; };
 		9F512CC62B4640AB00EC0BC3 /* KMPageDisplayCustomThemesCollectionViewItem.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMPageDisplayCustomThemesCollectionViewItem.xib; sourceTree = "<group>"; };
 		9F512CCD2B469A7600EC0BC3 /* KMPageDisplayThemeCollectionViewItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMPageDisplayThemeCollectionViewItem.swift; sourceTree = "<group>"; };
@@ -13681,6 +13689,8 @@
 				BB6013832AD3A0DE00A76FB2 /* CPDFTextWidgetAnnotation+PDFListView.swift */,
 				BB6013872AD3A3CB00A76FB2 /* CPDFWidgetAnnotation+PDFListView.swift */,
 				BB60138B2AD3A94200A76FB2 /* CPDFSignatureAnnotation+PDFListView.swift */,
+				9F41FDAC2C47D719008A6B82 /* CPDFPolylineAnnotation+PDFListView.swift */,
+				9F41FDB02C47DFD3008A6B82 /* CPDFPolygonAnnotation+PDFListView.swift */,
 				9FF816E42AFA5D400087EFC5 /* Table */,
 				F37322C6292DF9410013862C /* SelfSign */,
 			);
@@ -15716,6 +15726,7 @@
 				ADDEEA922AD796FF00EF675D /* KMSelfSignAnnotationFreeText.swift in Sources */,
 				89DB5DA9291B8DE70029624F /* KMOutlineEditViewController.swift in Sources */,
 				BB42A5D62B8ED77B0092C524 /* KMTabbingHintWindowController.swift in Sources */,
+				9F41FDAD2C47D719008A6B82 /* CPDFPolylineAnnotation+PDFListView.swift in Sources */,
 				BBC28F4E2B0F58DD00D73206 /* KMImageToolTipWindow.swift in Sources */,
 				BB6DD80C29347F77001F0544 /* KMSecureEncryptWindowController.swift in Sources */,
 				BBB14A572978E75D00936EDB /* KMRedactMutilPageFlagWindowController.swift in Sources */,
@@ -16355,6 +16366,7 @@
 				9F02018E2A1DDAA500C9B673 /* KMAITranslationWindowController.swift in Sources */,
 				BB88E45829404752002B3655 /* KMPDFConvert.swift in Sources */,
 				9F1FE4CC29406E4700E952CA /* CTTabContentsController.m in Sources */,
+				9F41FDB12C47DFD3008A6B82 /* CPDFPolygonAnnotation+PDFListView.swift in Sources */,
 				BB146FF0299DC0D100784A6A /* GTLRUploadParameters.m in Sources */,
 				BBD8EE932B8EC86A00EB05FE /* AutoSaveFileItem.m in Sources */,
 				AD3AAD232B0B6F9E00DE5FE7 /* KMCompareContentView.swift in Sources */,
@@ -16897,6 +16909,7 @@
 				BB90E4F32AF37F9F00B04B9F /* KMCustomViewButton.swift in Sources */,
 				AD7D5CAA2B906E36006562CD /* CPDFListView+Sync.swift in Sources */,
 				BBF19E9A2B0B3218007154C8 /* KMAnnotationStamp.swift in Sources */,
+				9F41FDAE2C47D719008A6B82 /* CPDFPolylineAnnotation+PDFListView.swift in Sources */,
 				AD0257402A8601CD00EAD5D5 /* KMAppleLoginManager.swift in Sources */,
 				BB4F7E8E2B0C7FE70077EC8C /* KMNoteColorCollectionViewItem.swift in Sources */,
 				ADBC2CFB299CA6B9006280C8 /* KMPrintDuplexPrintingSetView.swift in Sources */,
@@ -17268,6 +17281,7 @@
 				AD9527DC2952EE700039D2BC /* KMPrintPage_C.swift in Sources */,
 				ADBC2D29299DCA76006280C8 /* NSTextField+Layer.swift in Sources */,
 				9F0CB4702967E63100007028 /* KMPropertiesPanelNameSubVC.swift in Sources */,
+				9F41FDB22C47DFD3008A6B82 /* CPDFPolygonAnnotation+PDFListView.swift in Sources */,
 				9FD0FA3229CD947000F2AB0D /* KMOpacityPanel.swift in Sources */,
 				BB89722A294B08720045787C /* KMWatermarkAdjectiveTopBarItemModel.swift in Sources */,
 				BB146FCD299DC0D100784A6A /* GTMSessionUploadFetcher.m in Sources */,
@@ -18140,6 +18154,7 @@
 				BBF19E9B2B0B3218007154C8 /* KMAnnotationStamp.swift in Sources */,
 				9FE0BBED2B0F242C00CD1CAC /* NSUserDefaults_KMExtension.swift in Sources */,
 				BBBB6CDC2AD15B900035AA66 /* CPDFFreeTextAnnotation+PDFListView.swift in Sources */,
+				9F41FDAF2C47D719008A6B82 /* CPDFPolylineAnnotation+PDFListView.swift in Sources */,
 				9FE0BBF22B0F2FB000CD1CAC /* KMAnnotationLineWindowController.swift in Sources */,
 				F37322F5292DF9410013862C /* CSelfSignAnnotationFreeText.m in Sources */,
 				AD5999382AD7D9C200412F8B /* KMPropertiesViewPopController.swift in Sources */,
@@ -18779,6 +18794,7 @@
 				BB853C882AF8BC12009C20C1 /* KMAddPasswordOperationQueue.swift in Sources */,
 				BB10FAE72AFE039E00F18D65 /* KMPDFEditPageRangeWindowController.swift in Sources */,
 				9FDD0F79294FEF64000C4DAD /* KMConvertPDFManager.swift in Sources */,
+				9F41FDB32C47DFD3008A6B82 /* CPDFPolygonAnnotation+PDFListView.swift in Sources */,
 				AD3AAD1D2B0B5B4400DE5FE7 /* KMCompareCoveringWindowController.swift in Sources */,
 				ADDEEA4B2AD38BDB00EF675D /* KMSignatureHelpViewController.swift in Sources */,
 				AD58F4102B1DAAA800299EE0 /* KMPrintDefaultView.swift in Sources */,