Browse Source

Merge branch 'ios_dengkang' into ios

# Conflicts:
#	PDFViewer.xcodeproj/project.pbxproj
#	PDFViewer.xcodeproj/project.xcworkspace/xcuserdata/kdan.xcuserdatad/UserInterfaceState.xcuserstate
#	PDFViewer.xcodeproj/project.xcworkspace/xcuserdata/kdanmobile_2.xcuserdatad/UserInterfaceState.xcuserstate
#	PDFViewer.xcodeproj/xcuserdata/kdanmobile_2.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
#	PDFViewer/Controller/CPDFAddViewController.h
#	PDFViewer/Controller/CPDFAddViewController.m
#	PDFViewer/Controller/CPDFListController.m
#	PDFViewer/Controller/CPDFViewController.m
yangliuhua 2 years ago
parent
commit
f59a437a35
47 changed files with 3279 additions and 123 deletions
  1. 216 3
      PDFViewer.xcodeproj/project.pbxproj
  2. 18 0
      PDFViewer.xcodeproj/project.xcworkspace/xcuserdata/kdan.xcuserdatad/WorkspaceSettings.xcsettings
  3. BIN
      PDFViewer.xcodeproj/project.xcworkspace/xcuserdata/kdanmobile_2.xcuserdatad/UserInterfaceState.xcuserstate
  4. 0 102
      PDFViewer.xcodeproj/xcuserdata/kdanmobile_2.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
  5. 14 0
      PDFViewer.xcodeproj/xcuserdata/kdanmobile_2.xcuserdatad/xcschemes/xcschememanagement.plist
  6. 5 5
      PDFViewer/Base.lproj/Main.storyboard
  7. 1 1
      PDFViewer/Controller/CPDFAddViewController.m
  8. 31 0
      PDFViewer/Controller/CPDFBackgroundSettingViewController.h
  9. 418 0
      PDFViewer/Controller/CPDFBackgroundSettingViewController.m
  10. 33 0
      PDFViewer/Controller/CPDFImageViewController.h
  11. 437 0
      PDFViewer/Controller/CPDFImageViewController.m
  12. 7 1
      PDFViewer/Controller/CPDFListController.m
  13. 32 0
      PDFViewer/Controller/CPDFTextViewController.h
  14. 397 0
      PDFViewer/Controller/CPDFTextViewController.m
  15. 1 0
      PDFViewer/Controller/CPDFViewController.h
  16. 145 11
      PDFViewer/Controller/CPDFViewController.m
  17. 29 0
      PDFViewer/Model/CPDFBackgroundModel.h
  18. 12 0
      PDFViewer/Model/CPDFBackgroundModel.m
  19. 33 0
      PDFViewer/Model/CPDFDataModel.h
  20. 19 0
      PDFViewer/Model/CPDFDataModel.m
  21. 20 0
      PDFViewer/View/CPDFBackgroundPreview.h
  22. 43 0
      PDFViewer/View/CPDFBackgroundPreview.m
  23. 32 0
      PDFViewer/View/CPDFBackgroundSettingView.h
  24. 163 0
      PDFViewer/View/CPDFBackgroundSettingView.m
  25. 22 0
      PDFViewer/View/CPDFBackgroundView.h
  26. 93 0
      PDFViewer/View/CPDFBackgroundView.m
  27. 27 0
      PDFViewer/View/CPDFClipView.h
  28. 30 0
      PDFViewer/View/CPDFClipView.m
  29. 19 0
      PDFViewer/View/CPDFDrawBackgroundView.h
  30. 55 0
      PDFViewer/View/CPDFDrawBackgroundView.m
  31. 18 0
      PDFViewer/View/CPDFDrawImageView.h
  32. 76 0
      PDFViewer/View/CPDFDrawImageView.m
  33. 23 0
      PDFViewer/View/CPDFDrawView.h
  34. 115 0
      PDFViewer/View/CPDFDrawView.m
  35. 18 0
      PDFViewer/View/CPDFEditView.h
  36. 33 0
      PDFViewer/View/CPDFEditView.m
  37. 21 0
      PDFViewer/View/CPDFImagePreview.h
  38. 59 0
      PDFViewer/View/CPDFImagePreview.m
  39. 35 0
      PDFViewer/View/CPDFImageView.h
  40. 156 0
      PDFViewer/View/CPDFImageView.m
  41. 20 0
      PDFViewer/View/CPDFTextPreview.h
  42. 66 0
      PDFViewer/View/CPDFTextPreview.m
  43. 37 0
      PDFViewer/View/CPDFTextView.h
  44. 178 0
      PDFViewer/View/CPDFTextView.m
  45. 21 0
      PDFViewer/View/UIImage+TintColor.h
  46. 51 0
      PDFViewer/View/UIImage+TintColor.m
  47. BIN
      PDFViewer/View/sources/btn_selected.png

+ 216 - 3
PDFViewer.xcodeproj/project.pbxproj

@@ -7,6 +7,14 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		C92BA1912963CAB4009954EF /* UIImage+TintColor.m in Sources */ = {isa = PBXBuildFile; fileRef = C92BA1902963CAB4009954EF /* UIImage+TintColor.m */; };
+		C92BA1942963F806009954EF /* CPDFDrawBackgroundView.m in Sources */ = {isa = PBXBuildFile; fileRef = C92BA1932963F806009954EF /* CPDFDrawBackgroundView.m */; };
+		C92BA1972963F84B009954EF /* CPDFDrawImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = C92BA1962963F84B009954EF /* CPDFDrawImageView.m */; };
+		C92BA19A29651CA3009954EF /* CPDFBackgroundModel.m in Sources */ = {isa = PBXBuildFile; fileRef = C92BA19929651CA3009954EF /* CPDFBackgroundModel.m */; };
+		C96150D2295400B00020F445 /* CPDFDrawView.m in Sources */ = {isa = PBXBuildFile; fileRef = C96150D1295400B00020F445 /* CPDFDrawView.m */; };
+		C96150D529554F660020F445 /* CPDFClipView.m in Sources */ = {isa = PBXBuildFile; fileRef = C96150D429554F660020F445 /* CPDFClipView.m */; };
+		C96384932949E2020055CCCA /* ComPDFKit.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = C96384922949E2020055CCCA /* ComPDFKit.xcframework */; };
+		C9638496294ACC240055CCCA /* CPDFAddViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C9638495294ACC240055CCCA /* CPDFAddViewController.m */; };
 		C96D13932924793800CC92C7 /* btn_more.png in Resources */ = {isa = PBXBuildFile; fileRef = C96D13922924793800CC92C7 /* btn_more.png */; };
 		C96D13962924DD7E00CC92C7 /* CPDFHeaderFooterAddController.m in Sources */ = {isa = PBXBuildFile; fileRef = C96D13952924DD7E00CC92C7 /* CPDFHeaderFooterAddController.m */; };
 		C96D13992924E09300CC92C7 /* CPDFHeaderFooterAddView.m in Sources */ = {isa = PBXBuildFile; fileRef = C96D13982924E09300CC92C7 /* CPDFHeaderFooterAddView.m */; };
@@ -35,6 +43,12 @@
 		C9E65169292CBC31001B2C9D /* MASCompositeConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = C9E6515B292CBC31001B2C9D /* MASCompositeConstraint.m */; };
 		C9E6516A292CBC31001B2C9D /* NSArray+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = C9E6515C292CBC31001B2C9D /* NSArray+MASAdditions.m */; };
 		C9E6517029306274001B2C9D /* CPDFHeaderFooterTextTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = C9E6516F29306274001B2C9D /* CPDFHeaderFooterTextTableView.m */; };
+                C97E91682959B96C007F6943 /* CPDFEditView.m in Sources */ = {isa = PBXBuildFile; fileRef = C97E91672959B96C007F6943 /* CPDFEditView.m */; };
+        C986D3F52962857900EBD4DF /* CPDFBackgroundSettingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C986D3F42962857900EBD4DF /* CPDFBackgroundSettingViewController.m */; };
+        C986D3F8296288C400EBD4DF /* CPDFBackgroundPreview.m in Sources */ = {isa = PBXBuildFile; fileRef = C986D3F7296288C400EBD4DF /* CPDFBackgroundPreview.m */; };
+        C986D3FB296288F700EBD4DF /* CPDFBackgroundView.m in Sources */ = {isa = PBXBuildFile; fileRef = C986D3FA296288F700EBD4DF /* CPDFBackgroundView.m */; };
+        C986D3FE2962A70400EBD4DF /* CPDFBackgroundSettingView.m in Sources */ = {isa = PBXBuildFile; fileRef = C986D3FD2962A70400EBD4DF /* CPDFBackgroundSettingView.m */; };
+        
 		EC62978E29220F8300D339EE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EC62978D29220F8300D339EE /* AppDelegate.m */; };
 		EC62979129220F8300D339EE /* SceneDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EC62979029220F8300D339EE /* SceneDelegate.m */; };
 		EC62979429220F8300D339EE /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EC62979329220F8300D339EE /* ViewController.m */; };
@@ -45,6 +59,24 @@
 		EC6297B8292239A700D339EE /* CPDFModel.m in Sources */ = {isa = PBXBuildFile; fileRef = EC6297B7292239A700D339EE /* CPDFModel.m */; };
 		EC6297BD292239C200D339EE /* CPDFListController.m in Sources */ = {isa = PBXBuildFile; fileRef = EC6297BC292239C200D339EE /* CPDFListController.m */; };
 		ECC8831D2923352B00F6392E /* CPDFViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ECC8831C2923352B00F6392E /* CPDFViewController.m */; };
+		ECD0ABF02928ED9A0091B6EB /* CPDFTextPreview.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0ABE52928ED990091B6EB /* CPDFTextPreview.m */; };
+		ECD0ABF32928ED9A0091B6EB /* CPDFImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0ABE82928ED990091B6EB /* CPDFImageView.m */; };
+		ECD0ABF42928ED9A0091B6EB /* CPDFTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0ABEA2928ED990091B6EB /* CPDFTextView.m */; };
+		ECD0ABF52928ED9A0091B6EB /* CPDFImagePreview.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0ABEC2928ED9A0091B6EB /* CPDFImagePreview.m */; };
+		ECD0AC132928EECB0091B6EB /* MASConstraintMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0ABFB2928EECA0091B6EB /* MASConstraintMaker.m */; };
+		ECD0AC142928EECB0091B6EB /* NSLayoutConstraint+MASDebugAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0ABFE2928EECA0091B6EB /* NSLayoutConstraint+MASDebugAdditions.m */; };
+		ECD0AC152928EECB0091B6EB /* MASLayoutConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0ABFF2928EECA0091B6EB /* MASLayoutConstraint.m */; };
+		ECD0AC162928EECB0091B6EB /* NSArray+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0AC002928EECA0091B6EB /* NSArray+MASAdditions.m */; };
+		ECD0AC172928EECB0091B6EB /* MASConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0AC022928EECA0091B6EB /* MASConstraint.m */; };
+		ECD0AC182928EECB0091B6EB /* MASCompositeConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0AC032928EECA0091B6EB /* MASCompositeConstraint.m */; };
+		ECD0AC192928EECB0091B6EB /* MASViewConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0AC062928EECA0091B6EB /* MASViewConstraint.m */; };
+		ECD0AC1A2928EECB0091B6EB /* ViewController+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0AC092928EECA0091B6EB /* ViewController+MASAdditions.m */; };
+		ECD0AC1C2928EECB0091B6EB /* View+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0AC0D2928EECA0091B6EB /* View+MASAdditions.m */; };
+		ECD0AC1D2928EECB0091B6EB /* MASViewAttribute.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0AC112928EECB0091B6EB /* MASViewAttribute.m */; };
+		ECD0AC202928EF260091B6EB /* btn_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = ECD0AC1F2928EF260091B6EB /* btn_selected.png */; };
+		ECD0AC232928F2A70091B6EB /* CPDFTextViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0AC222928F2A70091B6EB /* CPDFTextViewController.m */; };
+		ECD0AC262928F2E50091B6EB /* CPDFImageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0AC252928F2E50091B6EB /* CPDFImageViewController.m */; };
+		ECD0AC32292B56C90091B6EB /* CPDFDataModel.m in Sources */ = {isa = PBXBuildFile; fileRef = ECD0AC31292B56C90091B6EB /* CPDFDataModel.m */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXCopyFilesBuildPhase section */
@@ -62,7 +94,22 @@
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
-		C96D13922924793800CC92C7 /* btn_more.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = btn_more.png; sourceTree = "<group>"; };
+		C92BA18F2963CAB4009954EF /* UIImage+TintColor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIImage+TintColor.h"; sourceTree = "<group>"; };
+		C92BA1902963CAB4009954EF /* UIImage+TintColor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIImage+TintColor.m"; sourceTree = "<group>"; };
+		C92BA1922963F806009954EF /* CPDFDrawBackgroundView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFDrawBackgroundView.h; sourceTree = "<group>"; };
+		C92BA1932963F806009954EF /* CPDFDrawBackgroundView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFDrawBackgroundView.m; sourceTree = "<group>"; };
+		C92BA1952963F84B009954EF /* CPDFDrawImageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFDrawImageView.h; sourceTree = "<group>"; };
+		C92BA1962963F84B009954EF /* CPDFDrawImageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFDrawImageView.m; sourceTree = "<group>"; };
+		C92BA19829651CA3009954EF /* CPDFBackgroundModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFBackgroundModel.h; sourceTree = "<group>"; };
+		C92BA19929651CA3009954EF /* CPDFBackgroundModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFBackgroundModel.m; sourceTree = "<group>"; };
+		C96150D0295400B00020F445 /* CPDFDrawView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFDrawView.h; sourceTree = "<group>"; };
+		C96150D1295400B00020F445 /* CPDFDrawView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFDrawView.m; sourceTree = "<group>"; };
+		C96150D329554F660020F445 /* CPDFClipView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFClipView.h; sourceTree = "<group>"; };
+		C96150D429554F660020F445 /* CPDFClipView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFClipView.m; sourceTree = "<group>"; };
+		C96384922949E2020055CCCA /* ComPDFKit.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = ComPDFKit.xcframework; sourceTree = "<group>"; };
+		C9638494294ACC240055CCCA /* CPDFAddViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFAddViewController.h; sourceTree = "<group>"; };
+		C9638495294ACC240055CCCA /* CPDFAddViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFAddViewController.m; sourceTree = "<group>"; };
+		C96D13922924793800CC92C7 /* btn_more.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = btn_more.png; sourceTree =
 		C96D13942924DD7E00CC92C7 /* CPDFHeaderFooterAddController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFHeaderFooterAddController.h; sourceTree = "<group>"; };
 		C96D13952924DD7E00CC92C7 /* CPDFHeaderFooterAddController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFHeaderFooterAddController.m; sourceTree = "<group>"; };
 		C96D13972924E09300CC92C7 /* CPDFHeaderFooterAddView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CPDFHeaderFooterAddView.h; path = PDFViewer/Controller/CPDFHeaderFooterAddView.h; sourceTree = SOURCE_ROOT; };
@@ -114,6 +161,17 @@
 		C9E6515F292CBC31001B2C9D /* MASConstraint+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MASConstraint+Private.h"; sourceTree = "<group>"; };
 		C9E6516E29306274001B2C9D /* CPDFHeaderFooterTextTableView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFHeaderFooterTextTableView.h; sourceTree = "<group>"; };
 		C9E6516F29306274001B2C9D /* CPDFHeaderFooterTextTableView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFHeaderFooterTextTableView.m; sourceTree = "<group>"; };
+                C97E91662959B96C007F6943 /* CPDFEditView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFEditView.h; sourceTree = "<group>"; };
+        C97E91672959B96C007F6943 /* CPDFEditView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFEditView.m; sourceTree = "<group>"; };
+        C986D3F32962857900EBD4DF /* CPDFBackgroundSettingViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFBackgroundSettingViewController.h; sourceTree = "<group>"; };
+        C986D3F42962857900EBD4DF /* CPDFBackgroundSettingViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFBackgroundSettingViewController.m; sourceTree = "<group>"; };
+        C986D3F6296288C400EBD4DF /* CPDFBackgroundPreview.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFBackgroundPreview.h; sourceTree = "<group>"; };
+        C986D3F7296288C400EBD4DF /* CPDFBackgroundPreview.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFBackgroundPreview.m; sourceTree = "<group>"; };
+        C986D3F9296288F700EBD4DF /* CPDFBackgroundView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFBackgroundView.h; sourceTree = "<group>"; };
+        C986D3FA296288F700EBD4DF /* CPDFBackgroundView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFBackgroundView.m; sourceTree = "<group>"; };
+        C986D3FC2962A70400EBD4DF /* CPDFBackgroundSettingView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFBackgroundSettingView.h; sourceTree = "<group>"; };
+        C986D3FD2962A70400EBD4DF /* CPDFBackgroundSettingView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFBackgroundSettingView.m; sourceTree = "<group>"; };
+
 		EC62978929220F8300D339EE /* PDFViewer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PDFViewer.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		EC62978C29220F8300D339EE /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
 		EC62978D29220F8300D339EE /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
@@ -132,6 +190,46 @@
 		EC6297BC292239C200D339EE /* CPDFListController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFListController.m; sourceTree = "<group>"; };
 		ECC8831B2923352B00F6392E /* CPDFViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFViewController.h; sourceTree = "<group>"; };
 		ECC8831C2923352B00F6392E /* CPDFViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFViewController.m; sourceTree = "<group>"; };
+		ECD0ABE52928ED990091B6EB /* CPDFTextPreview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPDFTextPreview.m; sourceTree = "<group>"; };
+		ECD0ABE82928ED990091B6EB /* CPDFImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPDFImageView.m; sourceTree = "<group>"; };
+		ECD0ABE92928ED990091B6EB /* CPDFTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPDFTextView.h; sourceTree = "<group>"; };
+		ECD0ABEA2928ED990091B6EB /* CPDFTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPDFTextView.m; sourceTree = "<group>"; };
+		ECD0ABEB2928ED9A0091B6EB /* CPDFImagePreview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPDFImagePreview.h; sourceTree = "<group>"; };
+		ECD0ABEC2928ED9A0091B6EB /* CPDFImagePreview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPDFImagePreview.m; sourceTree = "<group>"; };
+		ECD0ABED2928ED9A0091B6EB /* CPDFImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPDFImageView.h; sourceTree = "<group>"; };
+		ECD0ABEF2928ED9A0091B6EB /* CPDFTextPreview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPDFTextPreview.h; sourceTree = "<group>"; };
+		ECD0ABF92928EECA0091B6EB /* NSArray+MASAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+MASAdditions.h"; sourceTree = "<group>"; };
+		ECD0ABFA2928EECA0091B6EB /* View+MASAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "View+MASAdditions.h"; sourceTree = "<group>"; };
+		ECD0ABFB2928EECA0091B6EB /* MASConstraintMaker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASConstraintMaker.m; sourceTree = "<group>"; };
+		ECD0ABFC2928EECA0091B6EB /* MASConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASConstraint.h; sourceTree = "<group>"; };
+		ECD0ABFD2928EECA0091B6EB /* MASConstraint+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MASConstraint+Private.h"; sourceTree = "<group>"; };
+		ECD0ABFE2928EECA0091B6EB /* NSLayoutConstraint+MASDebugAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSLayoutConstraint+MASDebugAdditions.m"; sourceTree = "<group>"; };
+		ECD0ABFF2928EECA0091B6EB /* MASLayoutConstraint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASLayoutConstraint.m; sourceTree = "<group>"; };
+		ECD0AC002928EECA0091B6EB /* NSArray+MASAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+MASAdditions.m"; sourceTree = "<group>"; };
+		ECD0AC012928EECA0091B6EB /* NSArray+MASShorthandAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+MASShorthandAdditions.h"; sourceTree = "<group>"; };
+		ECD0AC022928EECA0091B6EB /* MASConstraint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASConstraint.m; sourceTree = "<group>"; };
+		ECD0AC032928EECA0091B6EB /* MASCompositeConstraint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASCompositeConstraint.m; sourceTree = "<group>"; };
+		ECD0AC042928EECA0091B6EB /* MASLayoutConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASLayoutConstraint.h; sourceTree = "<group>"; };
+		ECD0AC052928EECA0091B6EB /* NSLayoutConstraint+MASDebugAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSLayoutConstraint+MASDebugAdditions.h"; sourceTree = "<group>"; };
+		ECD0AC062928EECA0091B6EB /* MASViewConstraint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASViewConstraint.m; sourceTree = "<group>"; };
+		ECD0AC072928EECA0091B6EB /* MASConstraintMaker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASConstraintMaker.h; sourceTree = "<group>"; };
+		ECD0AC082928EECA0091B6EB /* Masonry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Masonry.h; sourceTree = "<group>"; };
+		ECD0AC092928EECA0091B6EB /* ViewController+MASAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ViewController+MASAdditions.m"; sourceTree = "<group>"; };
+		ECD0AC0A2928EECA0091B6EB /* ViewController+MASAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ViewController+MASAdditions.h"; sourceTree = "<group>"; };
+		ECD0AC0C2928EECA0091B6EB /* MASCompositeConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASCompositeConstraint.h; sourceTree = "<group>"; };
+		ECD0AC0D2928EECA0091B6EB /* View+MASAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "View+MASAdditions.m"; sourceTree = "<group>"; };
+		ECD0AC0E2928EECB0091B6EB /* MASViewConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASViewConstraint.h; sourceTree = "<group>"; };
+		ECD0AC0F2928EECB0091B6EB /* MASUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASUtilities.h; sourceTree = "<group>"; };
+		ECD0AC102928EECB0091B6EB /* MASViewAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASViewAttribute.h; sourceTree = "<group>"; };
+		ECD0AC112928EECB0091B6EB /* MASViewAttribute.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASViewAttribute.m; sourceTree = "<group>"; };
+		ECD0AC122928EECB0091B6EB /* View+MASShorthandAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "View+MASShorthandAdditions.h"; sourceTree = "<group>"; };
+		ECD0AC1F2928EF260091B6EB /* btn_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = btn_selected.png; sourceTree = "<group>"; };
+		ECD0AC212928F2A70091B6EB /* CPDFTextViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFTextViewController.h; sourceTree = "<group>"; };
+		ECD0AC222928F2A70091B6EB /* CPDFTextViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFTextViewController.m; sourceTree = "<group>"; };
+		ECD0AC242928F2E50091B6EB /* CPDFImageViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFImageViewController.h; sourceTree = "<group>"; };
+		ECD0AC252928F2E50091B6EB /* CPDFImageViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFImageViewController.m; sourceTree = "<group>"; };
+		ECD0AC30292B56C90091B6EB /* CPDFDataModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPDFDataModel.h; sourceTree = "<group>"; };
+		ECD0AC31292B56C90091B6EB /* CPDFDataModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPDFDataModel.m; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -228,11 +326,12 @@
 			isa = PBXGroup;
 			children = (
 				C9E65145292CBBDE001B2C9D /* Masonry */,
+                    ECD0ABF62928EE9A0091B6EB /* Masonry */,
 				EC6297B52922393F00D339EE /* Controller */,
+				ECD0ABE42928ED5D0091B6EB /* View */,
 				EC6297AD29222D3100D339EE /* Model */,
-				EC6297AE29222D4400D339EE /* View */,
-				EC62978C29220F8300D339EE /* AppDelegate.h */,
 				EC62978D29220F8300D339EE /* AppDelegate.m */,
+				EC62978C29220F8300D339EE /* AppDelegate.h */,
 				EC62978F29220F8300D339EE /* SceneDelegate.h */,
 				EC62979029220F8300D339EE /* SceneDelegate.m */,
 				EC62979229220F8300D339EE /* ViewController.h */,
@@ -253,6 +352,10 @@
 				EC6297B7292239A700D339EE /* CPDFModel.m */,
 				C993B916292B5BC500D8F474 /* CPDFHeaderFooterModel.h */,
 				C993B917292B5BC500D8F474 /* CPDFHeaderFooterModel.m */,
+                    ECD0AC30292B56C90091B6EB /* CPDFDataModel.h */,
+                ECD0AC31292B56C90091B6EB /* CPDFDataModel.m */,
+                C92BA19829651CA3009954EF /* CPDFBackgroundModel.h */,
+                C92BA19929651CA3009954EF /* CPDFBackgroundModel.m */,
 			);
 			path = Model;
 			sourceTree = "<group>";
@@ -292,10 +395,92 @@
 				C9B7639B2940B71600D25041 /* CPDFAddViewController.h */,
 				C9B7639C2940B71600D25041 /* CPDFAddViewController.m */,
 				C9B763A22941808500D25041 /* CPDFAddViewControllerHeader.h */,
+                    ECD0AC212928F2A70091B6EB /* CPDFTextViewController.h */,
+                ECD0AC222928F2A70091B6EB /* CPDFTextViewController.m */,
+                ECD0AC242928F2E50091B6EB /* CPDFImageViewController.h */,
+                ECD0AC252928F2E50091B6EB /* CPDFImageViewController.m */,
+                C9638494294ACC240055CCCA /* CPDFAddViewController.h */,
+                C9638495294ACC240055CCCA /* CPDFAddViewController.m */,
+                C986D3F32962857900EBD4DF /* CPDFBackgroundSettingViewController.h */,
+                C986D3F42962857900EBD4DF /* CPDFBackgroundSettingViewController.m */,
 			);
 			path = Controller;
 			sourceTree = "<group>";
 		};
+		ECD0ABE42928ED5D0091B6EB /* View */ = {
+			isa = PBXGroup;
+			children = (
+				ECD0AC1E2928EF030091B6EB /* sources */,
+				ECD0ABED2928ED9A0091B6EB /* CPDFImageView.h */,
+				ECD0ABE82928ED990091B6EB /* CPDFImageView.m */,
+				ECD0ABEB2928ED9A0091B6EB /* CPDFImagePreview.h */,
+				ECD0ABEC2928ED9A0091B6EB /* CPDFImagePreview.m */,
+				ECD0ABEF2928ED9A0091B6EB /* CPDFTextPreview.h */,
+				ECD0ABE52928ED990091B6EB /* CPDFTextPreview.m */,
+				ECD0ABE92928ED990091B6EB /* CPDFTextView.h */,
+				ECD0ABEA2928ED990091B6EB /* CPDFTextView.m */,
+				C96150D0295400B00020F445 /* CPDFDrawView.h */,
+				C96150D1295400B00020F445 /* CPDFDrawView.m */,
+				C96150D329554F660020F445 /* CPDFClipView.h */,
+				C96150D429554F660020F445 /* CPDFClipView.m */,
+				C97E91662959B96C007F6943 /* CPDFEditView.h */,
+				C97E91672959B96C007F6943 /* CPDFEditView.m */,
+				C986D3F6296288C400EBD4DF /* CPDFBackgroundPreview.h */,
+				C986D3F7296288C400EBD4DF /* CPDFBackgroundPreview.m */,
+				C986D3F9296288F700EBD4DF /* CPDFBackgroundView.h */,
+				C986D3FA296288F700EBD4DF /* CPDFBackgroundView.m */,
+				C986D3FC2962A70400EBD4DF /* CPDFBackgroundSettingView.h */,
+				C986D3FD2962A70400EBD4DF /* CPDFBackgroundSettingView.m */,
+				C92BA1922963F806009954EF /* CPDFDrawBackgroundView.h */,
+				C92BA1932963F806009954EF /* CPDFDrawBackgroundView.m */,
+				C92BA1952963F84B009954EF /* CPDFDrawImageView.h */,
+				C92BA1962963F84B009954EF /* CPDFDrawImageView.m */,
+				C92BA18F2963CAB4009954EF /* UIImage+TintColor.h */,
+				C92BA1902963CAB4009954EF /* UIImage+TintColor.m */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
+		ECD0ABF62928EE9A0091B6EB /* Masonry */ = {
+			isa = PBXGroup;
+			children = (
+				ECD0AC0C2928EECA0091B6EB /* MASCompositeConstraint.h */,
+				ECD0AC032928EECA0091B6EB /* MASCompositeConstraint.m */,
+				ECD0ABFC2928EECA0091B6EB /* MASConstraint.h */,
+				ECD0AC022928EECA0091B6EB /* MASConstraint.m */,
+				ECD0ABFD2928EECA0091B6EB /* MASConstraint+Private.h */,
+				ECD0AC072928EECA0091B6EB /* MASConstraintMaker.h */,
+				ECD0ABFB2928EECA0091B6EB /* MASConstraintMaker.m */,
+				ECD0AC042928EECA0091B6EB /* MASLayoutConstraint.h */,
+				ECD0ABFF2928EECA0091B6EB /* MASLayoutConstraint.m */,
+				ECD0AC082928EECA0091B6EB /* Masonry.h */,
+				ECD0AC0F2928EECB0091B6EB /* MASUtilities.h */,
+				ECD0AC102928EECB0091B6EB /* MASViewAttribute.h */,
+				ECD0AC112928EECB0091B6EB /* MASViewAttribute.m */,
+				ECD0AC0E2928EECB0091B6EB /* MASViewConstraint.h */,
+				ECD0AC062928EECA0091B6EB /* MASViewConstraint.m */,
+				ECD0ABF92928EECA0091B6EB /* NSArray+MASAdditions.h */,
+				ECD0AC002928EECA0091B6EB /* NSArray+MASAdditions.m */,
+				ECD0AC012928EECA0091B6EB /* NSArray+MASShorthandAdditions.h */,
+				ECD0AC052928EECA0091B6EB /* NSLayoutConstraint+MASDebugAdditions.h */,
+				ECD0ABFE2928EECA0091B6EB /* NSLayoutConstraint+MASDebugAdditions.m */,
+				ECD0ABFA2928EECA0091B6EB /* View+MASAdditions.h */,
+				ECD0AC0D2928EECA0091B6EB /* View+MASAdditions.m */,
+				ECD0AC122928EECB0091B6EB /* View+MASShorthandAdditions.h */,
+				ECD0AC0A2928EECA0091B6EB /* ViewController+MASAdditions.h */,
+				ECD0AC092928EECA0091B6EB /* ViewController+MASAdditions.m */,
+			);
+			path = Masonry;
+			sourceTree = "<group>";
+		};
+		ECD0AC1E2928EF030091B6EB /* sources */ = {
+			isa = PBXGroup;
+			children = (
+				ECD0AC1F2928EF260091B6EB /* btn_selected.png */,
+			);
+			path = sources;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
@@ -360,6 +545,7 @@
 				C9743C0029481F0F00E94840 /* add_newpage01.png in Resources */,
 				C9AF319229403A2A00CE0313 /* btn_frontpage.png in Resources */,
 				C993B8FB2925E14000D8F474 /* text_color_bar.png in Resources */,
+                    ECD0AC202928EF260091B6EB /* btn_selected.png in Resources */,
 				EC62979729220F8300D339EE /* Main.storyboard in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -377,7 +563,11 @@
 				C9E65169292CBC31001B2C9D /* MASCompositeConstraint.m in Sources */,
 				C96D13962924DD7E00CC92C7 /* CPDFHeaderFooterAddController.m in Sources */,
 				EC62979429220F8300D339EE /* ViewController.m in Sources */,
+				ECD0AC172928EECB0091B6EB /* MASConstraint.m in Sources */,
+				C97E91682959B96C007F6943 /* CPDFEditView.m in Sources */,
+				C96150D2295400B00020F445 /* CPDFDrawView.m in Sources */,
 				EC6297B8292239A700D339EE /* CPDFModel.m in Sources */,
+<<<<<<< HEAD
 				C9E65167292CBC31001B2C9D /* MASConstraint.m in Sources */,
 				C9AF3143293E032500CE0313 /* CPDFAddView.m in Sources */,
 				C9E65163292CBC31001B2C9D /* MASViewAttribute.m in Sources */,
@@ -392,12 +582,35 @@
 				C9E65160292CBC31001B2C9D /* MASViewConstraint.m in Sources */,
 				C9E65168292CBC31001B2C9D /* MASLayoutConstraint.m in Sources */,
 				C993B90F2927200400D8F474 /* CPDFBatesAddView.m in Sources */,
+                                ECD0AC232928F2A70091B6EB /* CPDFTextViewController.m in Sources */,
+                ECD0AC262928F2E50091B6EB /* CPDFImageViewController.m in Sources */,
+                ECD0ABF02928ED9A0091B6EB /* CPDFTextPreview.m in Sources */,
+                C9638496294ACC240055CCCA /* CPDFAddViewController.m in Sources */,
+                ECD0AC182928EECB0091B6EB /* MASCompositeConstraint.m in Sources */,
+                C986D3FE2962A70400EBD4DF /* CPDFBackgroundSettingView.m in Sources */,
+                C96150D529554F660020F445 /* CPDFClipView.m in Sources */,
 				EC62978E29220F8300D339EE /* AppDelegate.m in Sources */,
 				EC62979F29220F8400D339EE /* main.m in Sources */,
 				C9E6517029306274001B2C9D /* CPDFHeaderFooterTextTableView.m in Sources */,
 				C9E6516A292CBC31001B2C9D /* NSArray+MASAdditions.m in Sources */,
 				EC6297BD292239C200D339EE /* CPDFListController.m in Sources */,
+				C92BA1942963F806009954EF /* CPDFDrawBackgroundView.m in Sources */,
+				C986D3F52962857900EBD4DF /* CPDFBackgroundSettingViewController.m in Sources */,
+				ECD0AC132928EECB0091B6EB /* MASConstraintMaker.m in Sources */,
+				ECD0AC1A2928EECB0091B6EB /* ViewController+MASAdditions.m in Sources */,
+				ECD0AC142928EECB0091B6EB /* NSLayoutConstraint+MASDebugAdditions.m in Sources */,
+				ECD0AC162928EECB0091B6EB /* NSArray+MASAdditions.m in Sources */,
+				C986D3FB296288F700EBD4DF /* CPDFBackgroundView.m in Sources */,
+				C92BA19A29651CA3009954EF /* CPDFBackgroundModel.m in Sources */,
+				ECD0AC192928EECB0091B6EB /* MASViewConstraint.m in Sources */,
 				EC62979129220F8300D339EE /* SceneDelegate.m in Sources */,
+				C92BA1972963F84B009954EF /* CPDFDrawImageView.m in Sources */,
+				ECD0ABF52928ED9A0091B6EB /* CPDFImagePreview.m in Sources */,
+				ECD0AC32292B56C90091B6EB /* CPDFDataModel.m in Sources */,
+				ECD0ABF42928ED9A0091B6EB /* CPDFTextView.m in Sources */,
+				ECD0ABF32928ED9A0091B6EB /* CPDFImageView.m in Sources */,
+				C986D3F8296288C400EBD4DF /* CPDFBackgroundPreview.m in Sources */,
+				C92BA1912963CAB4009954EF /* UIImage+TintColor.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 18 - 0
PDFViewer.xcodeproj/project.xcworkspace/xcuserdata/kdan.xcuserdatad/WorkspaceSettings.xcsettings

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>BuildLocationStyle</key>
+	<string>UseAppPreferences</string>
+	<key>CustomBuildLocationType</key>
+	<string>RelativeToDerivedData</string>
+	<key>DerivedDataLocationStyle</key>
+	<string>Default</string>
+	<key>IssueFilterStyle</key>
+	<string>ShowActiveSchemeOnly</string>
+	<key>LiveSourceIssuesEnabled</key>
+	<true/>
+	<key>ShowSharedSchemesAutomaticallyEnabled</key>
+	<true/>
+</dict>
+</plist>

BIN
PDFViewer.xcodeproj/project.xcworkspace/xcuserdata/kdanmobile_2.xcuserdatad/UserInterfaceState.xcuserstate


+ 0 - 102
PDFViewer.xcodeproj/xcuserdata/kdanmobile_2.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -1,102 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Bucket
-   uuid = "C9705E14-C79F-4D2A-ADF6-CE5D16F03E83"
-   type = "1"
-   version = "2.0">
-   <Breakpoints>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "586B4355-6698-4BE5-A394-4B232CE80318"
-            shouldBeEnabled = "No"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "PDFViewer/Controller/HeaderFooterAlertViewController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "41"
-            endingLineNumber = "41"
-            landmarkName = "-viewDidLoad"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "05C2F84D-3598-4B1E-8CAA-E3E0C49A840F"
-            shouldBeEnabled = "No"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "PDFViewer/Controller/HeaderFooterAlertViewController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "30"
-            endingLineNumber = "30"
-            landmarkName = "-viewDidLoad"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "FE064F60-543B-4BD1-8A92-595D053B00F0"
-            shouldBeEnabled = "No"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "PDFViewer/Controller/HeaderFooterAlertViewController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "112"
-            endingLineNumber = "112"
-            landmarkName = "-showPages"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "A2F734DB-C4C5-43E0-89EA-C26301A35044"
-            shouldBeEnabled = "No"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "PDFViewer/Controller/CPDFTableViewController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "17"
-            endingLineNumber = "17"
-            landmarkName = "-dataArray"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "05E074D4-C1BE-4457-B3CC-04110F45C96C"
-            shouldBeEnabled = "No"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "PDFViewer/Controller/CPDFBatesAddViewController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "201"
-            endingLineNumber = "201"
-            landmarkName = "-changeText:"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "63422BA1-0EB0-4825-AAA0-E50249B95F62"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "PDFViewer/Masonry/ViewController+MASAdditions.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "43"
-            endingLineNumber = "43">
-         </BreakpointContent>
-      </BreakpointProxy>
-   </Breakpoints>
-</Bucket>

+ 14 - 0
PDFViewer.xcodeproj/xcuserdata/kdanmobile_2.xcuserdatad/xcschemes/xcschememanagement.plist

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>SchemeUserState</key>
+	<dict>
+		<key>PDFViewer.xcscheme_^#shared#^_</key>
+		<dict>
+			<key>orderHint</key>
+			<integer>0</integer>
+		</dict>
+	</dict>
+</dict>
+</plist>

+ 5 - 5
PDFViewer/Base.lproj/Main.storyboard

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
-    <device id="retina6_0" orientation="portrait" appearance="light"/>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="System colors in document resources" minToolsVersion="11.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@@ -14,7 +14,7 @@
             <objects>
                 <viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
                     <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
-                        <rect key="frame" x="0.0" y="0.0" width="390" height="844"/>
+                        <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
                         <color key="backgroundColor" systemColor="systemBackgroundColor"/>
@@ -22,7 +22,7 @@
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
             </objects>
-            <point key="canvasLocation" x="55" y="-34"/>
+            <point key="canvasLocation" x="-100.00000000000001" y="-297.32142857142856"/>
         </scene>
     </scenes>
     <resources>

+ 1 - 1
PDFViewer/Controller/CPDFAddViewController.m

@@ -265,7 +265,7 @@
             }
             break;
         default:
-            break;
+            break;=
     }
 }
 

+ 31 - 0
PDFViewer/Controller/CPDFBackgroundSettingViewController.h

@@ -0,0 +1,31 @@
+//
+//  CPDFBackgroundSettingViewController.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/2.
+//
+
+#import <UIKit/UIKit.h>
+#import <ComPDFKit/ComPDFKit.h>
+#import "CPDFBackgroundModel.h"
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol BackgroundDataModelDelegate <NSObject>
+
+- (void)changeBackgroundModel:(CPDFBackgroundModel *)dataModel;
+- (void)deleteBackgroundModel;
+
+@end
+
+@interface CPDFBackgroundSettingViewController : UIViewController
+
+@property (nonatomic,strong) CPDFDocument *document;
+@property (nonatomic,strong) id<BackgroundDataModelDelegate> delegate;
+
+- (instancetype)initWithDocument:(CPDFDocument *)document;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 418 - 0
PDFViewer/Controller/CPDFBackgroundSettingViewController.m

@@ -0,0 +1,418 @@
+//
+//  CPDFBackgroundSettingViewController.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/2.
+//
+
+#import "CPDFBackgroundSettingViewController.h"
+#import "CPDFBackgroundView.h"
+#import "CPDFBackgroundPreview.h"
+#import "CPDFBackgroundSettingView.h"
+#import "CPDFDrawBackgroundView.h"
+#import "CPDFDrawImageView.h"
+#import "Masonry.h"
+#import "UIImage+TintColor.h"
+
+@interface CPDFBackgroundSettingViewController () <UIImagePickerControllerDelegate,UINavigationControllerDelegate,UITextFieldDelegate>
+
+@property (nonatomic,strong) CPDFBackgroundView *backgroundView;
+@property (nonatomic,strong) CPDFBackgroundPreview *backgroundPreView;
+@property (nonatomic,strong) CPDFBackgroundSettingView *backgroudSettingView;
+@property (nonatomic,strong) CPDFDrawImageView *drawImageView;
+@property (nonatomic,strong) CPDFDrawBackgroundView *drawBackgroundView;
+@property (nonatomic,strong) CPDFBackgroundModel *dataModel;
+@property (nonatomic,assign) CGSize imageSize;
+@property (nonatomic,strong) UIImage *image;
+
+@end
+
+@implementation CPDFBackgroundSettingViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    
+    UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStylePlain target:self action:@selector(onClickedDoneBtn)];
+    
+    UIBarButtonItem *editBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(editClick)];
+    
+    UIBarButtonItem *deleteBtn = [[UIBarButtonItem alloc] initWithTitle:@"Delete" style:UIBarButtonItemStylePlain target:self action:@selector(deleteClick)];
+    
+    self.navigationItem.rightBarButtonItems = @[doneBtn, editBtn, deleteBtn];
+     
+    [self initDataMoel];
+    [self createView];
+    [self addConstraint];
+    [self addTargets];
+}
+
+#pragma mark - Initializers
+
+- (instancetype)initWithDocument:(CPDFDocument *)document {
+    self = [super init];
+    if (self) {
+        _document = document;
+        
+        CPDFPage *pdfPage = [document pageAtIndex:0];
+        CGSize imageSize = [document pageSizeAtIndex:0];
+        _image = [pdfPage thumbnailOfSize:imageSize];
+        _imageSize = imageSize;
+    }
+    return self;
+}
+
+- (void)createView {
+    _backgroundView = [[CPDFBackgroundView alloc] init];
+    [self.view addSubview:_backgroundView];
+    
+    _backgroundPreView = [[CPDFBackgroundPreview alloc] init];
+    [self.view addSubview:_backgroundPreView];
+    
+    _backgroundPreView.documentView.image = self.image;
+    
+    _drawBackgroundView = [[CPDFDrawBackgroundView alloc] initWithFrame:CGRectMake(0, 40, 393, 598.333)];
+    _drawBackgroundView.dataModel = self.dataModel;
+    [self.backgroundPreView addSubview:_drawBackgroundView];
+    
+    _drawImageView      = [[CPDFDrawImageView alloc] initWithFrame:CGRectMake(0, 40, 393, 598.333)];
+    [_drawImageView setImage:_image];
+    [self.backgroundPreView addSubview:_drawImageView];
+}
+
+- (void)initDataMoel {
+    _dataModel = [[CPDFBackgroundModel alloc] init];
+    _dataModel.backgroundColor = [UIColor whiteColor];
+    _dataModel.backgroudScale = 1.0f;
+    _dataModel.backgroundOpacity = 1.0f;
+    _dataModel.backgroundRotation = 0.0f;
+    _dataModel.verticalSpacing = 0.0f;
+    _dataModel.horizontalSpacing = 0.0f;
+}
+
+- (void)addConstraint {
+    if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight || [UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft || [UIDevice currentDevice].orientation == UIDeviceOrientationPortraitUpsideDown || (self.view.frame.size.width > self.view.frame.size.height)) {
+        [self addSideConstraint];
+    } else {
+        [self addNomalConstraint];
+    }
+}
+
+- (void)addSideConstraint {
+    [_backgroundView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.bottom.equalTo(self.view.mas_bottom).offset(-25);
+        make.left.equalTo(self.view.mas_left);
+        make.right.equalTo(self.view.mas_right);
+        make.height.mas_equalTo(70);
+    }];
+    
+    [_backgroundPreView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(self.view.mas_top).offset(43.6);
+        make.left.equalTo(self.view.mas_left);
+        make.right.equalTo(self.view.mas_right);
+        make.bottom.equalTo(self.backgroundView.mas_top);
+    }];
+    
+    [_backgroundPreView.documentView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(self.view.mas_top).offset(43.6);
+        make.bottom.equalTo(self.backgroundPreView.mas_bottom);
+        make.centerX.equalTo(self.backgroundPreView.mas_centerX);
+        make.width.mas_equalTo(233);
+    }];
+    
+    [_drawBackgroundView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(self.backgroundPreView.documentView.mas_top);
+        make.bottom.equalTo(self.backgroundPreView.documentView.mas_bottom);
+        make.left.equalTo(self.backgroundPreView.documentView.mas_left);
+        make.right.equalTo(self.backgroundPreView.documentView.mas_right);
+    }];
+    [_drawImageView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(self.backgroundPreView.documentView.mas_top);
+        make.bottom.equalTo(self.backgroundPreView.documentView.mas_bottom);
+        make.left.equalTo(self.backgroundPreView.documentView.mas_left);
+        make.right.equalTo(self.backgroundPreView.documentView.mas_right);
+    }];
+}
+
+- (void)addNomalConstraint {
+    [_backgroundView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.bottom.equalTo(self.view.mas_bottom).offset(-25);
+        make.left.equalTo(self.view.mas_left);
+        make.right.equalTo(self.view.mas_right);
+        make.height.mas_equalTo(70);
+    }];
+    
+    [_backgroundPreView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(self.view.mas_top).offset(83.6);
+        make.left.equalTo(self.view.mas_left);
+        make.right.equalTo(self.view.mas_right);
+        make.bottom.equalTo(self.backgroundView.mas_top);
+    }];
+    
+    [_backgroundPreView.documentView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.equalTo(self.backgroundPreView.mas_left);
+        make.top.equalTo(self.backgroundPreView.mas_top).offset(40);
+        make.bottom.equalTo(self.backgroundPreView.mas_bottom).offset(-40);
+        make.width.mas_equalTo(393);
+    }];
+}
+
+- (void)addTargets {
+    [_backgroundView.selectBtn addTarget:self action:@selector(onSelectBtnClicked:) forControlEvents:UIControlEventTouchDown];
+    
+    for (NSInteger i = 0; i < _backgroundView.colorArray.count; ++i) {
+        [_backgroundView.colorArray[i] addTarget:self action:@selector(onColorBtnClicked:) forControlEvents:UIControlEventTouchDown];
+    }
+}
+
+#pragma mark - Actions
+
+- (void)onClickedDoneBtn {
+    [self.delegate changeBackgroundModel:self.dataModel];
+    
+    [self.navigationController popViewControllerAnimated:YES];
+}
+
+- (void)editClick {
+    self.backgroundView.selectBtn.enabled = NO;
+    self.navigationItem.rightBarButtonItems.firstObject.enabled = NO;
+    self.navigationItem.rightBarButtonItems.lastObject.enabled = NO;
+    
+    if (!([_backgroudSettingView isDescendantOfView:self.view])) {
+        _backgroudSettingView = [[CPDFBackgroundSettingView alloc] init];
+        
+        _backgroudSettingView.verticalField.delegate = self;
+        _backgroudSettingView.horizontalField.delegate = self;
+        
+        [self.view addSubview:_backgroudSettingView];
+        
+        [_backgroudSettingView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.centerX.equalTo(self.backgroundPreView.mas_centerX);
+            make.centerY.equalTo(self.backgroundPreView.mas_centerY);
+            make.height.mas_equalTo(330);
+            make.width.mas_equalTo(320);
+        }];
+        
+        [UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
+            self.backgroudSettingView.center = CGPointMake(self.backgroudSettingView.center.x, self.backgroudSettingView.center.y - 300);
+        } completion:nil];
+        
+        [_backgroudSettingView.pageBtn addTarget:self action:@selector(onSelectPageRange:) forControlEvents:UIControlEventTouchUpInside];
+        [_backgroudSettingView.doneBtn addTarget:self action:@selector(doneClick:) forControlEvents:UIControlEventTouchUpInside];
+        [_backgroudSettingView.cancelBtn addTarget:self action:@selector(cancelClick:) forControlEvents:UIControlEventTouchUpInside];
+        
+        [_backgroudSettingView.opacitySlider addTarget:self action:@selector(onOpacityChanged:) forControlEvents:UIControlEventValueChanged];
+        [_backgroudSettingView.scaleSlider addTarget:self action:@selector(onScaleChanged:) forControlEvents:UIControlEventValueChanged];
+        [_backgroudSettingView.rotationSlider addTarget:self action:@selector(onRotationChanged:) forControlEvents:UIControlEventValueChanged];
+        
+        [_backgroudSettingView.horizontalField addTarget:self action:@selector(horizontalChange:) forControlEvents:UIControlEventEditingDidEnd];
+        [_backgroudSettingView.verticalField addTarget:self action:@selector(verticalChage:) forControlEvents:UIControlEventEditingDidEnd];
+    }
+}
+
+- (void)deleteClick {
+    [self.delegate deleteBackgroundModel];
+    
+    [self.navigationController popViewControllerAnimated:YES];
+}
+
+#pragma mark - UI Functions
+
+- (void)onColorBtnClicked:(UIButton *)btn {
+    
+    if (_dataModel.image) {
+        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Select Color Warning" message:@"Sorry,we can't choose color" preferredStyle:UIAlertControllerStyleAlert];
+        
+        [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        }]];
+        [self presentViewController:alertController animated:YES completion:nil];
+    }
+    
+    _dataModel.backgroundColor = btn.backgroundColor;
+    _drawBackgroundView.dataModel = self.dataModel;
+    [_drawBackgroundView setNeedsDisplay];
+    
+//    _backgroundPreView.documentView.image = [_image imageWithTintColor:btn.backgroundColor];
+}
+
+- (void)onSelectBtnClicked:(UIButton *)sender {
+    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
+    imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
+    imagePicker.delegate = self;
+    imagePicker.allowsEditing = YES;
+    [self presentViewController:imagePicker animated:YES completion:nil];
+}
+
+- (void)onSelectPageRange:(UIButton *)btn {
+    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
+    UIAlertAction *defaultRange = [UIAlertAction actionWithTitle:@"All Pages" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        self.backgroudSettingView.rangeLabel.text = @"Page Range: ALL";
+        }];
+    UIAlertAction *customRange = [UIAlertAction actionWithTitle:@"Custom" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        [self createCustomRangeAlert];
+        }];
+    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
+            
+        }];
+    [alertController addAction:defaultRange];
+    [alertController addAction:customRange];
+    [alertController addAction:cancelAction];
+    [self presentViewController:alertController animated:YES completion:nil];
+}
+
+- (void)createCustomRangeAlert {
+    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Custom Page Range" message:nil preferredStyle:UIAlertControllerStyleAlert];
+    
+    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
+        textField.placeholder = @"such as:1,3-5,10";
+    }];
+    [alertController addAction:[UIAlertAction actionWithTitle:@"Done" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        
+        self.dataModel.pageString = alertController.textFields.firstObject.text;
+        self.backgroudSettingView.rangeLabel.text = @"Page Range:Custom";
+    }]];
+    [alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+    }]];
+    [self presentViewController:alertController animated:YES completion:nil];
+}
+
+- (void)doneClick:(UIButton *)btn {
+    [self btnEnable];
+    _drawBackgroundView.dataModel = self.dataModel;
+    
+    [_drawBackgroundView setNeedsDisplay];
+    [_backgroudSettingView removeFromSuperview];
+}
+
+- (void)cancelClick:(UIButton *)btn {
+    [self btnEnable];
+    [_backgroudSettingView removeFromSuperview];
+}
+
+- (void)onOpacityChanged:(UISlider *)sender {
+    _dataModel.backgroundOpacity = 1 - sender.value;
+}
+
+- (void)onScaleChanged:(UISlider *)sender {
+    _dataModel.backgroudScale = sender.value;
+}
+
+- (void)onRotationChanged:(UISlider *)sender {
+    _dataModel.backgroundRotation = sender.value * 180 / M_PI;
+}
+
+- (void)horizontalChange:(UITextField *)text {
+    _dataModel.horizontalSpacing = [text.text floatValue];
+}
+
+- (void)verticalChage:(UITextField *)text {
+    _dataModel.verticalSpacing = [text.text floatValue];
+}
+
+- (void)btnEnable {
+    self.backgroundView.selectBtn.enabled = YES;
+    self.navigationItem.rightBarButtonItems.firstObject.enabled = YES;
+    self.navigationItem.rightBarButtonItems.lastObject.enabled = YES;
+}
+
+#pragma mark - Orientation
+
+- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
+    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
+    if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight) {
+        
+        [_backgroundView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.bottom.equalTo(self.view.mas_bottom).offset(-25);
+            make.left.equalTo(self.view.mas_left);
+            make.right.equalTo(self.view.mas_right);
+            make.height.mas_equalTo(70);
+        }];
+        
+        [_backgroundPreView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(self.view.mas_top).offset(43.6);
+            make.left.equalTo(self.view.mas_left);
+            make.right.equalTo(self.view.mas_right);
+            make.bottom.equalTo(self.backgroundView.mas_top);
+        }];
+        
+        [_backgroundPreView.documentView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(self.backgroundPreView.mas_top);
+            make.bottom.equalTo(self.backgroundPreView.mas_bottom);
+            make.centerX.equalTo(self.backgroundPreView.mas_centerX);
+            make.width.mas_equalTo(233);
+        }];
+        
+        [_drawBackgroundView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(self.backgroundPreView.documentView.mas_top);
+            make.bottom.equalTo(self.backgroundPreView.documentView.mas_bottom);
+            make.left.equalTo(self.backgroundPreView.documentView.mas_left);
+            make.right.equalTo(self.backgroundPreView.documentView.mas_right);
+        }];
+        [_drawImageView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(self.backgroundPreView.documentView.mas_top);
+            make.bottom.equalTo(self.backgroundPreView.documentView.mas_bottom);
+            make.left.equalTo(self.backgroundPreView.documentView.mas_left);
+            make.right.equalTo(self.backgroundPreView.documentView.mas_right);
+        }];
+    } else if ([UIDevice currentDevice].orientation == UIDeviceOrientationPortrait) {
+        
+        [_backgroundView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.bottom.equalTo(self.view.mas_bottom).offset(-25);
+            make.left.equalTo(self.view.mas_left);
+            make.right.equalTo(self.view.mas_right);
+            make.height.mas_equalTo(70);
+        }];
+        
+        [_backgroundPreView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(self.view.mas_top).offset(83.6);
+            make.left.equalTo(self.view.mas_left);
+            make.right.equalTo(self.view.mas_right);
+            make.bottom.equalTo(self.backgroundView.mas_top);
+        }];
+        
+        [_backgroundPreView.documentView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.left.equalTo(self.view.mas_left);
+            make.top.equalTo(self.view.mas_top).offset(123.6);
+            make.bottom.equalTo(self.backgroundPreView.mas_bottom).offset(-40);
+            make.width.mas_equalTo(393);
+        }];
+    }
+    
+    [_drawBackgroundView setNeedsDisplay];
+}
+
+#pragma mark - UIImagePickerControllerDelegate
+
+- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info {
+    UIImage *image = info[UIImagePickerControllerOriginalImage];
+    CGSize size;
+    size.width = self.backgroundPreView.documentView.frame.size.width;
+    size.height = self.backgroundPreView.documentView.frame.size.height;
+    _dataModel.image = [self imageWithImageSimple:image scaledToSize:_imageSize];
+    [_backgroundPreView.imageView sizeToFit];
+    
+    [picker dismissViewControllerAnimated:YES completion:nil];
+    [_drawBackgroundView setNeedsDisplay];
+}
+
+- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
+    [picker dismissViewControllerAnimated:YES completion:nil];
+}
+
+- (UIImage *)imageWithImageSimple:(UIImage *)image scaledToSize:(CGSize)newSize
+{
+    UIGraphicsBeginImageContext(newSize);
+    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
+    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
+    UIGraphicsEndImageContext();
+    return newImage;
+}
+
+#pragma mark - UITextFieldDelegate
+
+- (BOOL)textFieldShouldReturn:(UITextField *)textField {
+    [textField resignFirstResponder];
+    
+    return YES;
+}
+
+@end

+ 33 - 0
PDFViewer/Controller/CPDFImageViewController.h

@@ -0,0 +1,33 @@
+//
+//  CPDFImageViewController.h
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/19.
+//
+
+#import <UIKit/UIKit.h>
+
+
+@class CPDFImagePreview;
+@class CPDFImageView;
+@class CPDFDataModel;
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFImageViewController : UIViewController
+
+@property (nonatomic,strong) CPDFImagePreview *imagePreview;
+@property (nonatomic,strong) CPDFImageView *imageView;
+@property (nonatomic,strong) CPDFDataModel *dataModel;
+
+- (void)initDataModel;
+- (void)addTargets;
+- (void)addConstraint;
+- (void)createGestureRecognizer;
+- (void)createCustomRangeAlert;
+
+- (UIImage *)imageWithImageSimple:(UIImage *)image scaledToSize:(CGSize)newSize;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 437 - 0
PDFViewer/Controller/CPDFImageViewController.m

@@ -0,0 +1,437 @@
+//
+//  CPDFImageViewController.m
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/19.
+//
+
+#import "CPDFImageViewController.h"
+#import "CPDFImageView.h"
+#import "CPDFImagePreview.h"
+#import "CPDFDataModel.h"
+#import "CPDFDrawView.h"
+#import "CPDFClipView.h"
+#import "Masonry.h"
+
+@interface CPDFImageViewController () <UIImagePickerControllerDelegate,UINavigationControllerDelegate,CPDFClipTextPreviewDelegate,UITextFieldDelegate>
+
+@property (nonatomic,assign) CGRect watermarkFrame;
+
+@property (nonatomic,strong) CPDFDrawView *drawView;
+@property (nonatomic,strong) CPDFClipView *cliView;
+@property (nonatomic,assign) CGAffineTransform transform1;
+@property (nonatomic,assign) CGAffineTransform transform2;
+@property (nonatomic,assign) CGRect normalWatermarkRect;
+@property (nonatomic,strong) UILabel *shadowWaterLabel;
+
+@end
+
+@implementation CPDFImageViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    _imagePreview = [[CPDFImagePreview alloc] init];
+    _imageView = [[CPDFImageView alloc] init];
+    _dataModel = [[CPDFDataModel alloc] init];
+    
+    _imageView.verticalField.delegate = self;
+    _imageView.horizontalField.delegate = self;
+    
+    [self.view addSubview:_imagePreview];
+    [self.view addSubview:_imageView];
+    [self.view setBackgroundColor:UIColor.systemGray5Color];
+    
+    [self initDataModel];
+    [self addConstraint];
+    [self addTargets];
+    [self createGestureRecognizer];
+    
+    _normalWatermarkRect = CGRectMake(97.5, 143.333, 28, 28);
+    _shadowWaterLabel = [[UILabel alloc] initWithFrame:CGRectMake(97.5, 143.333, 28, 28)];
+}
+
+#pragma mark - Orientation
+
+- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
+    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
+    
+    if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight) {
+        
+        [_imageView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.right.equalTo(self.view.mas_right).offset(-38);
+            make.left.equalTo(_imagePreview.mas_right).offset(0);
+            make.height.equalTo(@205);
+            make.width.equalTo(@(self.view.bounds.size.width));
+            make.bottom.equalTo(self.view.mas_bottom).offset(-40);
+        }];
+        [_imagePreview mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(self.view.mas_top).offset(0);
+            make.right.equalTo(_imageView.mas_left).offset(-5);
+            make.left.equalTo(self.view.mas_left).offset(0);
+            make.bottom.equalTo(self.view.mas_bottom).offset(0);
+        }];
+    
+        if ([_drawView isDescendantOfView:self.view]) {
+            [_drawView mas_remakeConstraints:^(MASConstraintMaker *make) {
+                make.top.equalTo(self.view.mas_top).offset(0);
+                make.right.equalTo(_imageView.mas_left).offset(-5);
+                make.left.equalTo(self.view.mas_left).offset(0);
+                make.bottom.equalTo(self.view.mas_bottom).offset(0);
+            }];
+            [_cliView mas_remakeConstraints:^(MASConstraintMaker *make) {
+                make.top.equalTo(self.view.mas_top).offset(0);
+                make.right.equalTo(_imageView.mas_left).offset(-5);
+                make.left.equalTo(self.view.mas_left).offset(0);
+                make.bottom.equalTo(self.view.mas_bottom).offset(0);
+            }];
+        }
+    } else if ([UIDevice currentDevice].orientation == UIDeviceOrientationPortrait) {
+        [_imagePreview mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(self.view.mas_top).offset(0);
+            make.width.equalTo(self.view.mas_width);
+            make.bottom.equalTo(self.view.mas_bottom).offset(-205);
+        }];
+
+        [_imageView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(_imagePreview.mas_bottom).offset(0);
+            make.width.equalTo(_imagePreview.mas_width);
+            make.bottom.equalTo(self.view.mas_bottom).offset(0);
+        }];
+        
+        if ([_drawView isDescendantOfView:self.view]) {
+            [_drawView mas_remakeConstraints:^(MASConstraintMaker *make) {
+                make.top.equalTo(self.view.mas_top).offset(0);
+                make.width.equalTo(self.view.mas_width);
+                make.bottom.equalTo(self.view.mas_bottom).offset(-205);
+            }];
+            [_cliView mas_remakeConstraints:^(MASConstraintMaker *make) {
+                make.top.equalTo(self.view.mas_top).offset(0);
+                make.width.equalTo(self.view.mas_width);
+                make.bottom.equalTo(self.view.mas_bottom).offset(-205);
+            }];
+        }
+    }
+    
+    if ([_drawView isDescendantOfView:self.view]) {
+        [_drawView setDocumentViewRect:_imagePreview.documentView.frame];
+        [_drawView setWaterLabelRect:_imagePreview.watermarkView.frame];
+        [_drawView setNeedsDisplay];
+        [_cliView setNeedsDisplay];
+    }
+}
+
+#pragma mark - Initializers
+
+- (void)initDataModel {
+    _dataModel.watermarkOpacity = 1;
+    _dataModel.imagePath = @"btn_selected";
+    _dataModel.image = [UIImage imageNamed:_dataModel.imagePath];
+    _dataModel.watermarkScale = 1;
+    _dataModel.isTile = NO;
+    _dataModel.watermarkRotation = 0;
+    _dataModel.horizontalSpacing = 100;
+    _dataModel.verticalSpacing = 100;
+    
+    _imageView.horizontalField.text = 0;
+    _imageView.verticalField.text = 0;
+    _imageView.horizontalField.enabled = NO;
+    _imageView.verticalField.enabled = NO;
+    _imageView.imageScaleSlider.enabled = YES;
+    _imagePreview.watermarkView.image = [UIImage imageNamed:_dataModel.imagePath];
+}
+
+- (void)addConstraint {
+    [_imagePreview mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(self.view.mas_top).offset(0);
+        make.width.equalTo(self.view.mas_width);
+        make.bottom.equalTo(self.view.mas_bottom).offset(-205);
+    }];
+
+    [_imageView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(_imagePreview.mas_bottom).offset(0);
+        make.width.equalTo(_imagePreview.mas_width);
+        make.bottom.equalTo(self.view.mas_bottom).offset(0);
+    }];
+}
+
+- (void)addTargets {
+    [_imageView.selectBtn addTarget:self action:@selector(onSelectBtnClicked:) forControlEvents:UIControlEventTouchDown];
+    [_imageView.opacitySlider addTarget:self action:@selector(onOpacityChanged:) forControlEvents:UIControlEventValueChanged];
+    [_imageView.imageScaleSlider addTarget:self action:@selector(onImageScaleChanged:) forControlEvents:UIControlEventValueChanged];
+    [_imageView.tileSwitch addTarget:self action:@selector(onTileSwitchChanged:) forControlEvents:UIControlEventValueChanged];
+    [_imageView.pageBtn addTarget:self action:@selector(onSelectPageRange:) forControlEvents:UIControlEventTouchDown];
+    
+    [_imageView.horizontalField addTarget:self action:@selector(horizontalChange:) forControlEvents:UIControlEventEditingDidEnd];
+    [_imageView.verticalField addTarget:self action:@selector(verticalChage:) forControlEvents:UIControlEventEditingDidEnd];
+}
+
+#pragma mark - Gesture
+
+- (void)createGestureRecognizer {
+    [_imagePreview.documentView setUserInteractionEnabled:YES];
+    [_imagePreview.watermarkView setMultipleTouchEnabled:YES];
+    [_imagePreview.watermarkView setUserInteractionEnabled:YES];
+    [_imagePreview.rotationBtn setUserInteractionEnabled:YES];
+    
+    UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panWatermarkView:)];
+    [_imagePreview.watermarkView addGestureRecognizer:panRecognizer];
+    
+    UIPanGestureRecognizer *panRotationBtnRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(rotateWatermarkView:)];
+    [_imagePreview.rotationBtn addGestureRecognizer:panRotationBtnRecognizer];
+}
+
+- (void)rotateWatermarkView:(UIPanGestureRecognizer *)recognizer {
+    CGPoint point = [recognizer translationInView:_imagePreview];
+    CGFloat radian = atan2(point.x + _imagePreview.center.x - _imagePreview.watermarkView.center.x,point.y + _imagePreview.center.y - _imagePreview.watermarkView.center.y);
+    
+    if (self.dataModel.watermarkScale == 1) {
+        _imagePreview.watermarkView.transform = CGAffineTransformMakeRotation(-radian);
+    } else {
+        _imagePreview.watermarkView.transform = CGAffineTransformRotate(self.transform2, -radian);
+    }
+    
+    _transform1 = CGAffineTransformMakeRotation(-radian);
+    _dataModel.watermarkRotation = (-radian) * 180 / M_PI;
+}
+
+- (void)panWatermarkView:(UIPanGestureRecognizer *)recognizer {
+    CGPoint point = [recognizer translationInView:_imagePreview.documentView];
+    CGRect documentFrame = _imagePreview.documentView.frame;
+    documentFrame.origin.x -= _imagePreview.documentView.frame.origin.x;
+    documentFrame.origin.y -= _imagePreview.documentView.frame.origin.y;
+    
+    [_imagePreview.watermarkView setCenter:CGPointMake(_imagePreview.watermarkView.center.x + point.x, _imagePreview.watermarkView.center.y + point.y)];
+    [_imagePreview.rotationBtn setCenter:CGPointMake(_imagePreview.rotationBtn.center.x + point.x, _imagePreview.rotationBtn.center.y + point.y)];
+    
+    if (!CGRectContainsRect(documentFrame,_imagePreview.watermarkView.frame)) {
+        [_imagePreview.watermarkView setCenter:CGPointMake(_imagePreview.watermarkView.center.x - point.x, _imagePreview.watermarkView.center.y - point.y)];
+        [_imagePreview.rotationBtn setCenter:CGPointMake(_imagePreview.rotationBtn.center.x - point.x, _imagePreview.rotationBtn.center.y - point.y)];
+    }
+    
+    _dataModel.tx = _imagePreview.watermarkView.center.x - (_imagePreview.documentView.center.x - _imagePreview.documentView.frame.origin.x);
+    _dataModel.ty = _imagePreview.documentView.center.y - _imagePreview.documentView.frame.origin.y - _imagePreview.watermarkView.center.y;
+    
+    _shadowWaterLabel.center = _imagePreview.watermarkView.center;
+    
+    [recognizer setTranslation:CGPointZero inView:_imagePreview.documentView];
+    
+    _normalWatermarkRect = _shadowWaterLabel.frame;
+}
+
+#pragma mark - UI Functions
+
+- (void)onSelectBtnClicked:(UIButton *)sender {
+    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
+    imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
+    imagePicker.delegate = self;
+    imagePicker.allowsEditing = YES;
+    [self presentViewController:imagePicker animated:YES completion:nil];
+}
+
+- (void)onOpacityChanged:(UISlider *)sender {
+    _imagePreview.watermarkView.alpha =  1 - sender.value;
+    [_dataModel setWatermarkOpacity:1 - sender.value];
+}
+
+/*
+    this had core was deleted:
+ //    _watermarkFrame.size.width = sender.value * [UIImage imageNamed:_dataModel.imagePath].size.width;
+ //    _watermarkFrame.size.height = sender.value * [UIImage imageNamed:_dataModel.imagePath].size.height;
+ //    _watermarkFrame.size.width = sender.value * 33;
+ //    _watermarkFrame.size.height = sender.value * 33;
+ //
+ //    _watermarkFrame.origin.x = _imagePreview.watermarkView.frame.origin.x;
+ //    _watermarkFrame.origin.y = _imagePreview.watermarkView.frame.origin.y;
+ //    _imagePreview.watermarkView.frame = _watermarkFrame;
+ //    _imagePreview.watermarkFrame = _watermarkFrame;
+ */
+
+- (void)onImageScaleChanged:(UISlider *)sender {
+    sender.minimumValue = 0.5;
+    sender.maximumValue = 2;
+    
+    if (self.dataModel.watermarkRotation) {
+        _imagePreview.watermarkView.transform = CGAffineTransformScale(self.transform1, sender.value, sender.value);
+    } else {
+            _imagePreview.watermarkView.transform = CGAffineTransformMakeScale(sender.value, sender.value);
+    }
+
+    _transform2 = CGAffineTransformMakeScale(sender.value, sender.value);
+    _shadowWaterLabel.transform = CGAffineTransformMakeScale(sender.value, sender.value);
+    
+    [_imagePreview.rotationBtn mas_remakeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(_imagePreview.watermarkView.mas_bottom).offset(-10);
+        make.width.equalTo(@20);
+        make.height.equalTo(@20);
+        make.left.equalTo(_imagePreview.watermarkView.mas_right).offset(-10);
+    }];
+    
+    [_dataModel setWatermarkScale:sender.value];
+    
+    _normalWatermarkRect = _shadowWaterLabel.frame;
+}
+
+- (void)onSelectPageRange:(UIButton *)sender {
+    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
+    UIAlertAction *defaultRange = [UIAlertAction actionWithTitle:@"All Pages" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        self.imageView.rangeLabel.text = @"Page Range: ALL";
+        }];
+    UIAlertAction *customRange = [UIAlertAction actionWithTitle:@"Custom Page Range" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        [self createCustomRangeAlert];
+        }];
+    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
+            
+        }];
+    [alertController addAction:defaultRange];
+    [alertController addAction:customRange];
+    [alertController addAction:cancelAction];
+    [self presentViewController:alertController animated:YES completion:nil];
+}
+
+- (void)createCustomRangeAlert {
+    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Custom Page Range" message:nil preferredStyle:UIAlertControllerStyleAlert];
+    
+    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
+        textField.placeholder = @"such as:1,3-5,10";
+    }];
+    [alertController addAction:[UIAlertAction actionWithTitle:@"Done" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        
+        self.dataModel.pageString = alertController.textFields.firstObject.text;
+        self.imageView.rangeLabel.text = @"Page Range:Custom";
+    }]];
+    [alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+    }]];
+    [self presentViewController:alertController animated:YES completion:nil];
+}
+
+- (void)onTileSwitchChanged:(UISwitch *) sender {
+    if ([sender isOn]) {
+        _dataModel.isTile = YES;
+        _imageView.horizontalField.enabled = YES;
+        _imageView.verticalField.enabled = YES;
+        _imageView.imageScaleSlider.enabled = NO;
+        
+        _drawView = [[CPDFDrawView alloc] initWithFrame:self.imagePreview.bounds];
+        
+        [_drawView setDataModel:self.dataModel];
+        [_drawView setWaterLabelRect:self.normalWatermarkRect];
+        [_drawView setDocumentViewRect:self.imagePreview.documentView.frame];
+        
+        [self.view addSubview:_drawView];
+        [self.imagePreview bringSubviewToFront:_drawView];
+        
+        _cliView = [[CPDFClipView alloc] initWithFrame:self.imagePreview.bounds];
+        _cliView.delegate = self;
+        [self.view addSubview:_cliView];
+        [self.drawView bringSubviewToFront:_cliView];
+        
+    } else {
+        _dataModel.isTile = NO;
+        _imageView.horizontalField.enabled = NO;
+        _imageView.verticalField.enabled = NO;
+        _imageView.imageScaleSlider.enabled = YES;
+        
+        [self.drawView removeFromSuperview];
+        [self.cliView removeFromSuperview];
+    }
+}
+
+- (void)horizontalChange:(UITextField *)text {
+    [_drawView setHorizontal:[text.text floatValue]];
+    _dataModel.horizontalSpacing = [text.text floatValue];
+    
+    [_drawView setNeedsDisplay];
+}
+
+- (void)verticalChage:(UITextField *)text {
+    [_drawView setVertical:[text.text floatValue]];
+    _dataModel.verticalSpacing = [text.text floatValue];
+    
+    [_drawView setNeedsDisplay];
+}
+
+
+#pragma mark - UIImagePickerControllerDelegate
+
+- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info {
+    UIImage *image = info[UIImagePickerControllerOriginalImage];
+    CGSize size;
+    size.width = image.size.width / 30;
+    size.height = image.size.height / 30;
+    _imagePreview.watermarkView.image = [self imageWithImageSimple:image scaledToSize:size];
+    _dataModel.image = [self imageWithImageSimple:image scaledToSize:size];
+    [_imagePreview.watermarkView sizeToFit];
+    _shadowWaterLabel.frame = _imagePreview.watermarkView.frame;
+    [picker dismissViewControllerAnimated:YES completion:nil];
+    _normalWatermarkRect = _shadowWaterLabel.frame;
+}
+
+- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
+    [picker dismissViewControllerAnimated:YES completion:nil];
+}
+
+- (UIImage *)imageWithImageSimple:(UIImage *)image scaledToSize:(CGSize)newSize
+{
+    UIGraphicsBeginImageContext(newSize);
+    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
+    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
+    UIGraphicsEndImageContext();
+    return newImage;
+}
+
+#pragma mark - CPDFClipTextPreviewDelegate
+
+- (void)clipText:(CGContextRef)context {
+    CGContextSetFillColorWithColor(context, [UIColor systemGray5Color].CGColor);
+    CGContextFillRect(context, self.imagePreview.bounds);
+    CGContextClearRect(context, self.imagePreview.documentView.frame);
+}
+
+#pragma mark - UITextFieldDelegate
+
+- (void)textFieldDidBeginEditing:(UITextField *)textField {
+    
+    self.cliView.hidden = YES;
+    self.drawView.hidden = YES;
+    
+    if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight || [UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft || [UIDevice currentDevice].orientation == UIDeviceOrientationPortraitUpsideDown) {
+        
+    } else {
+        [_imageView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.height.mas_equalTo(205);
+            make.width.equalTo(_imagePreview.mas_width);
+            make.bottom.equalTo(self.view.mas_bottom).offset(-300);
+        }];
+        
+        [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^ {
+            self.imageView.center = CGPointMake(self.imageView.center.x, self.imageView.center.y - 300);
+        } completion:nil];
+    }
+}
+
+- (BOOL)textFieldShouldReturn:(UITextField *)textField {
+    [textField resignFirstResponder];
+    
+    self.cliView.hidden = NO;
+    self.drawView.hidden = NO;
+    
+    if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight || [UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft || [UIDevice currentDevice].orientation == UIDeviceOrientationPortraitUpsideDown) {
+        
+    } else {
+        [_imageView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(_imagePreview.mas_bottom).offset(0);
+            make.width.equalTo(_imagePreview.mas_width);
+            make.bottom.equalTo(self.view.mas_bottom).offset(0);
+            make.height.mas_equalTo(205);
+        }];
+        
+        [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^ {
+            self.imageView.center = CGPointMake(self.imageView.center.x, self.imageView.center.y + 300);
+        } completion:nil];
+    }
+    
+    return YES;
+}
+
+@end

+ 7 - 1
PDFViewer/Controller/CPDFListController.m

@@ -10,6 +10,9 @@
 #import "CPDFModel.h"
 #import "CPDFViewController.h"
 
+extern BOOL gImagePreviewIsFirstLayout;
+extern BOOL gTextPreviewIsFirstLayout;
+
 @interface CPDFListController () <UITableViewDataSource,UITableViewDelegate>
 
 @property (nonatomic,strong) UITableView *tableView;
@@ -62,6 +65,8 @@
     
     // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
     // self.navigationItem.rightBarButtonItem = self.editButtonItem;
+
+    _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
     
     _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
     
@@ -115,7 +120,8 @@
         
         CPDFViewController *pdfViewcontroller = [[CPDFViewController alloc] initWithPath:[self.dataArray[indexPath.row] filePath]];
         [self.navigationController pushViewController:pdfViewcontroller animated:YES];
-        
+        gImagePreviewIsFirstLayout = YES;
+        gTextPreviewIsFirstLayout = YES;
     }
 }
 

+ 32 - 0
PDFViewer/Controller/CPDFTextViewController.h

@@ -0,0 +1,32 @@
+//
+//  CPDFTextViewController.h
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/19.
+//
+
+#import <UIKit/UIKit.h>
+#import "CPDFTextPreview.h"
+
+@class CPDFTextPreview;
+@class CPDFTextView;
+@class CPDFDataModel;
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFTextViewController : UIViewController 
+
+@property (nonatomic,strong) CPDFTextPreview *textPreview;
+@property (nonatomic,strong) CPDFTextView *textView;
+@property (nonatomic,strong) CPDFDataModel *dataModel;
+@property (nonatomic,strong) UIAlertController *alertController;
+
+- (void)initDataModel;
+- (void)addTargets;
+- (void)addConstraint;
+- (void)createGestureRecognizer;
+- (void)createCustomRangeAlert;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 397 - 0
PDFViewer/Controller/CPDFTextViewController.m

@@ -0,0 +1,397 @@
+//
+//  CPDFTextViewController.m
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/19.
+//
+
+#import "CPDFTextViewController.h"
+#import "CPDFTextView.h"
+#import "CPDFDataModel.h"
+#import "CPDFDrawView.h"
+#import "CPDFClipView.h"
+#import "Masonry.h"
+
+@interface CPDFTextViewController () <CPDFClipTextPreviewDelegate,UITextFieldDelegate>
+
+@property (nonatomic,strong) CPDFDrawView *drawView;
+@property (nonatomic,strong) CPDFClipView *cliView;
+@property (nonatomic,assign) CGRect normalWatermarkRect;
+@property (nonatomic,strong) UILabel *shadowWaterLabel;
+
+@end
+
+@implementation CPDFTextViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    
+    _textPreview = [[CPDFTextPreview alloc] init];
+    _textView = [[CPDFTextView alloc] init];
+    
+    _textView.verticalField.delegate = self;
+    _textView.horizontalField.delegate = self;
+    
+    _dataModel = [[CPDFDataModel alloc] init];
+    _alertController = [UIAlertController alertControllerWithTitle:@"Watermark Content" message:nil preferredStyle:UIAlertControllerStyleAlert];
+    
+    [self.view addSubview:_textPreview];
+    [self.view addSubview:_textView];
+    [self.view setBackgroundColor:UIColor.systemGray5Color];
+    
+    [self addConstraint];
+    [self initDataModel];
+    [self addTargets];
+    [self createGestureRecognizer];
+    
+    _normalWatermarkRect = CGRectMake(69.666, 147.666, 83.666, 20.333);
+    _shadowWaterLabel = [[UILabel alloc] initWithFrame:CGRectMake(69.666, 147.666, 83.666, 20.333)];
+    _shadowWaterLabel.text = _textPreview.watermarkLabel.text;
+}
+
+#pragma mark - Initializers
+
+- (void)initDataModel {
+    _dataModel.textColor = UIColor.blackColor;
+    _dataModel.watermarkOpacity = 1;
+    _dataModel.text = @"Watermark";
+    _dataModel.watermarkScale = 17.0 / 24.0;
+    _dataModel.isTile = NO;
+    _dataModel.watermarkRotation = 0;
+    _dataModel.verticalSpacing = 100;
+    _dataModel.horizontalSpacing = 100;
+    
+    _textPreview.watermarkLabel.text = _dataModel.text;
+    _textView.horizontalField.text = 0;
+    _textView.verticalField.text = 0;
+    _textView.horizontalField.enabled = NO;
+    _textView.verticalField.enabled = NO;
+}
+
+- (void)addConstraint {
+        [_textPreview mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(self.view.mas_top).offset(0);
+            make.width.equalTo(self.view.mas_width);
+            make.bottom.equalTo(self.view.mas_bottom).offset(-205);
+        }];
+
+        [_textView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(_textPreview.mas_bottom).offset(0);
+            make.width.equalTo(_textPreview.mas_width);
+            make.bottom.equalTo(self.view.mas_bottom).offset(0);
+        }];
+}
+
+- (void)addTargets {
+    for (NSInteger i = 0; i < _textView.colorArray.count; ++i) {
+        [_textView.colorArray[i] addTarget:self action:@selector(onColorBtnClicked:) forControlEvents:UIControlEventTouchDown];
+    }
+    
+    __block CPDFTextViewController *strongBlock = self;
+    [_alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
+        
+    }];
+    [_alertController addAction:[UIAlertAction actionWithTitle:@"Done" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        
+        strongBlock.dataModel.text = strongBlock.alertController.textFields.firstObject.text;
+        strongBlock.textPreview.watermarkLabel.text = strongBlock.alertController.textFields.firstObject.text;
+        [strongBlock.textPreview.watermarkLabel sizeToFit];
+        
+    }]];
+    [_alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        strongBlock.alertController.view.hidden = YES;
+    }]];
+    
+    [_textView.opacitySlider addTarget:self action:@selector(onOpacityChanged:) forControlEvents:UIControlEventValueChanged];
+    [_textView.textScaleSlider addTarget:self action:@selector(onTextScaleChanged:) forControlEvents:UIControlEventValueChanged];
+    [_textView.tileSwitch addTarget:self action:@selector(onTileSwitchChanged:) forControlEvents:UIControlEventValueChanged];
+    [_textView.pageBtn addTarget:self action:@selector(onSelectPageRange:) forControlEvents:UIControlEventTouchDown];
+    
+    [_textView.horizontalField addTarget:self action:@selector(horizontalChange:) forControlEvents:UIControlEventEditingDidEnd];
+    [_textView.verticalField addTarget:self action:@selector(verticalChage:) forControlEvents:UIControlEventEditingDidEnd];
+}
+
+#pragma mark - UI Functions
+
+- (void)onColorBtnClicked:(UIButton *)sender {
+    _textPreview.watermarkLabel.textColor = sender.backgroundColor;
+    [_dataModel setTextColor:sender.backgroundColor];
+}
+
+- (void)onOpacityChanged:(UISlider *)sender {
+    _textPreview.watermarkLabel.alpha =  1 - sender.value;
+    [_dataModel setWatermarkOpacity:1 - sender.value];
+}
+
+- (void)onTextScaleChanged:(UISlider *)sender {
+    if (!_dataModel.isTile) {
+        sender.minimumValue = 12;
+        sender.maximumValue = 36;
+        _textPreview.watermarkLabel.font = [_textPreview.watermarkLabel.font fontWithSize:sender.value];
+        _shadowWaterLabel.font = [_textPreview.watermarkLabel.font fontWithSize:sender.value];
+        _shadowWaterLabel.center = _textPreview.watermarkLabel.center;
+        
+        [_textPreview.watermarkLabel sizeToFit];
+        [_shadowWaterLabel sizeToFit];
+        
+        [_dataModel setWatermarkScale:sender.value / 24];
+    }
+    
+    _normalWatermarkRect = _shadowWaterLabel.frame;
+}
+
+- (void)onTileSwitchChanged:(UISwitch *) sender {
+    if ([sender isOn]) {
+        _dataModel.isTile = YES;
+        _textView.horizontalField.enabled = YES;
+        _textView.verticalField.enabled = YES;
+        _textView.textScaleSlider.enabled = NO;
+        
+        _drawView = [[CPDFDrawView alloc] initWithFrame:self.textPreview.bounds];
+        
+        [_drawView setDataModel:self.dataModel];
+        [_drawView setWaterLabelRect:self.normalWatermarkRect];
+        [_drawView setDocumentViewRect:self.textPreview.documentView.frame];
+        
+        [self.view addSubview:_drawView];
+        [self.textPreview bringSubviewToFront:_drawView];
+        
+        _cliView = [[CPDFClipView alloc] initWithFrame:self.textPreview.bounds];
+        _cliView.delegate = self;
+        [self.view addSubview:_cliView];
+        [self.drawView bringSubviewToFront:_cliView];
+        
+    } else {
+        _dataModel.isTile = NO;
+        _textView.horizontalField.enabled = NO;
+        _textView.verticalField.enabled = NO;
+        _textView.textScaleSlider.enabled = YES;
+        
+        [_drawView removeFromSuperview];
+        [_cliView removeFromSuperview];
+    }
+}
+
+- (void)onSelectPageRange:(UIButton *)sender {
+    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
+    UIAlertAction *defaultRange = [UIAlertAction actionWithTitle:@"All Pages" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        self.textView.rangeLabel.text = @"Page Range: ALL";
+        }];
+    UIAlertAction *customRange = [UIAlertAction actionWithTitle:@"Custom Page Range" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        [self createCustomRangeAlert];
+        }];
+    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
+            
+        }];
+    [alertController addAction:defaultRange];
+    [alertController addAction:customRange];
+    [alertController addAction:cancelAction]; 
+    [self presentViewController:alertController animated:YES completion:nil];
+}
+
+- (void)createCustomRangeAlert {
+    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Custom Page Range" message:nil preferredStyle:UIAlertControllerStyleAlert];
+    
+    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
+        textField.placeholder = @"such as:1,3-5,10";
+    }];
+    [alertController addAction:[UIAlertAction actionWithTitle:@"Done" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        
+        self.dataModel.pageString = alertController.textFields.firstObject.text;
+        self.textView.rangeLabel.text = @"Page Range:Custom";
+    }]];
+    [alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+    }]];
+    [self presentViewController:alertController animated:YES completion:nil];
+}
+
+- (void)horizontalChange:(UITextField *)text {
+    [_drawView setHorizontal:[text.text floatValue]];
+    _dataModel.horizontalSpacing = [text.text floatValue];
+    [_drawView setNeedsDisplay];
+}
+
+- (void)verticalChage:(UITextField *)text {
+    [_drawView setVertical:[text.text floatValue]];
+    _dataModel.verticalSpacing = [text.text floatValue];
+    [_drawView setNeedsDisplay];
+}
+
+#pragma mark - Gesture
+
+- (void)createGestureRecognizer {
+    [_textPreview.documentView setUserInteractionEnabled:YES];
+    [_textPreview.watermarkLabel setUserInteractionEnabled:YES];
+    [_textPreview.rotationBtn setUserInteractionEnabled:YES];
+      
+    UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapWatermarkLabel:)];
+    [_textPreview.watermarkLabel addGestureRecognizer:tapGestureRecognizer];
+    
+    UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panWatermarkLabel:)];
+    [_textPreview.watermarkLabel addGestureRecognizer:panRecognizer];
+    
+    UIPanGestureRecognizer *panRotationBtnRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(rotationWatermarkLabel:)];
+    [_textPreview.rotationBtn addGestureRecognizer:panRotationBtnRecognizer];
+}
+
+- (void)tapWatermarkLabel:(UITapGestureRecognizer *)recognizer {
+    _alertController.view.hidden = NO;
+    _alertController.textFields.firstObject.text = _textPreview.watermarkLabel.text;
+    [self presentViewController:_alertController animated:true completion:nil];
+}
+
+- (void)panWatermarkLabel:(UIPanGestureRecognizer *)recognizer {
+    CGPoint point = [recognizer translationInView:_textPreview.documentView];
+    CGRect documentFrame = _textPreview.documentView.frame;
+    documentFrame.origin.x -= _textPreview.documentView.frame.origin.x;
+    documentFrame.origin.y -= _textPreview.documentView.frame.origin.y;
+    
+    [_textPreview.watermarkLabel setCenter:CGPointMake(_textPreview.watermarkLabel.center.x + point.x, _textPreview.watermarkLabel.center.y + point.y)];
+    [_textPreview.rotationBtn setCenter:CGPointMake(_textPreview.rotationBtn.center.x + point.x, _textPreview.rotationBtn.center.y + point.y)];
+    
+    if (!CGRectContainsRect(documentFrame,_textPreview.watermarkLabel.frame)) {
+        [_textPreview.watermarkLabel setCenter:CGPointMake(_textPreview.watermarkLabel.center.x - point.x, _textPreview.watermarkLabel.center.y - point.y)];
+        [_textPreview.rotationBtn setCenter:CGPointMake(_textPreview.rotationBtn.center.x - point.x, _textPreview.rotationBtn.center.y - point.y)];
+    }
+    
+    _dataModel.tx = _textPreview.watermarkLabel.center.x - (_textPreview.documentView.center.x - _textPreview.documentView.frame.origin.x);
+    _dataModel.ty = _textPreview.documentView.center.y - _textPreview.documentView.frame.origin.y - _textPreview.watermarkLabel.center.y;
+    [recognizer setTranslation:CGPointZero inView:_textPreview.documentView];
+    _shadowWaterLabel.center = _textPreview.watermarkLabel.center;
+    
+    _normalWatermarkRect = _shadowWaterLabel.frame;
+}
+
+- (void)rotationWatermarkLabel:(UIPanGestureRecognizer *)recognizer {
+    CGPoint point = [recognizer translationInView:_textPreview];
+    CGFloat radian = atan2(point.x + _textPreview.center.x - _textPreview.watermarkLabel.center.x, point.y + _textPreview.center.y - _textPreview.watermarkLabel.center.y);
+    _textPreview.watermarkLabel.transform = CGAffineTransformMakeRotation(-radian);
+    _dataModel.watermarkRotation = (-radian) * 180 / M_PI;
+}
+
+#pragma mark - Orientation
+
+- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
+    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
+    
+    if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight) {
+        
+        [_textView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.right.equalTo(self.view.mas_right).offset(-38);
+            make.left.equalTo(_textPreview.mas_right).offset(0);
+            make.height.equalTo(@205);
+            make.width.equalTo(@(self.view.bounds.size.width));
+            make.bottom.equalTo(self.view.mas_bottom).offset(-40);
+        }];
+        [_textPreview mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(self.view.mas_top).offset(0);
+            make.right.equalTo(_textView.mas_left).offset(-5);
+            make.left.equalTo(self.view.mas_left).offset(0);
+            make.bottom.equalTo(self.view.mas_bottom).offset(0);
+        }];
+        
+        if ([_drawView isDescendantOfView:self.view]) {
+            [_drawView mas_remakeConstraints:^(MASConstraintMaker *make) {
+                make.top.equalTo(self.view.mas_top).offset(0);
+                make.right.equalTo(_textView.mas_left).offset(-5);
+                make.left.equalTo(self.view.mas_left).offset(0);
+                make.bottom.equalTo(self.view.mas_bottom).offset(0);
+            }];
+            [_cliView mas_remakeConstraints:^(MASConstraintMaker *make) {
+                make.top.equalTo(self.view.mas_top).offset(0);
+                make.right.equalTo(_textView.mas_left).offset(-5);
+                make.left.equalTo(self.view.mas_left).offset(0);
+                make.bottom.equalTo(self.view.mas_bottom).offset(0);
+            }];
+        }
+        
+    } else if ([UIDevice currentDevice].orientation == UIDeviceOrientationPortrait) {
+        [_textPreview mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(self.view.mas_top).offset(0);
+            make.width.equalTo(self.view.mas_width);
+            make.bottom.equalTo(self.view.mas_bottom).offset(-205);
+        }];
+        [_textView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(_textPreview.mas_bottom).offset(0);
+            make.width.equalTo(_textPreview.mas_width);
+            make.bottom.equalTo(self.view.mas_bottom).offset(0);
+        }];
+        
+        if ([_drawView isDescendantOfView:self.view]) {
+            [_drawView mas_remakeConstraints:^(MASConstraintMaker *make) {
+                make.top.equalTo(self.view.mas_top).offset(0);
+                make.width.equalTo(self.view.mas_width);
+                make.bottom.equalTo(self.view.mas_bottom).offset(-205);
+            }];
+            [_cliView mas_remakeConstraints:^(MASConstraintMaker *make) {
+                make.top.equalTo(self.view.mas_top).offset(0);
+                make.width.equalTo(self.view.mas_width);
+                make.bottom.equalTo(self.view.mas_bottom).offset(-205);
+            }];
+        }
+    }
+    
+    if ([_drawView isDescendantOfView:self.view]) {
+        [_drawView setDocumentViewRect:_textPreview.documentView.frame];
+        [_drawView setWaterLabelRect:_textPreview.watermarkLabel.frame];
+        [_drawView setNeedsDisplay];
+        [_cliView setNeedsDisplay];
+    }
+}
+
+#pragma mark - CPDFClipTextPreviewDelegate
+
+- (void)clipText:(CGContextRef)context {
+    CGContextSetFillColorWithColor(context, [UIColor systemGray5Color].CGColor);
+    CGContextFillRect(context, self.textPreview.bounds);
+    CGContextClearRect(context, self.textPreview.documentView.frame);
+}
+
+#pragma mark - UITextFieldDelegate
+
+- (void)textFieldDidBeginEditing:(UITextField *)textField {
+    
+    self.cliView.hidden = YES;
+    self.drawView.hidden = YES;
+    
+    if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight || [UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft || [UIDevice currentDevice].orientation == UIDeviceOrientationPortraitUpsideDown) {
+        
+    } else {
+        [_textView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.height.mas_equalTo(205);
+            make.width.equalTo(_textPreview.mas_width);
+            make.bottom.equalTo(self.view.mas_bottom).offset(-300);
+        }];
+        
+        [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^ {
+            self.textView.center = CGPointMake(self.textView.center.x, self.textView.center.y - 300);
+        } completion:nil];
+    }
+}
+
+- (BOOL)textFieldShouldReturn:(UITextField *)textField {
+    [textField resignFirstResponder];
+    
+    self.cliView.hidden = NO;
+    self.drawView.hidden = NO;
+    
+    if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight || [UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft || [UIDevice currentDevice].orientation == UIDeviceOrientationPortraitUpsideDown) {
+        
+    } else {
+        [_textView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.top.equalTo(_textPreview.mas_bottom).offset(0);
+            make.width.equalTo(_textPreview.mas_width);
+            make.bottom.equalTo(self.view.mas_bottom).offset(0);
+            make.height.mas_equalTo(205);
+        }];
+        
+        [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^ {
+            self.textView.center = CGPointMake(self.textView.center.x, self.textView.center.y + 300);
+        } completion:nil];
+    }
+    
+    return YES;
+}
+
+@end

+ 1 - 0
PDFViewer/Controller/CPDFViewController.h

@@ -8,6 +8,7 @@
 #import <UIKit/UIKit.h>
 #import "CPDFHeaderFooterModel.h"
 
+
 NS_ASSUME_NONNULL_BEGIN
 
 @interface CPDFViewController : UIViewController

+ 145 - 11
PDFViewer/Controller/CPDFViewController.m

@@ -6,19 +6,30 @@
 //
 
 #import <ComPDFKit/ComPDFKit.h>
+#import <ComPDFKit/CPDFWatermark.h>
 #import <ComPDFKit/CPDFHeaderFooter.h>
 #import "CPDFViewController.h"
-#import "CPDFHeaderFooterAddController.h"
-#import "CPDFBatesAddViewController.h"
-#import "CPDFSettingView.h"
+#import "CPDFTextPreview.h"
+#import "CPDFImagePreview.h"
+#import "CPDFTextView.h"
+#import "CPDFImageView.h"
+#import "CPDFDataModel.h"
+#import "CPDFBackgroundModel.h"
+#import "Masonry.h"
+#import "CPDFAddViewController.h"
+#import "CPDFBackgroundSettingViewController.h"
+
+@interface CPDFViewController () <UIActionSheetDelegate,WaterMarkModelDataDelegate,BackgroundDataModelDelegate>
 
-@interface CPDFViewController () <UIActionSheetDelegate,CPDFModelDataDelegate>
-
-@property (nonatomic,strong) CPDFKitPlatformImage *image;
-@property (nonatomic,strong) CPDFDocument *document;
 @property (nonatomic,strong) CPDFView *pdfView;
-@property (nonatomic,strong) CPDFSettingView *headerFooterSetting;
-@property (nonatomic,strong) CPDFSettingView *batesSetting;
+@property (nonatomic,strong) CPDFDocument *pdfDocument;
+@property (nonatomic,strong) CPDFWatermark *textWatermark;
+@property (nonatomic,strong) CPDFWatermark *imageWatermark;
+@property (nonatomic,strong) CPDFAddViewController *addWaterMarkViewController;
+@property (nonatomic,strong) CPDFBackgroundSettingViewController * addBackgroundViewController;
+@property (nonatomic,strong) UIImage *image;
+@property (nonatomic,assign) CGSize imageSize;
+
 
 @end
 
@@ -34,7 +45,7 @@
 - (void)viewDidLoad {
     [super viewDidLoad];
     // Do any additional setup after loading the view.
-    // Add UIBarButtonItem in Navigation
+    //add UIBarButtonItem in Navigation
     self.navigationController.toolbarHidden = YES;
     UIImage *btnMore = [UIImage imageNamed:@"btn_more"];
     UIBarButtonItem *ringhtBarItem = [[UIBarButtonItem alloc] initWithImage:btnMore style:UIBarButtonItemStylePlain target:self action:@selector(onClickedOkbtn)];
@@ -70,7 +81,10 @@
     
     // Add watermark action
     UIAlertAction *addWatermarkAction = [UIAlertAction actionWithTitle:@"Add Watermark" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
-            NSLog(@"addWatermarkAction");
+        self.addWaterMarkViewController = [[CPDFAddViewController alloc] initWithDocument:self.pdfDocument];
+        self.addWaterMarkViewController.delegate = self;
+        
+        [self.navigationController pushViewController:self.addWaterMarkViewController animated:YES];
         }];
     
     // Setting headerfooter action
@@ -92,6 +106,7 @@
     [alertController addAction:addWatermarkAction];
     [alertController addAction:settingHeaderFooter];
     [alertController addAction:settingBatesAction];
+    [alertController addAction:addBackgroundAction];
     [alertController addAction:cancelAction];
     
     [self presentViewController:alertController animated:YES completion:nil];
@@ -318,6 +333,125 @@
     _pdfView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
     
    [self.view addSubview:_pdfView];
+    
+#pragma mark - WaterMarkModelDataDelegate
+
+- (void)changeTextModel:(CPDFDataModel *)dataModel {
+    _textWatermark = [[CPDFWatermark alloc] initWithDocument:_pdfDocument type:CPDFWatermarkTypeText];
+    
+    _textWatermark.text = dataModel.text;
+    _textWatermark.textColor = dataModel.textColor;
+    
+    _textWatermark.opacity = dataModel.watermarkOpacity;
+    
+    _textWatermark.scale = dataModel.watermarkScale * 2.5;
+    
+    _textWatermark.isTilePage = dataModel.isTile;
+    
+    _textWatermark.tx = dataModel.tx * _imageSize.width / self.addWaterMarkViewController.textViewController.textPreview.documentView.frame.size.width;
+    _textWatermark.ty = dataModel.ty * _imageSize.height / self.addWaterMarkViewController.textViewController.textPreview.documentView.frame.size.height;
+    
+    _textWatermark.rotation = dataModel.watermarkRotation;
+    
+    if (_textWatermark.isTilePage) {
+        _textWatermark.verticalSpacing = dataModel.verticalSpacing;
+        _textWatermark.horizontalSpacing = dataModel.horizontalSpacing;
+    }
+    
+    if (dataModel.pageString) {
+        _textWatermark.pageString = dataModel.pageString;
+    }
+    
+    [_pdfView.document addWatermark:_textWatermark];
+    [_pdfView layoutDocumentView];
+    NSURL *url = [NSURL fileURLWithPath:_path];
+    [_pdfView.document writeToURL:url];
+}
+
+- (void)changeImageModel:(CPDFDataModel *)dataModel {
+    _imageWatermark = [[CPDFWatermark alloc] initWithDocument:_pdfDocument type:CPDFWatermarkTypeImage];
+    
+    _imageWatermark.image = dataModel.image;
+    
+    _imageWatermark.opacity = dataModel.watermarkOpacity;
+    
+    _imageWatermark.scale = dataModel.watermarkScale * 2;
+    
+    _imageWatermark.isTilePage = dataModel.isTile;
+    
+    _imageWatermark.tx = dataModel.tx * _imageSize.width / self.addWaterMarkViewController.imageViewController.imagePreview.documentView.frame.size.width;
+    _imageWatermark.ty = dataModel.ty * _imageSize.height / self.addWaterMarkViewController.imageViewController.imagePreview.documentView.frame.size.height;
+    
+    _imageWatermark.rotation = dataModel.watermarkRotation;
+    
+    if (_imageWatermark.isTilePage) {
+        _imageWatermark.verticalSpacing = dataModel.verticalSpacing;
+        _imageWatermark.horizontalSpacing = dataModel.horizontalSpacing;
+    }
+    
+    if (dataModel.pageString) {
+        _imageWatermark.pageString = dataModel.pageString;
+    }
+    
+    [_pdfView.document addWatermark:_imageWatermark];
+    [_pdfView layoutDocumentView];
+    NSURL *url = [NSURL fileURLWithPath:_path];
+    [_pdfView.document writeContentToURL:url];
+}
+
+- (void)deleteTextModel:(CPDFWatermark *)waterMark {
+    [self.pdfDocument removeWatermark:waterMark];
+    NSURL *url = [NSURL fileURLWithPath:_path];
+    [_pdfView.document writeToURL:url];
+    
+    _pdfDocument = [[CPDFDocument alloc] initWithURL:url];
+    _pdfView = [[CPDFView alloc] initWithFrame:self.view.bounds];
+    _pdfView.document = _pdfDocument;
+    _pdfView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+    [self.view addSubview:_pdfView];
+}
+
+#pragma mark - BackgroundDataModelDelegate
+
+- (void)changeBackgroundModel:(CPDFBackgroundModel *)dataModel {
+    CPDFBackground *pageBackground = [_pdfDocument background];
+    
+    pageBackground.color = dataModel.backgroundColor;
+    pageBackground.scale = dataModel.backgroudScale;
+    pageBackground.rotation = dataModel.backgroundRotation;
+    pageBackground.opacity = dataModel.backgroundOpacity;
+    pageBackground.pageString = dataModel.pageString;
+    pageBackground.xOffset = dataModel.horizontalSpacing;
+    pageBackground.yOffset = dataModel.verticalSpacing;
+    pageBackground.isAllowsView = YES;
+    pageBackground.isAllowsPrint = YES;
+    [pageBackground setImage:dataModel.image];
+    
+    [pageBackground update];
+    
+    NSURL *url = [NSURL fileURLWithPath:_path];
+    [_pdfView.document writeToURL:url];
+    
+    _pdfDocument = [[CPDFDocument alloc] initWithURL:url];
+    _pdfView = [[CPDFView alloc] initWithFrame:self.view.bounds];
+    _pdfView.document = _pdfDocument;
+    _pdfView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+    [self.view addSubview:_pdfView];
+}
+
+- (void)deleteBackgroundModel {
+    CPDFBackground *pageBackground = [_pdfDocument background];
+    
+    [pageBackground clear];
+    
+    NSURL *url = [NSURL fileURLWithPath:_path];
+    [_pdfView.document writeToURL:url];
+    
+    _pdfDocument = [[CPDFDocument alloc] initWithURL:url];
+    _pdfView = [[CPDFView alloc] initWithFrame:self.view.bounds];
+    _pdfView.document = _pdfDocument;
+    _pdfView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+    [self.view addSubview:_pdfView];
 }
 
 @end

+ 29 - 0
PDFViewer/Model/CPDFBackgroundModel.h

@@ -0,0 +1,29 @@
+//
+//  CPDFBackgroundModel.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/4.
+//
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFBackgroundModel : NSObject
+
+@property (nonatomic,strong) UIColor *backgroundColor;
+
+@property (nonatomic,assign) CGFloat backgroundOpacity;
+@property (nonatomic,assign) CGFloat backgroudScale;
+@property (nonatomic,assign) NSString *pageString;
+@property (nonatomic,assign) CGFloat tx;
+@property (nonatomic,assign) CGFloat ty;
+@property (nonatomic,assign) CGFloat backgroundRotation;
+@property (nonatomic,strong) UIImage *image;
+@property (nonatomic,assign) CGFloat verticalSpacing;
+@property (nonatomic,assign) CGFloat horizontalSpacing;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 12 - 0
PDFViewer/Model/CPDFBackgroundModel.m

@@ -0,0 +1,12 @@
+//
+//  CPDFBackgroundModel.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/4.
+//
+
+#import "CPDFBackgroundModel.h"
+
+@implementation CPDFBackgroundModel
+
+@end

+ 33 - 0
PDFViewer/Model/CPDFDataModel.h

@@ -0,0 +1,33 @@
+//
+//  CPDFDataModel.h
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/21.
+//
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFDataModel : NSObject
+
+@property (nonatomic,copy) NSString *text;
+@property (nonatomic,strong) UIColor *textColor;
+
+@property (nonatomic,assign) CGFloat watermarkOpacity;
+@property (nonatomic,assign) CGFloat watermarkScale;
+@property (nonatomic,assign) BOOL isTile;
+@property (nonatomic,assign) NSString *pageString;
+@property (nonatomic,assign) CGFloat tx;
+@property (nonatomic,assign) CGFloat ty;
+@property (nonatomic,assign) CGFloat watermarkRotation;
+@property (nonatomic,strong) UIImage *image;
+@property (nonatomic,assign) CGFloat verticalSpacing;
+@property (nonatomic,assign) CGFloat horizontalSpacing;
+
+@property (nonatomic,copy) NSString *imagePath;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 19 - 0
PDFViewer/Model/CPDFDataModel.m

@@ -0,0 +1,19 @@
+//
+//  CPDFDataModel.m
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/21.
+//
+
+#import "CPDFDataModel.h"
+
+@implementation CPDFDataModel
+
+-(instancetype)init {
+    if (self = [super init]) {
+        _textColor = [[UIColor alloc] init];
+    }
+    return self;
+}
+
+@end

+ 20 - 0
PDFViewer/View/CPDFBackgroundPreview.h

@@ -0,0 +1,20 @@
+//
+//  CPDFBackgroundPreview.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/2.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFBackgroundPreview : UIView
+
+@property (nonatomic,strong) UIImageView *documentView;
+@property (nonatomic,strong) UIImageView *imageView;
+@property (nonatomic,strong) UIColor *tintColor;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 43 - 0
PDFViewer/View/CPDFBackgroundPreview.m

@@ -0,0 +1,43 @@
+//
+//  CPDFBackgroundPreview.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/2.
+//
+
+#import "CPDFBackgroundPreview.h"
+#import "Masonry.h"
+
+@implementation CPDFBackgroundPreview
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    
+    if (self) {
+        _documentView = [[UIImageView alloc] init];
+        [self addSubview:_documentView];
+        
+        _imageView = [[UIImageView alloc] init];
+        [self addSubview:_imageView];
+        
+        self.backgroundColor = [UIColor systemGray5Color];
+    }
+    
+    return self;
+}
+
+- (void)drawRect:(CGRect)rect {
+    [super drawRect:rect];
+    
+    _imageView.layer.borderColor = UIColor.blueColor.CGColor;
+    _imageView.layer.borderWidth = 1;
+    [_imageView sizeToFit];
+    _imageView.contentMode = UIViewContentModeScaleAspectFit;
+    
+    CGRect frame = _imageView.frame;
+    frame.origin = CGPointMake(_documentView.bounds.size.width / 2 - _imageView.frame.size.width / 2, _documentView.bounds.size.height / 2 - _imageView.frame.size.height / 2);
+    
+    _imageView.frame = frame;
+}
+
+@end

+ 32 - 0
PDFViewer/View/CPDFBackgroundSettingView.h

@@ -0,0 +1,32 @@
+//
+//  CPDFBackgroundSettingView.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/2.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFBackgroundSettingView : UIView
+
+@property (nonatomic,strong) UILabel *titleLabel;
+@property (nonatomic,strong) UISlider *scaleSlider;
+@property (nonatomic,strong) UISlider *opacitySlider;
+@property (nonatomic,strong) UISlider *rotationSlider;
+@property (nonatomic,strong) UILabel *rotationlabel;
+@property (nonatomic,strong) UILabel *textLabel;
+@property (nonatomic,strong) UILabel *opacityLabel;
+@property (nonatomic,strong) UILabel *rangeLabel;
+@property (nonatomic,strong) UITextField *verticalField;
+@property (nonatomic,strong) UITextField *horizontalField;
+@property (nonatomic,strong) UILabel *verticalLabel;
+@property (nonatomic,strong) UILabel *horizontalLabel;
+@property (nonatomic,strong) UIButton *pageBtn;
+@property (nonatomic,strong) UIButton *doneBtn;
+@property (nonatomic,strong) UIButton *cancelBtn;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 163 - 0
PDFViewer/View/CPDFBackgroundSettingView.m

@@ -0,0 +1,163 @@
+//
+//  CPDFBackgroundSettingView.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/2.
+//
+
+#import "CPDFBackgroundSettingView.h"
+#import "Masonry.h"
+
+@implementation CPDFBackgroundSettingView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    if (self) {
+        _opacitySlider = [[UISlider alloc] init];
+        _scaleSlider = [[UISlider alloc] init];
+        _rotationSlider = [[UISlider alloc] init];
+        
+        [self addSubview:_opacitySlider];
+        [self addSubview:_scaleSlider];
+        [self addSubview:_rotationSlider];
+        
+        _rotationlabel = [[UILabel alloc] init];
+        _rangeLabel = [[UILabel alloc] init];
+        _textLabel = [[UILabel alloc] init];
+        _opacityLabel = [[UILabel alloc] init];
+        _titleLabel = [[UILabel alloc] init];
+        
+        [self addSubview:_textLabel];
+        [self addSubview:_opacityLabel];
+        [self addSubview:_rangeLabel];
+        [self addSubview:_rotationlabel];
+        [self addSubview:_titleLabel];
+        
+        _verticalField = [[UITextField alloc] init];
+        _verticalField.borderStyle = UITextBorderStyleRoundedRect;
+        _verticalLabel = [[UILabel alloc] init];
+        _horizontalField = [[UITextField alloc] init];
+        _horizontalField.borderStyle = UITextBorderStyleRoundedRect;
+        _horizontalLabel = [[UILabel alloc] init];
+        _pageBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
+        
+        [self addSubview:_verticalLabel];
+        [self addSubview:_verticalField];
+        [self addSubview:_horizontalField];
+        [self addSubview:_horizontalLabel];
+        [self addSubview:_pageBtn];
+        
+        _doneBtn = [[UIButton alloc] init];
+        _cancelBtn = [[UIButton alloc] init];
+        
+        [self addSubview:_doneBtn];
+        [self addSubview:_cancelBtn];
+        
+        self.backgroundColor = [UIColor systemGray6Color];
+    }
+    
+    return self;
+}
+
+- (void)drawRect:(CGRect)rect {
+    
+    _titleLabel.frame = CGRectMake(5, 5, 180, 50);
+    _rangeLabel.frame = CGRectMake(5, 165, 150, 30);
+    _textLabel.frame = CGRectMake(5, 95, 90, 30);
+    _opacityLabel.frame = CGRectMake(5, 60, 90, 30);
+    _rotationlabel.frame = CGRectMake(5, 130, 90, 30);
+    
+    [self addConstraint];
+    [self assignData];
+}
+
+- (void)addConstraint {
+    [_verticalField mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.top.equalTo(self.pageBtn.mas_bottom).offset(10);
+        make.width.equalTo(@80);
+        make.height.equalTo(@30);
+    }];
+    [_verticalLabel mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-95);
+        make.top.equalTo(self.pageBtn.mas_bottom).offset(10);
+        make.width.equalTo(@20);
+        make.height.equalTo(@30);
+    }];
+    [_horizontalField mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.equalTo(self.mas_left).offset(25);
+        make.top.equalTo(self.pageBtn.mas_bottom).offset(10);
+        make.width.equalTo(@80);
+        make.height.equalTo(@30);
+    }];
+    [_horizontalLabel mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.equalTo(self.mas_left).offset(5);
+        make.top.equalTo(self.pageBtn.mas_bottom).offset(10);
+        make.width.equalTo(@20);
+        make.height.equalTo(@30);
+    }];
+    [_scaleSlider mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.left.equalTo(_textLabel.mas_right).offset(0);
+        make.top.equalTo(self.mas_top).offset(95);
+        make.height.equalTo(@30);
+    }];
+    [_opacitySlider mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.left.equalTo(_opacityLabel.mas_right).offset(0);
+        make.top.equalTo(self.mas_top).offset(60);
+        make.height.equalTo(@30);
+    }];
+    [_rotationSlider mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.left.equalTo(_rotationlabel.mas_right).offset(0);
+        make.top.equalTo(_scaleSlider.mas_bottom).offset(5);
+    }];
+    
+    [_pageBtn mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.top.equalTo(self.rotationSlider.mas_bottom).offset(5);
+        make.left.equalTo(_rangeLabel.mas_right);
+        make.height.equalTo(@35);
+    }];
+    
+    [_doneBtn mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.top.equalTo(_horizontalField.mas_bottom).offset(25);
+        make.height.mas_equalTo(30);
+        make.width.mas_equalTo(80);
+    }];
+    
+    [_cancelBtn mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-110);
+        make.top.equalTo(_horizontalField.mas_bottom).offset(25);
+        make.height.mas_equalTo(30);
+        make.width.mas_equalTo(80);
+    }];
+}
+
+- (void)assignData {
+    _rangeLabel.text = @"Page Range";
+    _rangeLabel.font = [UIFont systemFontOfSize:15];
+    _titleLabel.text = @"Background Edit";
+    _rotationlabel.text = @"Rotation";
+    _textLabel.text = @"Scale";
+    _opacityLabel.text = @"Opacity";
+    _verticalLabel.text = @"Y:";
+    _horizontalLabel.text = @"X:";
+    
+    _scaleSlider.minimumValue = 0.2;
+    _scaleSlider.maximumValue = 1;
+    _scaleSlider.value = 1;
+    
+    _rotationSlider.minimumValue = 0;
+    _rotationSlider.maximumValue = M_PI;
+    
+    [_pageBtn setTitle:@"Page Range" forState:UIControlStateNormal];
+    [_doneBtn setTitle:@"Done" forState:UIControlStateNormal];
+    [_doneBtn setTitleColor:UIColor.systemBlueColor forState:UIControlStateNormal];
+    [_cancelBtn setTitle:@"Cancel" forState:UIControlStateNormal];
+    [_cancelBtn setTitleColor:UIColor.systemBlueColor forState:UIControlStateNormal];
+}
+
+@end

+ 22 - 0
PDFViewer/View/CPDFBackgroundView.h

@@ -0,0 +1,22 @@
+//
+//  CPDFBackgroundView.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/2.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFBackgroundView : UIView
+
+@property (nonatomic,strong) UIButton *colorBtn;
+@property (nonatomic,strong) UILabel *colorLabel;
+@property (nonatomic,strong) UIButton *selectBtn;
+@property (nonatomic,strong) UILabel *imageLabel;
+@property (nonatomic,strong) NSMutableArray *colorArray;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 93 - 0
PDFViewer/View/CPDFBackgroundView.m

@@ -0,0 +1,93 @@
+//
+//  CPDFBackgroundView.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/2.
+//
+
+#define KBUTTON_WIDTH 28
+#define KBUTTON_HEIGHT 28
+
+#import "CPDFBackgroundView.h"
+#import "Masonry.h"
+
+@implementation CPDFBackgroundView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    
+    if (self) {
+        _imageLabel = [[UILabel alloc] init];
+        [self addSubview:_imageLabel];
+        
+        _selectBtn = [[UIButton alloc] init];
+        [self addSubview:_selectBtn];
+        
+        _colorLabel = [[UILabel alloc] init];
+        [self addSubview:_colorLabel];
+        
+        _colorArray = [NSMutableArray array];
+        for (NSInteger i = 0; i < 8; ++i) {
+            _colorBtn = [UIButton buttonWithType:UIButtonTypeSystem];
+            [_colorArray addObject:_colorBtn];
+            [self addSubview:_colorBtn];
+        }
+    }
+    
+    return self;
+}
+
+- (void)drawRect:(CGRect)rect {
+    [super drawRect:rect];
+    
+    _colorLabel.frame = CGRectMake(20, 5, 50, 30);
+    _colorLabel.text = @"Color";
+    _imageLabel.frame = CGRectMake(20, 40, 140, 30);
+    _imageLabel.text = @"Image";
+    
+    for (NSInteger i = 0; i < _colorArray.count; i++) {
+        [[[self colorArray][i] layer] setCornerRadius:KBUTTON_WIDTH / 2];
+        [[[self colorArray][i] layer] setMasksToBounds:YES];
+        [[_colorArray[i] layer] setBorderWidth:0.5f];
+        [[_colorArray[i] layer] setBorderColor:UIColor.systemGray4Color.CGColor];
+    }
+    
+    [_colorArray[0] setBackgroundColor:[UIColor redColor]];
+    [_colorArray[1] setBackgroundColor:[UIColor orangeColor]];
+    [_colorArray[2] setBackgroundColor:[UIColor yellowColor]];
+    [_colorArray[3] setBackgroundColor:[UIColor greenColor]];
+    [_colorArray[4] setBackgroundColor:[UIColor blueColor]];
+    [_colorArray[5] setBackgroundColor:[UIColor brownColor]];
+    [_colorArray[6] setBackgroundColor:[UIColor purpleColor]];
+    [_colorArray[7] setBackgroundColor:[UIColor whiteColor]];
+    
+    _selectBtn.layer.borderWidth = 1.0;
+    _selectBtn.layer.borderColor = UIColor.systemGray4Color.CGColor;
+    [_selectBtn setTitle:@"Select Image" forState:UIControlStateNormal];
+    [_selectBtn setTitleColor:UIColor.blackColor forState:UIControlStateNormal];
+    _selectBtn.layer.cornerRadius = 7;
+    
+    [self addConstraint];
+}
+ 
+- (void)addConstraint {
+    NSInteger offset = 10;
+    for (NSInteger i = 0; i < _colorArray.count; ++i) {
+        [_colorArray[i] mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.right.equalTo(self.mas_right).offset( - offset);
+            make.top.equalTo(self.mas_top).offset(5);
+            make.width.equalTo(@KBUTTON_WIDTH);
+            make.height.equalTo(@KBUTTON_HEIGHT);
+        }];
+        offset += 40;
+    }
+    
+    [_selectBtn mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-25);
+        make.top.equalTo(self.colorLabel.mas_bottom).offset(5);
+        make.width.mas_equalTo(180);
+        make.height.equalTo(@35);
+    }];
+}
+
+@end

+ 27 - 0
PDFViewer/View/CPDFClipView.h

@@ -0,0 +1,27 @@
+//
+//  CPDFClipView.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2022/12/23.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol CPDFClipTextPreviewDelegate <NSObject>
+
+@required
+
+- (void)clipText:(CGContextRef)context;
+
+@end
+
+
+@interface CPDFClipView : UIView
+
+@property (nonatomic,strong) id<CPDFClipTextPreviewDelegate> delegate;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 30 - 0
PDFViewer/View/CPDFClipView.m

@@ -0,0 +1,30 @@
+//
+//  CPDFClipView.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2022/12/23.
+//
+
+#import "CPDFClipView.h"
+
+@implementation CPDFClipView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    
+    if (self) {
+        self.backgroundColor = [UIColor clearColor];
+    }
+    
+    return self;
+}
+
+- (void)drawRect:(CGRect)rect {
+    [super drawRect:rect];
+    
+    CGContextRef context = UIGraphicsGetCurrentContext();
+    
+    [self.delegate clipText:context];
+}
+
+@end

+ 19 - 0
PDFViewer/View/CPDFDrawBackgroundView.h

@@ -0,0 +1,19 @@
+//
+//  CPDFDrawBackgroundView.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/3.
+//
+
+#import <UIKit/UIKit.h>
+#import "CPDFBackgroundModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFDrawBackgroundView : UIView
+
+@property (nonatomic,strong) CPDFBackgroundModel *dataModel;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 55 - 0
PDFViewer/View/CPDFDrawBackgroundView.m

@@ -0,0 +1,55 @@
+//
+//  CPDFDrawBackgroundView.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/3.
+//
+
+#import "CPDFDrawBackgroundView.h"
+
+@implementation CPDFDrawBackgroundView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    
+    if (self) {
+        self.backgroundColor = [UIColor whiteColor];
+    }
+    
+    return self;
+}
+
+- (void)drawRect:(CGRect)rect {
+    [super drawRect:rect];
+    
+    CGContextRef context = UIGraphicsGetCurrentContext();
+    
+    [self showDraw:context];
+}
+
+- (void)showDraw:(CGContextRef)context {
+    CGContextSetFillColorWithColor(context, self.dataModel.backgroundColor.CGColor);
+    
+    CGContextSetAlpha(context, self.dataModel.backgroundOpacity);
+    
+    CGFloat ctm = (self.dataModel.backgroundRotation * M_PI) / 180;
+    CGFloat centerWidth = self.bounds.size.width / 2;
+    CGFloat centerHeigth = self.bounds.size.height / 2;
+    
+    CGContextTranslateCTM(context, self.dataModel.horizontalSpacing, - self.dataModel.verticalSpacing);
+
+    CGContextTranslateCTM(context, centerWidth, centerHeigth);
+    CGContextRotateCTM(context, ctm);
+    
+    CGContextScaleCTM(context, self.dataModel.backgroudScale, self.dataModel.backgroudScale);
+    if (_dataModel.image) {
+        [_dataModel.image drawInRect:CGRectMake(- centerWidth,  - centerHeigth, self.frame.size.width,self.frame.size.height) blendMode:kCGBlendModeNormal alpha:self.dataModel.backgroundOpacity];
+    } else {
+        CGContextFillRect(context, CGRectMake( - centerWidth, - centerHeigth, self.bounds.size.width, self.bounds.size.height));
+    }
+    
+    CGContextRotateCTM(context, -ctm);
+    CGContextTranslateCTM(context, - centerWidth, - centerHeigth);
+}
+
+@end

+ 18 - 0
PDFViewer/View/CPDFDrawImageView.h

@@ -0,0 +1,18 @@
+//
+//  CPDFDrawImageView.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/3.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFDrawImageView : UIView
+
+@property (nonatomic,strong) UIImage *image;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 76 - 0
PDFViewer/View/CPDFDrawImageView.m

@@ -0,0 +1,76 @@
+//
+//  CPDFDrawImageView.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/3.
+//
+
+#import "CPDFDrawImageView.h"
+
+@implementation CPDFDrawImageView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    
+    if (self) {
+        self.backgroundColor = [UIColor clearColor];
+    }
+    
+    return self;
+}
+
+- (void)drawRect:(CGRect)rect {
+    CGContextRef context = UIGraphicsGetCurrentContext();
+    
+    [self showDraw:context];
+}
+
+- (void)showDraw:(CGContextRef)context {
+    UIImage *newImage = [self imageToTransparent:_image];
+    
+    [newImage drawInRect:self.bounds blendMode:kCGBlendModeNormal alpha:1.0f];
+}
+
+- (UIImage*) imageToTransparent:(UIImage*) image {
+    const int imageWidth = image.size.width;
+    const int imageHeight = image.size.height;
+    size_t bytesPerRow = imageWidth * 4;
+    uint32_t *rgbImageBuf = (uint32_t *)malloc(bytesPerRow * imageHeight);
+    
+    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+    CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace
+                                                 , kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
+    
+    CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage);
+    
+    int pixelNum = imageWidth * imageHeight;
+    uint32_t* pCurPtr = rgbImageBuf;
+    for (int i = 0; i < pixelNum; i++, pCurPtr++)
+    {
+        if ((*pCurPtr & 0x65815A00) == 0x65815a00)
+        {
+            uint8_t* ptr = (uint8_t*)pCurPtr;
+            ptr[0] = 0;
+        }
+    }
+
+    CGDataProviderRef dataProvider =CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, ProviderReleaseData);
+    CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight,8, 32, bytesPerRow, colorSpace,
+                                        kCGImageAlphaLast |kCGBitmapByteOrder32Little, dataProvider,
+                                        NULL, true,kCGRenderingIntentDefault);
+    CGDataProviderRelease(dataProvider);
+
+    UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef];
+
+    CGImageRelease(imageRef);
+    CGContextRelease(context);
+    CGColorSpaceRelease(colorSpace);
+
+    return resultUIImage;
+}
+
+ void ProviderReleaseData(void *info, const void *data, size_t size) {
+     free((void *) data);
+}
+
+@end

+ 23 - 0
PDFViewer/View/CPDFDrawView.h

@@ -0,0 +1,23 @@
+//
+//  CPDFDrawView.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2022/12/22.
+//
+
+#import <UIKit/UIKit.h>
+#import "CPDFDataModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFDrawView : UIView
+
+@property (nonatomic,strong) CPDFDataModel *dataModel;
+@property (nonatomic,assign) CGRect waterLabelRect;
+@property (nonatomic,assign) CGRect documentViewRect;
+@property (nonatomic,assign) CGFloat vertical;
+@property (nonatomic,assign) CGFloat horizontal;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 115 - 0
PDFViewer/View/CPDFDrawView.m

@@ -0,0 +1,115 @@
+//
+//  CPDFDrawView.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2022/12/22.
+//
+
+#import "CPDFDrawView.h"
+
+@implementation CPDFDrawView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    
+    if (self) {
+        self.backgroundColor = [UIColor clearColor];
+        
+        _dataModel = [[CPDFDataModel alloc] init];
+        
+        _horizontal = 100;
+        _vertical = 100;
+    }
+    
+    return self;
+}
+
+- (void)drawRect:(CGRect)rect {
+    [super drawRect:rect];
+    
+    CGContextRef context = UIGraphicsGetCurrentContext();
+
+    if (self.dataModel.text) {
+        [self drawText:context];
+    } else if (self.dataModel.image) {
+        [self drawImage:context];
+    }
+    
+}
+
+- (void)drawText:(CGContextRef)context {
+    CGContextSetFillColorWithColor(context, self.dataModel.textColor.CGColor);
+    CGContextSaveGState(context);
+    
+    CGContextSetAlpha(context, self.dataModel.watermarkOpacity);
+    
+    UIFont *font = [UIFont systemFontOfSize:24 * self.dataModel.watermarkScale];
+    NSDictionary *dic = @{NSFontAttributeName:font,NSForegroundColorAttributeName:self.dataModel.textColor};
+    
+    NSInteger wx,wy,height,width;
+    wx = self.waterLabelRect.origin.x + self.documentViewRect.origin.x;
+    wy = self.waterLabelRect.origin.y + self.documentViewRect.origin.y;
+    height = self.waterLabelRect.size.height + _vertical / 2.5;
+    width = self.waterLabelRect.size.width + _horizontal / 2.3;
+
+    NSInteger x,y,a,b;
+    x = self.frame.size.width / width;
+    y = self.frame.size.height / height;
+
+    a = wx % width;
+    b = wy % height;
+    
+    CGFloat ctm = (self.dataModel.watermarkRotation * M_PI) / 180;
+    
+    CGContextTranslateCTM(context, self.center.x,  self.center.y);
+    
+    CGContextRotateCTM(context, ctm);
+
+    for (NSInteger i = 0; i < x; i++) {
+        for (NSInteger j = 0; j < y; j++) {
+            
+            [self.dataModel.text drawInRect:CGRectMake((a + i * width) - self.center.x, b + j * height - self.center.y, width - _horizontal / 2.5, height - _vertical / 2.5) withAttributes:dic];
+        }
+    }
+    
+    CGContextRotateCTM(context, -ctm);
+    CGContextTranslateCTM(context, - self.center.x, - self.center.y);
+}
+
+- (void)drawImage:(CGContextRef)context {
+    CGContextSaveGState(context);
+    
+    CGContextSetAlpha(context, self.dataModel.watermarkOpacity);
+    
+    NSInteger wx,wy,height,width;
+    wx = self.waterLabelRect.origin.x + self.documentViewRect.origin.x;
+    wy = self.waterLabelRect.origin.y + self.documentViewRect.origin.y;
+    height = self.waterLabelRect.size.height + _vertical / 1.8;
+    width = self.waterLabelRect.size.width + _horizontal / 1.8;
+
+    NSInteger x,y,a,b;
+    x = self.frame.size.width / width;
+    y = self.frame.size.height / height;
+
+    a = wx % width;
+    b = wy % height;
+    
+    CGFloat ctm = (self.dataModel.watermarkRotation * M_PI) / 180;
+    
+    CGContextTranslateCTM(context, self.center.x,  self.center.y);
+    
+    CGContextRotateCTM(context, ctm);
+
+    for (NSInteger i = 0; i < x; i++) {
+        for (NSInteger j = 0; j < y; j++) {
+            
+            [self.dataModel.image drawInRect:CGRectMake((a + i * width) - self.center.x, b + j * height - self.center.y, width - _horizontal / 1.8, height - _vertical / 1.8) blendMode:kCGBlendModeNormal alpha:self.dataModel.watermarkOpacity];
+        }
+    }
+    CGContextRotateCTM(context, -ctm);
+    
+    CGContextTranslateCTM(context, - self.center.x, - self.center.y);
+    
+}
+
+@end

+ 18 - 0
PDFViewer/View/CPDFEditView.h

@@ -0,0 +1,18 @@
+//
+//  CPDFEditView.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2022/12/26.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFEditView : UIView
+ 
+@property (nonatomic,strong) UITableView *editTableView;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 33 - 0
PDFViewer/View/CPDFEditView.m

@@ -0,0 +1,33 @@
+//
+//  CPDFEditView.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2022/12/26.
+//
+
+#import "CPDFEditView.h"
+
+@implementation CPDFEditView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    
+    if (self) {
+        _editTableView = [[UITableView alloc] initWithFrame:self.bounds style:UITableViewStylePlain];
+        _editTableView.backgroundColor = [UIColor systemGray6Color];
+        _editTableView.rowHeight = 50;
+        _editTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+        _editTableView.tableFooterView = [[UIView alloc] init];
+        [_editTableView setEditing:YES animated:YES];
+        _editTableView.allowsMultipleSelection = NO;
+        _editTableView.allowsSelectionDuringEditing = NO;
+        _editTableView.allowsMultipleSelectionDuringEditing = NO;
+        
+        [self addSubview:_editTableView];
+        
+        self.backgroundColor = [UIColor systemGray6Color];
+    }
+    return self;
+}
+
+@end

+ 21 - 0
PDFViewer/View/CPDFImagePreview.h

@@ -0,0 +1,21 @@
+//
+//  CPDFImagePreview.h
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/18.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFImagePreview : UIView
+
+@property (nonatomic,strong) UIImageView *watermarkView;
+@property (nonatomic,strong) UIButton *rotationBtn;
+@property (nonatomic,strong) UIImageView *documentView;
+@property (nonatomic,assign) CGRect watermarkFrame;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 59 - 0
PDFViewer/View/CPDFImagePreview.m

@@ -0,0 +1,59 @@
+//
+//  CPDFImagePreview.m
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/18.
+//
+
+#import "CPDFImagePreview.h"
+#import "Masonry.h"
+
+BOOL gImagePreviewIsFirstLayout = YES;
+
+@implementation CPDFImagePreview
+
+- (instancetype)initWithFrame:(CGRect)frame
+{
+    if (self = [super initWithFrame:frame]) {
+        _watermarkView = [[UIImageView alloc] init];
+        _rotationBtn = [UIButton buttonWithType:UIButtonTypeCustom];
+        _documentView = [[UIImageView alloc] init];
+
+        [self addSubview:_documentView];
+        [_documentView addSubview:_watermarkView];
+        [_watermarkView addSubview:_rotationBtn];
+    }
+    return self;
+}
+
+#pragma mark - Layout
+
+- (void)layoutSubviews {
+    [super layoutSubviews];
+    
+    _watermarkView.layer.borderColor = UIColor.blueColor.CGColor;
+    _watermarkView.layer.borderWidth = 1;
+    [_watermarkView sizeToFit];
+    _watermarkView.contentMode = UIViewContentModeScaleAspectFit;
+    
+    CGRect frame = _watermarkView.frame;
+    frame.origin = CGPointMake(_documentView.bounds.size.width / 2 - _watermarkView.frame.size.width / 2, _documentView.bounds.size.height / 2 - _watermarkView.frame.size.height / 2);
+    _watermarkFrame = frame;
+    
+    _watermarkView.frame = _watermarkFrame;
+    
+    [_rotationBtn mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(_watermarkView.mas_bottom).offset(-10);
+        make.width.equalTo(@20);
+        make.height.equalTo(@20);
+        make.left.equalTo(_watermarkView.mas_right).offset(-10);
+    }];
+    
+    _rotationBtn.layer.cornerRadius = 10;
+    _rotationBtn.layer.masksToBounds = YES;
+    _rotationBtn.layer.borderColor = UIColor.blueColor.CGColor;
+    [_rotationBtn setBackgroundImage:[UIImage imageNamed:@"btn_selected"] forState:UIControlStateNormal];
+    
+}
+
+@end

+ 35 - 0
PDFViewer/View/CPDFImageView.h

@@ -0,0 +1,35 @@
+//
+//  CPDFImageView.h
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/16.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFImageView : UIView
+
+@property (nonatomic,strong) UIButton *selectBtn;
+@property (nonatomic,strong) UISlider *imageScaleSlider;
+@property (nonatomic,strong) UISlider *opacitySlider;
+@property (nonatomic,strong) UISwitch *tileSwitch;
+@property (nonatomic,strong) UILabel *rangeLabel;
+@property (nonatomic,strong) UILabel *tileLabel;
+@property (nonatomic,strong) UILabel *sizeLabel;
+@property (nonatomic,strong) UILabel *opacityLabel;
+@property (nonatomic,strong) UITextField *verticalField;
+@property (nonatomic,strong) UITextField *horizontalField;
+@property (nonatomic,strong) UILabel *verticalLabel;
+@property (nonatomic,strong) UILabel *horizontalLabel;
+@property (nonatomic,strong) UILabel *imageLabel;
+@property (nonatomic,strong) UIButton *pageBtn;
+
+- (void)createView;
+- (void)createFrame;
+- (void)assignData;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 156 - 0
PDFViewer/View/CPDFImageView.m

@@ -0,0 +1,156 @@
+//
+//  CPDFImageView.m
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/16.
+//
+
+#import "CPDFImageView.h"
+#import "Masonry.h"
+
+@implementation CPDFImageView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    
+    if (self = [super initWithFrame:frame]) {
+        [self createView];
+        [self assignData];
+    }
+    
+    return self;
+}
+
+#pragma mark - Layout
+
+- (void)layoutSubviews {
+    [super layoutSubviews];
+    [self createFrame];
+    [self addConstraint];
+}
+
+- (void)createView {
+    
+    _opacitySlider = [[UISlider alloc] init];
+    _imageScaleSlider = [[UISlider alloc] init];
+    _tileSwitch = [[UISwitch alloc] init];
+    _rangeLabel = [[UILabel alloc] init];
+    _tileLabel = [[UILabel alloc] init];
+    _sizeLabel = [[UILabel alloc] init];
+    _opacityLabel = [[UILabel alloc] init];
+    
+    _verticalField = [[UITextField alloc] init];
+    _verticalField.borderStyle = UITextBorderStyleRoundedRect;
+    
+    _verticalLabel = [[UILabel alloc] init];
+    
+    _horizontalField = [[UITextField alloc] init];
+    _horizontalField.borderStyle = UITextBorderStyleRoundedRect;
+    
+    _horizontalLabel = [[UILabel alloc] init];
+    _imageLabel = [[UILabel alloc] init];
+    _selectBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
+    _pageBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
+    
+    [self addSubview:_opacitySlider];
+    [self addSubview:_sizeLabel];
+    [self addSubview:_opacityLabel];
+    [self addSubview:_imageScaleSlider];
+    [self addSubview:_tileSwitch];
+    [self addSubview:_rangeLabel];
+    [self addSubview:_tileLabel];
+    [self addSubview:_verticalLabel];
+    [self addSubview:_verticalField];
+    [self addSubview:_horizontalField];
+    [self addSubview:_horizontalLabel];
+    [self addSubview:_imageLabel];
+    [self addSubview:_selectBtn];
+    [self addSubview:_pageBtn];
+    
+    [self setBackgroundColor:[UIColor whiteColor]];
+    
+}
+
+- (void)createFrame {
+    // y -- 40   height -- 30
+    _tileSwitch.frame = CGRectMake(100, 160, 10, 10);
+    _rangeLabel.frame = CGRectMake(10, 120, 180, 30);
+    _tileLabel.frame = CGRectMake(10, 160, 100, 30);
+    _sizeLabel.frame = CGRectMake(10, 80, 90, 30);
+    _opacityLabel.frame = CGRectMake(10, 40, 90, 30);
+    _imageLabel.frame = CGRectMake(10, 5, 150, 30);
+    
+    _selectBtn.layer.borderWidth = 1.0;
+    _selectBtn.layer.borderColor = UIColor.systemGray4Color.CGColor;
+    [_selectBtn setTitle:@"Select Image" forState:UIControlStateNormal];
+    [_selectBtn setTitleColor:UIColor.blackColor forState:UIControlStateNormal];
+    _selectBtn.layer.cornerRadius = 7;
+    
+    _pageBtn.layer.borderWidth = 1.0;
+    _pageBtn.layer.borderColor = UIColor.systemGray4Color.CGColor;
+    [_pageBtn setTitle:@"Page Range" forState:UIControlStateNormal];
+    [_pageBtn setTitleColor:UIColor.blackColor forState:UIControlStateNormal];
+    _pageBtn.layer.cornerRadius = 7;
+}
+
+- (void)addConstraint {
+    [_verticalField mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.top.equalTo(self.pageBtn.mas_bottom).offset(10);
+        make.width.equalTo(@80);
+        make.height.equalTo(@30);
+    }];
+    [_verticalLabel mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-95);
+        make.top.equalTo(self.pageBtn.mas_bottom).offset(10);
+        make.width.equalTo(@20);
+        make.height.equalTo(@30);
+    }];
+    [_horizontalField mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-115);
+        make.top.equalTo(self.pageBtn.mas_bottom).offset(10);
+        make.width.equalTo(@80);
+        make.height.equalTo(@30);
+    }];
+    [_horizontalLabel mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-195);
+        make.top.equalTo(self.pageBtn.mas_bottom).offset(10);
+        make.width.equalTo(@20);
+        make.height.equalTo(@30);
+    }];
+    [_selectBtn mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.top.equalTo(self.mas_top).offset(2);
+        make.left.equalTo(_horizontalField.mas_left);
+        make.height.equalTo(@35);
+    }];
+    [_imageScaleSlider mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.left.equalTo(_sizeLabel.mas_right).offset(0);
+        make.top.equalTo(self.mas_top).offset(80);
+        make.height.equalTo(@30);
+    }];
+    [_opacitySlider mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.left.equalTo(_opacityLabel.mas_right).offset(0);
+        make.top.equalTo(self.mas_top).offset(40);
+        make.height.equalTo(@30);
+    }];
+    [_pageBtn mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.top.equalTo(self.mas_top).offset(115);
+        make.left.equalTo(_horizontalField.mas_left);
+        make.height.equalTo(@35);
+    }];
+}
+
+- (void)assignData {
+    _rangeLabel.text = @"Page Range";
+    _tileLabel.text = @"Full Screen";
+    _sizeLabel.text = @"Image Size";
+    _opacityLabel.text = @"Opacity";
+    _verticalLabel.text = @"Y:";
+    _horizontalLabel.text = @"X:";
+    _imageLabel.text = @"Image";
+}
+
+@end

+ 20 - 0
PDFViewer/View/CPDFTextPreview.h

@@ -0,0 +1,20 @@
+//
+//  CPDFTextPreview.h
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/18.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFTextPreview : UIView 
+
+@property (nonatomic,strong) UILabel *watermarkLabel;
+@property (nonatomic,strong) UIButton *rotationBtn;
+@property (nonatomic,strong) UIImageView *documentView;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 66 - 0
PDFViewer/View/CPDFTextPreview.m

@@ -0,0 +1,66 @@
+//
+//  CPDFTextPreview.m
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/18.
+//
+
+#import "CPDFTextPreview.h"
+#import "Masonry.h"
+
+BOOL gTextPreviewIsFirstLayout = YES;
+
+@implementation CPDFTextPreview
+
+- (instancetype)initWithFrame:(CGRect)frame
+{
+    if (self = [super initWithFrame:frame]) {
+        _watermarkLabel = [[UILabel alloc] init];
+        _rotationBtn = [UIButton buttonWithType:UIButtonTypeCustom];
+        _documentView = [[UIImageView alloc] init];
+        
+        [self addSubview:_documentView];
+        [_documentView addSubview:_watermarkLabel];
+        [_watermarkLabel addSubview:_rotationBtn];
+        
+        self.backgroundColor = [UIColor systemGray5Color];
+    }
+    return self;
+}
+
+#pragma mark - Drawrect
+
+- (void)drawRect:(CGRect)rect {
+    [super drawRect:rect];
+
+    _watermarkLabel.layer.borderWidth = 1;
+    _watermarkLabel.layer.borderColor = UIColor.blueColor.CGColor;
+
+    [_watermarkLabel sizeToFit];
+    
+    /*
+     this have a core was delete:
+         if (gTextPreviewIsFirstLayout) {
+             gTextPreviewIsFirstLayout = NO;
+         }
+     
+     */
+
+    CGRect frame = _watermarkLabel.frame;
+    frame.origin = CGPointMake(_documentView.bounds.size.width / 2 - _watermarkLabel.frame.size.width / 2, _documentView.bounds.size.height / 2 - _watermarkLabel.frame.size.height / 2);
+        _watermarkLabel.frame = frame;
+
+    _rotationBtn.layer.cornerRadius = 10;
+    _rotationBtn.layer.masksToBounds = YES;
+    _rotationBtn.layer.borderColor = UIColor.blueColor.CGColor;
+    [_rotationBtn setBackgroundImage:[UIImage imageNamed:@"btn_selected"] forState:UIControlStateNormal];
+    
+    [_rotationBtn mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(_watermarkLabel.mas_bottom).offset(-10);
+        make.width.equalTo(@20);
+        make.height.equalTo(@20);
+        make.left.equalTo(_watermarkLabel.mas_right).offset(-10);
+    }];
+}
+
+@end

+ 37 - 0
PDFViewer/View/CPDFTextView.h

@@ -0,0 +1,37 @@
+//
+//  CPDFTextView.h
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/16.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CPDFTextView : UIView
+
+@property (nonatomic,strong) UIButton *colorBtn;
+@property (nonatomic,strong) UILabel *colorLabel;
+@property (nonatomic,strong) UISlider *textScaleSlider;
+@property (nonatomic,strong) UISlider *opacitySlider;
+@property (nonatomic,strong) UISwitch *tileSwitch;
+@property (nonatomic,strong) UILabel *rangeLabel;
+@property (nonatomic,strong) UILabel *tileLabel;
+@property (nonatomic,strong) UILabel *textLabel;
+@property (nonatomic,strong) UILabel *opacityLabel;
+@property (nonatomic,strong) UITextField *verticalField;
+@property (nonatomic,strong) UITextField *horizontalField;
+@property (nonatomic,strong) UILabel *verticalLabel;
+@property (nonatomic,strong) UILabel *horizontalLabel;
+@property (nonatomic,strong) UIButton *pageBtn;
+
+@property (nonatomic,strong) NSMutableArray *colorArray;
+
+- (void)createView;
+- (void)createFrame;
+- (void)assignData;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 178 - 0
PDFViewer/View/CPDFTextView.m

@@ -0,0 +1,178 @@
+//
+//  CPDFTextView.m
+//  PDFViewer
+//
+//  Created by kdan on 2022/11/16.
+//
+
+#import "CPDFTextView.h"
+#import "Masonry.h"
+
+#define KBUTTON_WIDTH 28
+#define KBUTTON_HEIGHT 28
+
+@implementation CPDFTextView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    
+    if (self = [super initWithFrame:frame]) {
+        [self createView];
+        [self assignData];
+        self.backgroundColor = [UIColor whiteColor];
+    }
+    
+    return self;
+}
+
+#pragma mark - Layout
+
+- (void)layoutSubviews {
+    [super layoutSubviews];
+    [self createFrame];
+    [self addConstraint];
+}
+
+- (void)createView {
+    
+    _opacitySlider = [[UISlider alloc] init];
+    _textScaleSlider = [[UISlider alloc] init];
+    _tileSwitch = [[UISwitch alloc] init];
+    _rangeLabel = [[UILabel alloc] init];
+    _tileLabel = [[UILabel alloc] init];
+    _textLabel = [[UILabel alloc] init];
+    _opacityLabel = [[UILabel alloc] init];
+    _colorLabel = [[UILabel alloc] init];
+    
+    _verticalField = [[UITextField alloc] init];
+    _verticalField.borderStyle = UITextBorderStyleRoundedRect;
+    
+    _verticalLabel = [[UILabel alloc] init];
+    
+    _horizontalField = [[UITextField alloc] init];
+    _horizontalField.borderStyle = UITextBorderStyleRoundedRect;
+    
+    _horizontalLabel = [[UILabel alloc] init];
+    _pageBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
+    
+    _colorArray = [NSMutableArray array];
+    for (NSInteger i = 0; i < 8; ++i) {
+        _colorBtn = [UIButton buttonWithType:UIButtonTypeSystem];
+        [_colorArray addObject:_colorBtn];
+        [self addSubview:_colorBtn];
+    }
+    
+    
+    [self addSubview:_opacitySlider];
+    [self addSubview:_textLabel];
+    [self addSubview:_opacityLabel];
+    [self addSubview:_textScaleSlider];
+    [self addSubview:_tileSwitch];
+    [self addSubview:_rangeLabel];
+    [self addSubview:_tileLabel];
+    [self addSubview:_verticalLabel];
+    [self addSubview:_verticalField];
+    [self addSubview:_horizontalField];
+    [self addSubview:_horizontalLabel];
+    [self addSubview:_colorLabel];
+    [self addSubview:_pageBtn];
+    
+}
+
+- (void)createFrame {
+    // y -- 40   height -- 30
+    _tileSwitch.frame = CGRectMake(100, 160, 10, 10);
+    _rangeLabel.frame = CGRectMake(10, 120, 180, 30);
+    _tileLabel.frame = CGRectMake(10, 160, 100, 30);
+    _textLabel.frame = CGRectMake(10, 80, 90, 30);
+    _opacityLabel.frame = CGRectMake(10, 40, 90, 30);
+    _colorLabel.frame = CGRectMake(10, 5, 50, 30);
+    
+    for (NSInteger i = 0; i < _colorArray.count; i++) {
+        [[[self colorArray][i] layer] setCornerRadius:KBUTTON_WIDTH / 2];
+        [[[self colorArray][i] layer] setMasksToBounds:YES];
+    }
+    
+    [_colorArray[0] setBackgroundColor:[UIColor redColor]];
+    [_colorArray[1] setBackgroundColor:[UIColor orangeColor]];
+    [_colorArray[2] setBackgroundColor:[UIColor yellowColor]];
+    [_colorArray[3] setBackgroundColor:[UIColor greenColor]];
+    [_colorArray[4] setBackgroundColor:[UIColor blueColor]];
+    [_colorArray[5] setBackgroundColor:[UIColor brownColor]];
+    [_colorArray[6] setBackgroundColor:[UIColor purpleColor]];
+    [_colorArray[7] setBackgroundColor:[UIColor grayColor]];
+    
+    _pageBtn.layer.borderWidth = 1.0;
+    _pageBtn.layer.borderColor = UIColor.systemGray4Color.CGColor;
+    [_pageBtn setTitle:@"Page Range" forState:UIControlStateNormal];
+    [_pageBtn setTitleColor:UIColor.blackColor forState:UIControlStateNormal];
+    _pageBtn.layer.cornerRadius = 7;
+}
+
+- (void)addConstraint {
+    [_verticalField mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.top.equalTo(self.pageBtn.mas_bottom).offset(10);
+        make.width.equalTo(@80);
+        make.height.equalTo(@30);
+    }];
+    [_verticalLabel mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-95);
+        make.top.equalTo(self.pageBtn.mas_bottom).offset(10);
+        make.width.equalTo(@20);
+        make.height.equalTo(@30);
+    }];
+    [_horizontalField mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-115);
+        make.top.equalTo(self.pageBtn.mas_bottom).offset(10);
+        make.width.equalTo(@80);
+        make.height.equalTo(@30);
+    }];
+    [_horizontalLabel mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-195);
+        make.top.equalTo(self.pageBtn.mas_bottom).offset(10);
+        make.width.equalTo(@20);
+        make.height.equalTo(@30);
+    }];
+    [_textScaleSlider mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.left.equalTo(_textLabel.mas_right).offset(0);
+        make.top.equalTo(self.mas_top).offset(80);
+        make.height.equalTo(@30);
+    }];
+    [_opacitySlider mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.left.equalTo(_opacityLabel.mas_right).offset(0);
+        make.top.equalTo(self.mas_top).offset(40);
+        make.height.equalTo(@30);
+    }];
+    
+    NSInteger offset = 10;
+    for (NSInteger i = 0; i < _colorArray.count; ++i) {
+        [_colorArray[i] mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.right.equalTo(self.mas_right).offset( - offset);
+            make.top.equalTo(self.mas_top).offset(5);
+            make.width.equalTo(@KBUTTON_WIDTH);
+            make.height.equalTo(@KBUTTON_HEIGHT);
+        }];
+        offset += 40;
+    }
+    
+    [_pageBtn mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.right.equalTo(self.mas_right).offset(-15);
+        make.top.equalTo(self.mas_top).offset(115);
+        make.left.equalTo(_horizontalField.mas_left);
+        make.height.equalTo(@35);
+    }];
+}
+
+- (void)assignData {
+    _rangeLabel.text = @"Page Range";
+    _tileLabel.text = @"Full Screen";
+    _textLabel.text = @"Font Size";
+    _opacityLabel.text = @"Opacity";
+    _verticalLabel.text = @"Y:";
+    _horizontalLabel.text = @"X:";
+    _colorLabel.text = @"Color";
+}
+
+@end

+ 21 - 0
PDFViewer/View/UIImage+TintColor.h

@@ -0,0 +1,21 @@
+//
+//  UIImage+TintColor.h
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/3.
+//
+
+#import <UIKit/UIKit.h>
+#import "CPDFDataModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface UIImage (TintColor)
+
+@property (nonatomic,strong) CPDFDataModel *datamodel;
+
+- (UIImage *)imageWithTintColor:(UIColor *)tintColor;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 51 - 0
PDFViewer/View/UIImage+TintColor.m

@@ -0,0 +1,51 @@
+//
+//  UIImage+TintColor.m
+//  PDFViewer
+//
+//  Created by kdanmobile_2 on 2023/1/3.
+//
+
+#import "UIImage+TintColor.h"
+
+@implementation UIImage (TintColor)
+
+- (UIImage *)imageWithTintColor:(UIColor *)tintColor {
+    UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
+
+    [tintColor setFill];
+    
+    CGRect bounds = CGRectMake(0, 0, self.size.width, self.size.height);
+    UIRectFill(bounds);
+    
+    [self drawInRect:bounds blendMode:kCGBlendModeDestinationIn alpha:0.3f];
+    
+    [self drawInRect:bounds blendMode:kCGBlendModeOverlay alpha:2.0f];
+    
+    UIImage *tintImage = UIGraphicsGetImageFromCurrentImageContext();
+    UIGraphicsEndImageContext();
+    
+    return tintImage;
+}
+
+- (void)setDatamodel:(CPDFDataModel *)datamodel {
+    self.datamodel = datamodel;
+}
+
+- (CPDFDataModel *)datamodel {
+    return self.datamodel;
+}
+
+- (CGRect)rotateRect:(CGRect)rect {
+    CGAffineTransform tranform_1 = CGAffineTransformMakeTranslation(- self.size.width / 2,  - self.size.height / 2);
+    CGRect rect_1 = CGRectApplyAffineTransform(rect,tranform_1);
+    
+    CGAffineTransform tranform_2 = CGAffineTransformMakeRotation(M_PI / 8);
+    CGRect rect_2 = CGRectApplyAffineTransform(rect_1,tranform_2);
+    
+    CGAffineTransform tranform_3 = CGAffineTransformMakeTranslation(- self.size.width / 2,  - self.size.height / 2);
+    CGRect rect_3 = CGRectApplyAffineTransform(rect_2,tranform_3);
+    
+    return rect_3;
+}
+
+@end

BIN
PDFViewer/View/sources/btn_selected.png